@apifuse/provider-sdk 2.2.0-beta.4 → 2.2.0-beta.40

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 (303) hide show
  1. package/AUTHORING.md +501 -13
  2. package/CHANGELOG.md +165 -1
  3. package/README.md +72 -14
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +88 -4
  6. package/bin/apifuse-dev.ts +38 -5
  7. package/bin/apifuse-pack-check.ts +22 -2
  8. package/bin/apifuse-pack-smoke.ts +57 -2
  9. package/bin/apifuse-pack-types.ts +356 -38
  10. package/bin/apifuse-perf.ts +14 -13
  11. package/bin/apifuse-record.ts +691 -68
  12. package/bin/apifuse-submit-check.ts +518 -37
  13. package/bin/apifuse-sync-assets.ts +117 -0
  14. package/bin/submit-check-delimited-text.ts +50 -0
  15. package/dist/auth-turn/index.d.ts +3 -3
  16. package/dist/auth-turn/index.js +1 -1
  17. package/dist/auth.d.ts +14 -0
  18. package/dist/auth.js +67 -0
  19. package/dist/ceremonies/index.d.ts +16 -0
  20. package/dist/ceremonies/index.js +141 -36
  21. package/dist/cli/commands.d.ts +1 -1
  22. package/dist/cli/commands.js +8 -0
  23. package/dist/cli/create.d.ts +3 -0
  24. package/dist/cli/create.js +34 -35
  25. package/dist/cli/prompt-assets.d.ts +80 -0
  26. package/dist/cli/prompt-assets.js +743 -0
  27. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  28. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  29. package/dist/cli/templates/provider/README.md.tpl +4 -4
  30. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  31. package/dist/cli/templates/provider/operations/ping.ts.tpl +2 -1
  32. package/dist/config/loader.d.ts +177 -16
  33. package/dist/config/loader.js +424 -127
  34. package/dist/contract-serialization.js +4 -8
  35. package/dist/contract-types.d.ts +1 -0
  36. package/dist/contract.js +2 -0
  37. package/dist/declaration-validation.d.ts +32 -0
  38. package/dist/declaration-validation.js +207 -0
  39. package/dist/define.d.ts +51 -25
  40. package/dist/define.js +752 -38
  41. package/dist/error-resolution.d.ts +4 -0
  42. package/dist/error-resolution.js +122 -0
  43. package/dist/errors.d.ts +18 -0
  44. package/dist/errors.js +40 -0
  45. package/dist/fixture-sanitization.d.ts +28 -0
  46. package/dist/fixture-sanitization.js +217 -0
  47. package/dist/health-scenario.d.ts +1842 -0
  48. package/dist/health-scenario.js +624 -0
  49. package/dist/index.d.ts +19 -9
  50. package/dist/index.js +10 -6
  51. package/dist/lint.d.ts +6 -1
  52. package/dist/lint.js +362 -3
  53. package/dist/native-address.d.ts +43 -0
  54. package/dist/native-address.js +281 -0
  55. package/dist/native-egress-policy.d.ts +31 -0
  56. package/dist/native-egress-policy.js +288 -0
  57. package/dist/observability.d.ts +5 -2
  58. package/dist/observability.js +48 -1
  59. package/dist/provider.d.ts +8 -2
  60. package/dist/provider.js +3 -1
  61. package/dist/runtime/auth-flow.d.ts +5 -1
  62. package/dist/runtime/auth-flow.js +6 -0
  63. package/dist/runtime/browser.d.ts +1 -0
  64. package/dist/runtime/browser.js +492 -49
  65. package/dist/runtime/cache.d.ts +1 -0
  66. package/dist/runtime/cache.js +169 -15
  67. package/dist/runtime/choice-wordlist.d.ts +9 -0
  68. package/dist/runtime/choice-wordlist.js +138 -0
  69. package/dist/runtime/choice.d.ts +13 -1
  70. package/dist/runtime/choice.js +490 -102
  71. package/dist/runtime/executor.d.ts +2 -2
  72. package/dist/runtime/executor.js +26 -2
  73. package/dist/runtime/http.d.ts +1 -0
  74. package/dist/runtime/http.js +515 -53
  75. package/dist/runtime/instrumentation.d.ts +2 -2
  76. package/dist/runtime/instrumentation.js +366 -8
  77. package/dist/runtime/native-network-errors.d.ts +33 -0
  78. package/dist/runtime/native-network-errors.js +69 -0
  79. package/dist/runtime/native-network.d.ts +96 -0
  80. package/dist/runtime/native-network.js +1232 -0
  81. package/dist/runtime/ocr.d.ts +29 -0
  82. package/dist/runtime/ocr.js +440 -0
  83. package/dist/runtime/proxy-errors.js +6 -2
  84. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  85. package/dist/runtime/proxy-nodemaven.js +146 -0
  86. package/dist/runtime/proxy-telemetry.d.ts +80 -1
  87. package/dist/runtime/proxy-telemetry.js +154 -47
  88. package/dist/runtime/redirects.d.ts +29 -0
  89. package/dist/runtime/redirects.js +36 -0
  90. package/dist/runtime/redis.d.ts +1 -1
  91. package/dist/runtime/redis.js +4 -2
  92. package/dist/runtime/request-options.d.ts +68 -1
  93. package/dist/runtime/request-options.js +548 -0
  94. package/dist/runtime/resolver-config.d.ts +6 -0
  95. package/dist/runtime/resolver-config.js +6 -0
  96. package/dist/runtime/resolver-public.d.ts +1 -0
  97. package/dist/runtime/resolver-public.js +1 -0
  98. package/dist/runtime/resolver-shared.d.ts +3 -0
  99. package/dist/runtime/resolver-shared.js +12 -0
  100. package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
  101. package/dist/runtime/resolver-vendors/bindings.js +40 -0
  102. package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
  103. package/dist/runtime/resolver-vendors/browser.js +377 -0
  104. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  105. package/dist/runtime/resolver-vendors/capsolver.js +526 -0
  106. package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
  107. package/dist/runtime/resolver-vendors/hosts.js +33 -0
  108. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  109. package/dist/runtime/resolver-vendors/twocaptcha.js +407 -0
  110. package/dist/runtime/resolver-vendors/types.d.ts +94 -0
  111. package/dist/runtime/resolver-vendors/types.js +96 -0
  112. package/dist/runtime/resolver.d.ts +60 -0
  113. package/dist/runtime/resolver.js +737 -0
  114. package/dist/runtime/secrets.d.ts +27 -0
  115. package/dist/runtime/secrets.js +51 -0
  116. package/dist/runtime/state.d.ts +3 -0
  117. package/dist/runtime/state.js +277 -71
  118. package/dist/runtime/stealth-cookies.d.ts +20 -0
  119. package/dist/runtime/stealth-cookies.js +111 -0
  120. package/dist/runtime/stealth.d.ts +28 -3
  121. package/dist/runtime/stealth.js +519 -255
  122. package/dist/runtime/stt.js +1 -12
  123. package/dist/runtime/timeout.d.ts +5 -0
  124. package/dist/runtime/timeout.js +12 -0
  125. package/dist/runtime/trace-config.d.ts +12 -0
  126. package/dist/runtime/trace-config.js +61 -0
  127. package/dist/serve.d.ts +1 -1
  128. package/dist/serve.js +1 -1
  129. package/dist/server/index.d.ts +5 -3
  130. package/dist/server/index.js +3 -3
  131. package/dist/server/self-test-input-tokens.d.ts +2 -1
  132. package/dist/server/self-test-input-tokens.js +18 -14
  133. package/dist/server/self-test.d.ts +114 -0
  134. package/dist/server/self-test.js +784 -148
  135. package/dist/server/serve-implementation.d.ts +213 -0
  136. package/dist/server/serve-implementation.js +2173 -0
  137. package/dist/server/serve.d.ts +1 -70
  138. package/dist/server/serve.js +1 -1130
  139. package/dist/server/trace-output.d.ts +4 -0
  140. package/dist/server/trace-output.js +20 -0
  141. package/dist/server/types.d.ts +30 -5
  142. package/dist/server/types.js +13 -1
  143. package/dist/stateful/errors.d.ts +19 -0
  144. package/dist/stateful/errors.js +24 -0
  145. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  146. package/dist/stateful/http-provider-event-emitter.js +237 -0
  147. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  148. package/dist/stateful/http-session-owner-registry.js +210 -0
  149. package/dist/stateful/index.d.ts +18 -0
  150. package/dist/stateful/index.js +18 -0
  151. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  152. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  153. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  154. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  155. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  156. package/dist/stateful/provider-event-pipeline.js +1 -0
  157. package/dist/stateful/provider-events.d.ts +101 -0
  158. package/dist/stateful/provider-events.js +289 -0
  159. package/dist/stateful/session-key.d.ts +15 -0
  160. package/dist/stateful/session-key.js +86 -0
  161. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  162. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  163. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  164. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  165. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  166. package/dist/stateful/stateful-provider-adapter.js +287 -0
  167. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  168. package/dist/stateful/stateful-provider-observability.js +161 -0
  169. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  170. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  171. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  172. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  173. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  174. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  175. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  176. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  177. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  178. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  179. package/dist/stateful-signing.d.ts +18 -0
  180. package/dist/stateful-signing.js +27 -0
  181. package/dist/stealth/profiles.js +16 -7
  182. package/dist/stream-evidence.d.ts +74 -0
  183. package/dist/stream-evidence.js +785 -0
  184. package/dist/stream.js +7 -1
  185. package/dist/testing/index.d.ts +2 -1
  186. package/dist/testing/index.js +2 -1
  187. package/dist/testing/run.d.ts +32 -2
  188. package/dist/testing/run.js +489 -21
  189. package/dist/trace-sanitization.d.ts +5 -0
  190. package/dist/trace-sanitization.js +45 -0
  191. package/dist/types.d.ts +545 -23
  192. package/dist/types.js +1 -0
  193. package/package.json +44 -5
  194. package/src/auth-turn/index.ts +1 -1
  195. package/src/auth.ts +118 -0
  196. package/src/ceremonies/index.ts +189 -46
  197. package/src/cli/commands.ts +10 -0
  198. package/src/cli/create.ts +42 -35
  199. package/src/cli/prompt-assets.ts +865 -0
  200. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  201. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  202. package/src/cli/templates/provider/README.md.tpl +4 -4
  203. package/src/cli/templates/provider/index.ts.tpl +6 -3
  204. package/src/cli/templates/provider/operations/ping.ts.tpl +2 -1
  205. package/src/config/loader.ts +665 -163
  206. package/src/contract-serialization.ts +5 -7
  207. package/src/contract-types.ts +1 -0
  208. package/src/contract.ts +2 -0
  209. package/src/declaration-validation.ts +266 -0
  210. package/src/define.ts +970 -87
  211. package/src/error-resolution.ts +127 -0
  212. package/src/errors.ts +52 -0
  213. package/src/fixture-sanitization.ts +248 -0
  214. package/src/health-scenario.ts +875 -0
  215. package/src/index.ts +204 -8
  216. package/src/lint.ts +408 -4
  217. package/src/native-address.ts +340 -0
  218. package/src/native-egress-policy.ts +358 -0
  219. package/src/observability.ts +51 -1
  220. package/src/provider.ts +133 -0
  221. package/src/runtime/auth-flow.ts +12 -0
  222. package/src/runtime/browser.ts +661 -63
  223. package/src/runtime/cache.ts +189 -14
  224. package/src/runtime/choice-wordlist.ts +145 -0
  225. package/src/runtime/choice.ts +631 -120
  226. package/src/runtime/executor.ts +40 -7
  227. package/src/runtime/http.ts +641 -61
  228. package/src/runtime/instrumentation.ts +520 -15
  229. package/src/runtime/native-network-errors.ts +99 -0
  230. package/src/runtime/native-network.ts +1605 -0
  231. package/src/runtime/ocr.ts +523 -0
  232. package/src/runtime/proxy-errors.ts +12 -4
  233. package/src/runtime/proxy-nodemaven.ts +221 -0
  234. package/src/runtime/proxy-telemetry.ts +244 -75
  235. package/src/runtime/redirects.ts +66 -0
  236. package/src/runtime/redis.ts +7 -2
  237. package/src/runtime/request-options.ts +680 -1
  238. package/src/runtime/resolver-config.ts +6 -0
  239. package/src/runtime/resolver-public.ts +20 -0
  240. package/src/runtime/resolver-shared.ts +17 -0
  241. package/src/runtime/resolver-vendors/bindings.ts +56 -0
  242. package/src/runtime/resolver-vendors/browser.ts +533 -0
  243. package/src/runtime/resolver-vendors/capsolver.ts +700 -0
  244. package/src/runtime/resolver-vendors/hosts.ts +38 -0
  245. package/src/runtime/resolver-vendors/twocaptcha.ts +539 -0
  246. package/src/runtime/resolver-vendors/types.ts +212 -0
  247. package/src/runtime/resolver.ts +1103 -0
  248. package/src/runtime/secrets.ts +64 -0
  249. package/src/runtime/state.ts +394 -77
  250. package/src/runtime/stealth-cookies.ts +132 -0
  251. package/src/runtime/stealth.ts +675 -289
  252. package/src/runtime/stt.ts +1 -19
  253. package/src/runtime/timeout.ts +18 -0
  254. package/src/runtime/trace-config.ts +77 -0
  255. package/src/serve.ts +6 -1
  256. package/src/server/index.ts +37 -2
  257. package/src/server/self-test-input-tokens.ts +29 -14
  258. package/src/server/self-test.ts +1025 -175
  259. package/src/server/serve-implementation.ts +3250 -0
  260. package/src/server/serve.ts +1 -1626
  261. package/src/server/trace-output.ts +32 -0
  262. package/src/server/types.ts +13 -1
  263. package/src/stateful/README.md +146 -0
  264. package/src/stateful/errors.ts +35 -0
  265. package/src/stateful/http-provider-event-emitter.ts +314 -0
  266. package/src/stateful/http-session-owner-registry.ts +306 -0
  267. package/src/stateful/index.ts +18 -0
  268. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  269. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  270. package/src/stateful/provider-event-pipeline.ts +61 -0
  271. package/src/stateful/provider-events.ts +462 -0
  272. package/src/stateful/session-key.ts +111 -0
  273. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  274. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  275. package/src/stateful/stateful-provider-adapter.ts +562 -0
  276. package/src/stateful/stateful-provider-observability.ts +261 -0
  277. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  278. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  279. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  280. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  281. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  282. package/src/stateful-signing.ts +46 -0
  283. package/src/stealth/profiles.ts +17 -7
  284. package/src/stream-evidence.ts +988 -0
  285. package/src/stream.ts +8 -1
  286. package/src/testing/index.ts +10 -1
  287. package/src/testing/run.ts +658 -15
  288. package/src/trace-sanitization.ts +63 -0
  289. package/src/types.ts +660 -38
  290. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  291. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  292. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  293. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  294. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  295. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  296. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  297. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  298. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  299. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  300. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  301. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  302. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  303. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/src/types.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import type ms from "ms";
2
+ import type { HealthScenario } from "./health-scenario.js";
3
+ import type { SerializedCookieJar } from "tough-cookie";
2
4
 
3
5
  import type { infer as ZodInfer, ZodType } from "zod";
4
6
 
@@ -62,6 +64,8 @@ export interface OperationToolRouterMetadata {
62
64
  riskClass?: OperationRiskClass;
63
65
  /** OpenAI remote-MCP approval hint. Defaults from riskClass. */
64
66
  approval?: OperationApprovalPolicy;
67
+ /** Canonical operation-level connection requirement consumed by the registry and Gateway. */
68
+ connectionMode?: "none" | "optional" | "required";
65
69
  /** Override connection requirement when provider auth + openWorld inference is insufficient. */
66
70
  requiresConnection?: boolean;
67
71
  /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
@@ -210,14 +214,14 @@ export type SmsOrigin =
210
214
  kind: "e164";
211
215
  value: E164PhoneNumber;
212
216
  display?: string;
213
- }
217
+ }
214
218
  | {
215
219
  /** Country-local service sender, for example KR 1661-5270. */
216
220
  kind: "nationalServiceCode";
217
221
  country: Iso3166Alpha2CountryCode;
218
222
  value: string;
219
223
  display?: string;
220
- };
224
+ };
221
225
 
222
226
  export interface SmsOtpExtractionPattern {
223
227
  /** RegExp or source string containing exactly one usable OTP capture. */
@@ -240,6 +244,61 @@ export interface SmsOtpMatcherDefinition {
240
244
  extractOtp(body: string): string | null;
241
245
  }
242
246
 
247
+ export interface ProviderOcrConfig {
248
+ readonly mode: "required" | "optional";
249
+ }
250
+
251
+ export type OcrImageInput =
252
+ | { readonly kind: "base64"; readonly data: string; readonly mediaType?: string }
253
+ | { readonly kind: "url"; readonly url: string };
254
+
255
+ export interface OcrRecognizeRequest {
256
+ readonly image: OcrImageInput;
257
+ readonly hint?: "captcha" | "document" | "generic";
258
+ readonly prompt?: string;
259
+ readonly maxTokens?: number;
260
+ readonly timeoutMs?: number;
261
+ }
262
+
263
+ export interface OcrWarning {
264
+ readonly code: string;
265
+ readonly message: string;
266
+ }
267
+
268
+ export interface OcrResult {
269
+ readonly text: string;
270
+ readonly model: string;
271
+ readonly warnings?: readonly OcrWarning[];
272
+ }
273
+
274
+ export interface OcrCaptchaOptions {
275
+ readonly length?: number;
276
+ /** Allowed characters. A RegExp is applied to each character, not to the whole text. */
277
+ readonly charset?: string | RegExp;
278
+ readonly caseSensitive?: boolean;
279
+ readonly maxCandidates?: number;
280
+ }
281
+
282
+ export interface OcrCaptchaCandidate {
283
+ readonly text: string;
284
+ readonly satisfiesConstraints: boolean;
285
+ }
286
+
287
+ export interface OcrCaptchaResult {
288
+ readonly text: string;
289
+ readonly candidates: readonly OcrCaptchaCandidate[];
290
+ readonly satisfiesConstraints: boolean;
291
+ readonly model: string;
292
+ }
293
+
294
+ export interface OcrContext {
295
+ recognize(request: OcrRecognizeRequest): Promise<OcrResult>;
296
+ extractCaptchaText(
297
+ image: OcrImageInput,
298
+ options?: OcrCaptchaOptions,
299
+ ): Promise<OcrCaptchaResult>;
300
+ }
301
+
243
302
  export type SttTranscribeMode = "general" | "otp";
244
303
  export type SttPromptPolicy = "none" | "default-hint" | "custom-hint";
245
304
  export type SttUnsupportedOptionPolicy = "warn" | "error";
@@ -249,6 +308,123 @@ export interface ProviderSttConfig {
249
308
  mode: ProviderSttMode;
250
309
  }
251
310
 
311
+ /**
312
+ * Union order is documentation only.
313
+ *
314
+ * The SDK owns the default hosted-vendor fallback policy and derives the chain
315
+ * from each provider's declared challenge kinds. Hosted solvers are preferred
316
+ * with `capsolver` ahead of `2captcha` in that policy.
317
+ *
318
+ * `browser` is the in-house CDP pool and remains opt-in; it is excluded from the
319
+ * default chain. `custom` is likewise reserved for provider-specific configuration.
320
+ *
321
+ * `ProviderResolverConfig.vendors` overrides the SDK policy when declared.
322
+ */
323
+ export type ProviderResolverVendor =
324
+ | "browser"
325
+ | "capsolver"
326
+ | "capmonster"
327
+ | "2captcha"
328
+ | "custom";
329
+
330
+ /**
331
+ * Token-family kinds resolve to `{ form: "token" }`. Cookie-family kinds resolve
332
+ * to `{ form: "cookies" }`; network-identity binding is defined per kind. `aws_waf`
333
+ * was measured portable across residential leases on buyee, while `cf_clearance`
334
+ * remains unmeasured here and is treated as identity-scoped because it is widely
335
+ * described as IP-bound.
336
+ */
337
+ export type ProviderChallenge =
338
+ | {
339
+ readonly kind: "turnstile";
340
+ readonly siteKey: string;
341
+ readonly pageUrl: string;
342
+ readonly action?: string;
343
+ readonly cdata?: string;
344
+ }
345
+ | {
346
+ readonly kind: "recaptcha_v2";
347
+ readonly siteKey: string;
348
+ readonly pageUrl: string;
349
+ }
350
+ | {
351
+ readonly kind: "recaptcha_v3";
352
+ readonly siteKey: string;
353
+ readonly pageUrl: string;
354
+ readonly action: string;
355
+ readonly minScore?: number;
356
+ }
357
+ | {
358
+ readonly kind: "hcaptcha";
359
+ readonly siteKey: string;
360
+ readonly pageUrl: string;
361
+ }
362
+ | {
363
+ readonly kind: "cloudflare_interstitial";
364
+ readonly pageUrl: string;
365
+ readonly blockedHtml?: string;
366
+ }
367
+ | {
368
+ readonly kind: "aws_waf";
369
+ readonly pageUrl: string;
370
+ /** `window.gokuProps.key`; solver vendors require it, while `"browser"` does not. */
371
+ readonly siteKey?: string;
372
+ readonly captchaScript?: string;
373
+ readonly context?: string;
374
+ readonly iv?: string;
375
+ }
376
+ | {
377
+ readonly kind: "akamai_sec_cpt";
378
+ readonly pageUrl: string;
379
+ /** The admitted challenge document, needed for tile/context extraction. */
380
+ readonly challengeHtml?: string;
381
+ }
382
+ | {
383
+ readonly kind: "akamai_sensor";
384
+ readonly pageUrl: string;
385
+ /** Upstream sensor script URL the payload must be POSTed to. */
386
+ readonly scriptUrl: string;
387
+ /** Current `_abck` cookie value, rotates each round. */
388
+ readonly abck?: string;
389
+ /** Current `bm_sz` / `ak_bmsc` value when the upstream set one. */
390
+ readonly bmsz?: string;
391
+ /** Bot Manager major version when known ("3" measured on zozo.jp). */
392
+ readonly version?: string;
393
+ };
394
+
395
+ export type ProviderChallengeKind = ProviderChallenge["kind"];
396
+
397
+ /**
398
+ * Token solutions carry no network-identity binding. Cookie-solution binding is
399
+ * per challenge kind: `aws_waf` was measured portable across residential leases
400
+ * on buyee, while `cf_clearance` is unmeasured here and treated as scoped to the
401
+ * identity that produced it. The provider attaches the returned cookies to its
402
+ * own requests.
403
+ */
404
+ export type ChallengeSolution =
405
+ | { readonly form: "token"; readonly token: string }
406
+ | {
407
+ readonly form: "cookies";
408
+ readonly cookies: Readonly<Record<string, string>>;
409
+ readonly userAgent: string;
410
+ /** Epoch seconds copied from the upstream cookie's own expiry attribute; never a constant. */
411
+ readonly expires?: number;
412
+ };
413
+
414
+ export interface ProviderResolverConfig {
415
+ /** Optional ordered override for the SDK-owned vendor fallback chain. */
416
+ readonly vendors?: readonly ProviderResolverVendor[];
417
+ /** Challenge kinds this provider is permitted to request. */
418
+ readonly kinds: readonly ProviderChallengeKind[];
419
+ /**
420
+ * Client fingerprint profile the SDK must use when reaching this upstream.
421
+ * Measured on zozo.jp: Chrome/Firefox profiles are refused 403 before any
422
+ * challenge is served, while a Safari profile is admitted. Provider-declared
423
+ * because only the provider knows its upstream's admission rule.
424
+ */
425
+ readonly clientProfile?: string;
426
+ }
427
+
252
428
  export type SttAudioInput = {
253
429
  kind: "base64";
254
430
  data: string;
@@ -327,6 +503,10 @@ export interface SttContext {
327
503
  ): VerificationCodeExtractionResult;
328
504
  }
329
505
 
506
+ export interface ResolverContext {
507
+ solve(challenge: ProviderChallenge, signal?: AbortSignal): Promise<ChallengeSolution>;
508
+ }
509
+
330
510
  export interface HealthJourneySchedule {
331
511
  kind: "interval";
332
512
  /** ISO 8601 duration, for example PT8H. */
@@ -339,11 +519,11 @@ export type HealthScheduleRandomization =
339
519
  | {
340
520
  mode: "centered";
341
521
  maxOffset: Iso8601Duration;
342
- }
522
+ }
343
523
  | {
344
524
  mode: "delayed";
345
525
  maxDelay: Iso8601Duration;
346
- };
526
+ };
347
527
 
348
528
  export interface HealthJourneyStep {
349
529
  id: string;
@@ -458,7 +638,7 @@ export type HealthJourneyManualTriggerPolicy =
458
638
  /** ISO 8601 duration. Minimum time between manual executions. */
459
639
  minManualInterval: Iso8601Duration;
460
640
  publicRationale: string;
461
- };
641
+ };
462
642
 
463
643
  export interface HealthJourneyRunResult {
464
644
  status?: "ok" | "degraded" | "down" | "unknown";
@@ -466,7 +646,7 @@ export interface HealthJourneyRunResult {
466
646
  metadata?: Record<string, unknown>;
467
647
  }
468
648
 
469
- export interface HealthJourneyDefinition {
649
+ interface HealthJourneyDefinitionBase {
470
650
  id: string;
471
651
  title?: string;
472
652
  description?: string;
@@ -478,11 +658,17 @@ export interface HealthJourneyDefinition {
478
658
  requiredSecrets?: readonly string[];
479
659
  manualTrigger?: HealthJourneyManualTriggerPolicy;
480
660
  steps: readonly [HealthJourneyStep, ...HealthJourneyStep[]];
481
- run?: (
482
- ctx: HealthJourneyRunContext,
483
- ) => Promise<HealthJourneyRunResult | undefined>;
484
661
  }
485
662
 
663
+ export type HealthJourneyDefinition = HealthJourneyDefinitionBase &
664
+ (
665
+ | {
666
+ run: (ctx: HealthJourneyRunContext) => Promise<HealthJourneyRunResult | undefined>;
667
+ scenario?: never;
668
+ }
669
+ | { scenario: HealthScenario; run?: never }
670
+ );
671
+
486
672
  /**
487
673
  * Health-check authoring surface owned by `@apifuse/provider-sdk`.
488
674
  *
@@ -718,9 +904,13 @@ export interface HealthMonitorProbeOverride {
718
904
  degradedThresholdMs?: number;
719
905
  }
720
906
 
907
+ export const VALID_OPERATION_ERROR_STATUSES = [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504] as const;
908
+
909
+ export type ProviderErrorStatus = (typeof VALID_OPERATION_ERROR_STATUSES)[number];
910
+
721
911
  export interface OperationErrorCode {
722
912
  code: string;
723
- status?: number;
913
+ status?: ProviderErrorStatus;
724
914
  description: string;
725
915
  retryable?: boolean;
726
916
  }
@@ -759,7 +949,12 @@ export interface StealthProfile {
759
949
  headerOrder?: string[];
760
950
  }
761
951
 
762
- export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2";
952
+ export type AuthMode =
953
+ | "none"
954
+ | "platform-managed"
955
+ | "credentials"
956
+ | "oauth2"
957
+ | "oauth2_proxied";
763
958
 
764
959
  export type ConnectionMode = AuthMode;
765
960
 
@@ -769,7 +964,27 @@ export type ProviderAccessVisibility = "public" | "early_access";
769
964
 
770
965
  export type ProviderProxyMode = "disabled" | "optional" | "required";
771
966
 
772
- export type ProviderProxyProvider = "smartproxy" | "decodo" | "custom";
967
+ /**
968
+ * Proxy egress vendors. These are FOUR DISTINCT services — do not conflate them
969
+ * (a common mistake because the names collide with a well-known rebrand):
970
+ *
971
+ * - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
972
+ * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
973
+ * endpoints). This is our own vendor. It is NOT the company formerly named
974
+ * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
975
+ * - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
976
+ * credentials; geo/session encoded in the username, no allocation API.
977
+ * - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
978
+ * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
979
+ * username params. A different company from `smartproxy` above.
980
+ * **@deprecated** — unused; no managed adapter. Declare a
981
+ * `ProviderProxyPolicy` using `smartproxy` or `nodemaven` instead; the
982
+ * `smartproxy` allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
983
+ * - `custom` — **@deprecated** static proxy marker with no managed adapter.
984
+ * Use `ProviderProxyPolicy` with `smartproxy`/`nodemaven`; the `smartproxy`
985
+ * allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
986
+ */
987
+ export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
773
988
 
774
989
  export type ProviderProxySessionAffinity =
775
990
  | "request"
@@ -783,7 +998,18 @@ export interface ProviderProxyPolicy {
783
998
  * certificate verification, and vendor allocator endpoints are SDK-owned.
784
999
  */
785
1000
  mode: ProviderProxyMode;
1001
+ /**
1002
+ * @deprecated Use `providers: [...]` to declare an ordered vendor fallback
1003
+ * chain. A single-element `providers` list is equivalent to this field.
1004
+ */
786
1005
  provider?: ProviderProxyProvider;
1006
+ /**
1007
+ * Ordered proxy-vendor fallback chain. The SDK tries each vendor in order and
1008
+ * fails over to the next when a vendor lacks credentials or its allocation /
1009
+ * transport is exhausted. When omitted, `provider` (or the platform default)
1010
+ * is used as a single-vendor chain.
1011
+ */
1012
+ providers?: ProviderProxyProvider[];
787
1013
  geo?: {
788
1014
  /** ISO 3166-1 alpha-2 country code, for example KR or US. */
789
1015
  country?: Iso3166Alpha2CountryCode;
@@ -794,6 +1020,12 @@ export interface ProviderProxyPolicy {
794
1020
  affinity?: ProviderProxySessionAffinity;
795
1021
  lifetimeMinutes?: number;
796
1022
  poolSize?: number;
1023
+ /**
1024
+ * Seconds before hard sticky expiry at which native connections receive
1025
+ * the `expiring` event so the provider can drain and reconnect cleanly.
1026
+ * Declared by the provider; the SDK does not assume a default cut point.
1027
+ */
1028
+ drainLeadSeconds?: number;
797
1029
  };
798
1030
  }
799
1031
 
@@ -804,9 +1036,9 @@ export interface ProviderAccessConfig {
804
1036
  * Provider-level rollout visibility.
805
1037
  *
806
1038
  * - `public`: visible in public docs/catalog/OpenAPI and callable through
807
- * the existing provider policy stack.
1039
+ * the existing provider policy stack.
808
1040
  * - `early_access`: hidden from public discovery and callable only when the
809
- * active customer organization has a provider-level access grant.
1041
+ * active customer organization has a provider-level access grant.
810
1042
  *
811
1043
  * This is intentionally provider-level only. It does not alter auth mode,
812
1044
  * operation schemas, health-check authoring, `openWorld`, or Connection
@@ -828,12 +1060,12 @@ export type ProviderLogoProfile =
828
1060
  */
829
1061
  url?: string;
830
1062
  background?: string;
831
- }
1063
+ }
832
1064
  | {
833
1065
  source: "monogram" | "none";
834
1066
  background?: string;
835
1067
  fallbackReason: string;
836
- };
1068
+ };
837
1069
 
838
1070
  export type ProviderPublicConnectionMode =
839
1071
  | "apifuse_managed"
@@ -970,6 +1202,11 @@ export interface HttpRetrySummary {
970
1202
  export interface RequestOptions {
971
1203
  headers?: Record<string, string>;
972
1204
  params?: RequestParams;
1205
+ /**
1206
+ * Query parameters whose values contain credentials or other secret material.
1207
+ * They are sent like `params`, but redacted from SDK errors, traces, and recorded fixtures.
1208
+ */
1209
+ sensitiveParams?: Record<string, string>;
973
1210
  proxy?: string;
974
1211
  timeout?: number;
975
1212
  /**
@@ -978,8 +1215,32 @@ export interface RequestOptions {
978
1215
  */
979
1216
  throwOnHttpError?: boolean;
980
1217
  retry?: boolean | HttpRetryPreset | HttpRetryOptions;
1218
+ /**
1219
+ * Opt-in redirect-hop enforcement for ctx.http. When present, redirects are
1220
+ * evaluated before the next request is issued. Existing callers that omit
1221
+ * this policy retain the native fetch redirect behavior.
1222
+ */
1223
+ redirectPolicy?: HttpRedirectPolicy;
1224
+ }
1225
+
1226
+ export type RedirectRunReason =
1227
+ | "completed"
1228
+ | "stopped"
1229
+ | "max_hops"
1230
+ | "missing_location"
1231
+ | "loop";
1232
+
1233
+ export type HttpRedirectPolicyMode = "same-origin";
1234
+
1235
+ export interface HttpRedirectPolicy {
1236
+ /** Only follow redirects whose canonical scheme, host, and port match the initial URL. */
1237
+ mode: HttpRedirectPolicyMode;
1238
+ /** Maximum number of redirect hops that may be followed. Must be an integer from 0 to 20. */
1239
+ maxHops: number;
981
1240
  }
982
1241
 
1242
+ export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
1243
+
983
1244
  export type HttpMethod =
984
1245
  | "HEAD"
985
1246
  | "head"
@@ -998,10 +1259,16 @@ export type HttpMethod =
998
1259
  | "PATCH"
999
1260
  | "patch";
1000
1261
 
1001
- export interface StealthFetchOptions extends RequestOptions {
1262
+ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy"> {
1002
1263
  method?: HttpMethod;
1003
1264
  body?: string | Buffer;
1004
1265
  redirect?: "follow" | "manual" | "error";
1266
+ /**
1267
+ * Maximum decoded response-body bytes to buffer. When set, the stealth
1268
+ * transport aborts the response and throws `response_too_large` if the
1269
+ * declared or streamed body exceeds this limit.
1270
+ */
1271
+ maxBodyBytes?: number;
1005
1272
  /**
1006
1273
  * Offsets policy-managed proxy pool selection for caller-managed retries.
1007
1274
  * Use when a request receives an upstream challenge page rather than a
@@ -1022,18 +1289,45 @@ export interface StealthFetchOptions extends RequestOptions {
1022
1289
  }
1023
1290
 
1024
1291
  export interface CookieJar {
1025
- get(name: string): string | undefined;
1026
- getAll(): Record<string, string>;
1027
- toString(): string;
1028
- find?(predicate: (cookie: string) => boolean): string | undefined;
1292
+ /** URL-less reads use the jar's response URL or session base URL. */
1293
+ get(name: string, url?: string): string | undefined;
1294
+ getAll(url?: string): Record<string, string>;
1295
+ toString(url?: string): string;
1296
+ find?(predicate: (cookie: string) => boolean, url?: string): string | undefined;
1029
1297
  }
1030
1298
 
1299
+ /**
1300
+ * Version 1 of the JSON-safe, attribute-preserving stealth cookie store.
1301
+ * The nested jar is tough-cookie's serialized form and retains cookie origin,
1302
+ * Path, Secure, expiry, host-only, and other RFC attributes.
1303
+ */
1304
+ export interface StealthCookieStoreV1 {
1305
+ readonly version: 1;
1306
+ readonly jar: SerializedCookieJar;
1307
+ }
1308
+
1309
+ /** Cookie persistence formats understood by this SDK version. */
1310
+ export type StealthCookieStore = StealthCookieStoreV1;
1311
+
1031
1312
  export interface StealthSessionCookies extends CookieJar {
1032
- has(name: string): boolean;
1033
- setFromCookieStrings(cookieStrings: readonly string[]): void;
1034
- toHeader(): string;
1313
+ has(name: string, url?: string): boolean;
1314
+ /** URL-less writes are scoped to the session base URL. */
1315
+ setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
1316
+ toHeader(url?: string): string;
1317
+ /**
1318
+ * Returns every cookie as a flat name/value map, collapsing duplicate names.
1319
+ * @deprecated Use serialize() for lossless, attribute-preserving persistence.
1320
+ */
1035
1321
  snapshot(): Record<string, string>;
1322
+ /**
1323
+ * Restores flat values as host-only, Path=/ cookies on the session base URL.
1324
+ * @deprecated Use deserialize() with state produced by serialize().
1325
+ */
1036
1326
  restore(cookies: Record<string, string>): void;
1327
+ /** Returns a versioned, JSON-safe, attribute-preserving representation of every cookie. */
1328
+ serialize(): StealthCookieStoreV1;
1329
+ /** Replaces the jar with a previously serialized, attribute-preserving cookie store. */
1330
+ deserialize(state: StealthCookieStore): void;
1037
1331
  clear(): void;
1038
1332
  }
1039
1333
 
@@ -1078,8 +1372,14 @@ export interface StealthRedirectRunOptions
1078
1372
  export interface StealthRedirectRunResult {
1079
1373
  final: StealthResponse;
1080
1374
  hops: StealthRedirectHop[];
1081
- reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
1375
+ reason: RedirectRunReason;
1376
+ /**
1377
+ * Complete flat view across all redirect hosts. Attributes and duplicate names are lost.
1378
+ * @deprecated Use cookieStore for lossless persistence.
1379
+ */
1082
1380
  cookies: Record<string, string>;
1381
+ /** Versioned, attribute-preserving cookie state accumulated across the redirect chain. */
1382
+ cookieStore: StealthCookieStoreV1;
1083
1383
  }
1084
1384
 
1085
1385
  export interface StealthSession {
@@ -1169,11 +1469,188 @@ export interface HttpClient {
1169
1469
  ): Promise<AsyncIterable<SseMessage>>;
1170
1470
  }
1171
1471
 
1472
+ /** Request-scoped file reference accepted by provider operation inputs. */
1473
+ export interface ProviderFileRef {
1474
+ readonly type: "request_file";
1475
+ readonly id: string;
1476
+ readonly filename: string;
1477
+ readonly mime_type?: string;
1478
+ readonly size: number;
1479
+ readonly sha256?: string;
1480
+ }
1481
+
1482
+ /** File body resolved from a request-scoped {@link ProviderFileRef}. */
1483
+ export type ProviderResolvedFile = Omit<ProviderFileRef, "mime_type"> & {
1484
+ readonly mimeType?: string;
1485
+ arrayBuffer(): Promise<ArrayBuffer>;
1486
+ bytes(): Promise<Uint8Array>;
1487
+ stream(): ReadableStream<Uint8Array>;
1488
+ };
1489
+
1490
+ /** Resolver supplied by runtimes that accept request-scoped file inputs. */
1491
+ export interface ProviderFilesContext {
1492
+ has(input: string | ProviderFileRef): boolean;
1493
+ resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
1494
+ }
1495
+
1496
+ export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
1497
+
1498
+ export interface NativeTcpPortRange {
1499
+ readonly start: number;
1500
+ readonly end: number;
1501
+ }
1502
+
1503
+ /** Static native TCP egress declared by a provider. */
1504
+ export interface NativeTcpEgressRule {
1505
+ readonly host: string;
1506
+ readonly ports: readonly number[];
1507
+ readonly tls: NativeTcpTlsMode;
1508
+ }
1509
+
1510
+ /**
1511
+ * Bounded native TCP egress discovered through a declared bootstrap endpoint.
1512
+ * Host suffixes are exact DNS suffixes, not wildcard patterns.
1513
+ * Dynamic rules must declare at least one target host selector through
1514
+ * targetHostSuffixes, targetIpv4Cidrs, and/or targetIpv6Cidrs. Literal grant
1515
+ * sources and targets match only same-family selectors (except exact
1516
+ * sourceHost); DNS names match only host/suffix selectors. IPv4-mapped and
1517
+ * IPv4-compatible IPv6 literals are authorized only by IPv4 CIDRs.
1518
+ *
1519
+ * Dynamic rules are ordered. The first rule whose source, target, port, and TLS
1520
+ * selectors match exclusively owns the grant; its ttlMs and maxGrants bounds
1521
+ * apply, and an exhausted/shorter rule never falls through to a later overlap.
1522
+ * Every rule must declare a source host selector, source port list/range, and
1523
+ * target port list/range; omitted ttlMs/maxGrants remain unbounded.
1524
+ */
1525
+ export interface NativeTcpDynamicEgressRule {
1526
+ readonly sourceHost?: string;
1527
+ readonly sourceHostSuffixes?: readonly string[];
1528
+ readonly sourceIpv4Cidrs?: readonly string[];
1529
+ readonly sourceIpv6Cidrs?: readonly string[];
1530
+ readonly sourcePorts?: readonly number[];
1531
+ readonly sourcePortRanges?: readonly NativeTcpPortRange[];
1532
+ readonly targetHostSuffixes?: readonly string[];
1533
+ readonly targetIpv4Cidrs?: readonly string[];
1534
+ readonly targetIpv6Cidrs?: readonly string[];
1535
+ readonly targetPorts?: readonly number[];
1536
+ readonly targetPortRanges?: readonly NativeTcpPortRange[];
1537
+ readonly tls: NativeTcpTlsMode;
1538
+ readonly ttlMs?: number;
1539
+ readonly maxGrants?: number;
1540
+ }
1541
+
1542
+ /** Common TCP/TLS connection input supported by the native runtime. */
1543
+ export interface NativeNetworkConnectInput {
1544
+ readonly host: string;
1545
+ readonly port: number;
1546
+ readonly serverName?: string;
1547
+ readonly rejectUnauthorized?: boolean;
1548
+ /**
1549
+ * Maximum time without a successful socket read before the connection is
1550
+ * closed. Opt-in; when absent, reads can remain pending indefinitely.
1551
+ */
1552
+ readonly idleTimeoutMs?: number;
1553
+ /** Maximum time allowed to establish the TCP/SOCKS/TLS connection. */
1554
+ readonly timeoutMs?: number;
1555
+ readonly signal?: AbortSignal;
1556
+ /** Overrides the credential-derived sticky affinity key. */
1557
+ readonly affinityKey?: string;
1558
+ }
1559
+
1560
+ export type NativeNetworkConnectOptions = Omit<
1561
+ NativeNetworkConnectInput,
1562
+ "serverName" | "rejectUnauthorized"
1563
+ >;
1564
+
1565
+ export type NativeTlsConnectOptions = NativeNetworkConnectInput;
1566
+
1567
+ export interface NativeNetworkDynamicGrantOptions {
1568
+ readonly sourceHost: string;
1569
+ readonly sourcePort: number;
1570
+ readonly host: string;
1571
+ readonly port: number;
1572
+ readonly tls: NativeTcpTlsMode;
1573
+ readonly ttlMs?: number;
1574
+ }
1575
+
1576
+ export interface NativeNetworkEgressGrant {
1577
+ revoke(): void;
1578
+ }
1579
+
1580
+ /** Consumer-facing alias used by native TCP providers. */
1581
+ export type NativeTcpEgressGrant = NativeNetworkEgressGrant;
1582
+
1583
+ /** Resolved egress identity for a native connection routed through a proxy. */
1584
+ export interface NativeProxyEgressInfo {
1585
+ readonly vendor: ProviderProxyProvider;
1586
+ readonly sticky: boolean;
1587
+ /** Vendor sticky session id (sid). Absent for rotating sessions. */
1588
+ readonly sessionId?: string;
1589
+ /** Hard expiry of the sticky binding, ISO 8601. */
1590
+ readonly expiresAt?: string;
1591
+ }
1592
+
1593
+ export type NativeProxyExpiringReason = "sticky_expiry";
1594
+
1595
+ export interface NativeProxyExpiringEvent {
1596
+ readonly expiresAt: string;
1597
+ readonly leadSeconds: number;
1598
+ readonly reason: NativeProxyExpiringReason;
1599
+ }
1600
+
1601
+ /**
1602
+ * Cooperative drain handler. The SDK awaits this before closing a socket whose
1603
+ * sticky proxy binding is about to expire, then force-closes at hard expiry.
1604
+ */
1605
+ export type NativeProxyDrainHandler = (
1606
+ event: NativeProxyExpiringEvent,
1607
+ ) => void | Promise<void>;
1608
+
1609
+ /** Typed reason recorded when the SDK closes a native connection intentionally. */
1610
+ export interface NativeNetworkCloseReason {
1611
+ readonly code: string;
1612
+ readonly message: string;
1613
+ }
1614
+
1615
+ /** Byte-oriented connection returned by the native TCP/TLS runtime. */
1616
+ export interface NativeNetworkConnection {
1617
+ /** Present when the connection was routed through a proxy. */
1618
+ readonly proxy?: NativeProxyEgressInfo;
1619
+ /** Present after an SDK-planned close, such as sticky proxy expiry. */
1620
+ readonly closeReason?: NativeNetworkCloseReason;
1621
+ /** Register a cooperative drain handler for sticky-expiry reconnects. */
1622
+ onExpiring?(handler: NativeProxyDrainHandler): void;
1623
+ read(): Promise<Uint8Array | null>;
1624
+ write(data: Uint8Array): Promise<void>;
1625
+ close(): Promise<void>;
1626
+ }
1627
+
1628
+ export interface NativeNetworkClient {
1629
+ connectTcp(
1630
+ input: NativeNetworkConnectOptions,
1631
+ ): Promise<NativeNetworkConnection>;
1632
+ connectTls(input: NativeTlsConnectOptions): Promise<NativeNetworkConnection>;
1633
+ grantTcpEgress(
1634
+ input: NativeNetworkDynamicGrantOptions,
1635
+ ): NativeNetworkEgressGrant;
1636
+ }
1637
+
1638
+ export interface NativeContext {
1639
+ readonly network: NativeNetworkClient;
1640
+ }
1641
+
1642
+ export interface NativeProviderConfig {
1643
+ readonly network?: {
1644
+ readonly tcp?: readonly NativeTcpEgressRule[];
1645
+ readonly dynamicTcp?: readonly NativeTcpDynamicEgressRule[];
1646
+ };
1647
+ }
1648
+
1172
1649
  export interface ProviderCacheKeyOptions {
1173
1650
  /**
1174
- * Additional field names to omit from stable key material. The SDK always
1175
- * omits known secret-bearing names such as serviceKey, authorization,
1176
- * cookie, token, password, and secret.
1651
+ * Additional field names whose values are hashed in stable key material. The
1652
+ * SDK always hashes values under known secret-bearing names such as serviceKey,
1653
+ * authorization, cookie, token, password, and secret.
1177
1654
  */
1178
1655
  redactFields?: string[];
1179
1656
  }
@@ -1268,7 +1745,19 @@ export interface BrowserFrame {
1268
1745
  locator(selector: string): BrowserLocator;
1269
1746
  }
1270
1747
 
1271
- export type BrowserResourceMethod = "GET" | "HEAD";
1748
+ export interface BrowserCookie {
1749
+ readonly name: string;
1750
+ readonly value: string;
1751
+ readonly domain: string;
1752
+ readonly path: string;
1753
+ /** Unix seconds. Absent for a session cookie. */
1754
+ readonly expires?: number;
1755
+ readonly httpOnly: boolean;
1756
+ readonly secure: boolean;
1757
+ readonly sameSite?: "Strict" | "Lax" | "None";
1758
+ }
1759
+
1760
+ export type BrowserResourceMethod = "GET" | "HEAD" | "POST";
1272
1761
 
1273
1762
  export type BrowserResourceRequest = {
1274
1763
  readonly url: string;
@@ -1280,16 +1769,19 @@ export type BrowserResourceRequest = {
1280
1769
  export type BrowserResourceBody = Buffer | Uint8Array | ArrayBuffer | string;
1281
1770
 
1282
1771
  export type BrowserResourceDecision =
1772
+ | {
1773
+ readonly action: "continue";
1774
+ }
1283
1775
  | {
1284
1776
  readonly action: "fulfill";
1285
1777
  readonly status?: number;
1286
1778
  readonly headers?: Readonly<Record<string, string>>;
1287
1779
  readonly body?: BrowserResourceBody;
1288
- }
1780
+ }
1289
1781
  | {
1290
1782
  readonly action: "block";
1291
1783
  readonly reason?: string;
1292
- };
1784
+ };
1293
1785
 
1294
1786
  export type BrowserResourceRoute = {
1295
1787
  readonly match:
@@ -1304,13 +1796,30 @@ export type BrowserResourceRoute = {
1304
1796
  export type BrowserResourcePolicy = {
1305
1797
  readonly defaultAction?: "block";
1306
1798
  readonly allowedMethods?: readonly BrowserResourceMethod[];
1799
+ /**
1800
+ * Appends an enforcing CSP header to every renderable document response
1801
+ * while the policy is active. Existing CSP headers are retained, so this
1802
+ * can only further restrict the document.
1803
+ */
1804
+ readonly documentContentSecurityPolicy?: string;
1307
1805
  readonly routes: readonly BrowserResourceRoute[];
1308
1806
  };
1309
1807
 
1310
1808
  export interface BrowserPage extends BrowserFrame {
1311
1809
  close(): Promise<void>;
1810
+ /** Returns the user agent used by this page's browser context. */
1811
+ userAgent(): Promise<string>;
1812
+ /**
1813
+ * Reads the browser context's cookie jar, including httpOnly cookies.
1814
+ * Cookie expiry values are Unix seconds and are absent for session cookies.
1815
+ */
1816
+ cookies(): Promise<readonly BrowserCookie[]>;
1312
1817
  fill(selector: string, text: string): Promise<void>;
1313
1818
  goto(url: string): Promise<void>;
1819
+ goto(
1820
+ url: string,
1821
+ options?: { readonly timeout?: number; readonly waitUntil?: "load" | "domcontentloaded" },
1822
+ ): Promise<void>;
1314
1823
  pageId?: string;
1315
1824
  screenshot(options?: { fullPage?: boolean }): Promise<Buffer>;
1316
1825
  click(selector: string): Promise<void>;
@@ -1398,10 +1907,32 @@ export interface ProviderChoiceBindingOptions {
1398
1907
  credentialKeys?: readonly string[];
1399
1908
  }
1400
1909
 
1910
+ export type ProviderChoiceConsumeMode = "never" | "on-parse" | "explicit";
1911
+
1912
+ export type ProviderChoiceConsumeResult =
1913
+ | { readonly status: "consumed" }
1914
+ | { readonly status: "already-consumed" }
1915
+ | { readonly status: "unsupported" };
1916
+
1917
+ export type ProviderChoiceExplicitParseResult =
1918
+ | {
1919
+ readonly status: "active";
1920
+ readonly payload: Record<string, unknown>;
1921
+ /** Stable, opaque key for provider-owned idempotency records. */
1922
+ readonly replayKey: string;
1923
+ /** Atomically claims a word token. Inline tokens report unsupported. */
1924
+ consume(): Promise<ProviderChoiceConsumeResult>;
1925
+ }
1926
+ | {
1927
+ readonly status: "consumed";
1928
+ /** Use this key to read the provider-owned result before returning an error. */
1929
+ readonly replayKey: string;
1930
+ };
1931
+
1401
1932
  export type ProviderChoiceStorageOptions =
1402
1933
  | {
1403
1934
  readonly mode: "inline";
1404
- }
1935
+ }
1405
1936
  | {
1406
1937
  readonly mode: "server";
1407
1938
  readonly namespace: string;
@@ -1410,7 +1941,7 @@ export type ProviderChoiceStorageOptions =
1410
1941
  readonly maxEntries: number;
1411
1942
  readonly maxValueBytes: number;
1412
1943
  readonly unavailable?: "reject";
1413
- }
1944
+ }
1414
1945
  | {
1415
1946
  readonly mode: "auto";
1416
1947
  readonly namespace: string;
@@ -1420,7 +1951,7 @@ export type ProviderChoiceStorageOptions =
1420
1951
  readonly maxEntries: number;
1421
1952
  readonly maxValueBytes: number;
1422
1953
  readonly unavailable?: "reject";
1423
- };
1954
+ };
1424
1955
 
1425
1956
  export interface ProviderChoiceIssueOptions<
1426
1957
  TPayload extends Record<string, unknown>,
@@ -1431,6 +1962,8 @@ export interface ProviderChoiceIssueOptions<
1431
1962
  ttlMs: number;
1432
1963
  nowMs?: number;
1433
1964
  bind?: ProviderChoiceBindingOptions;
1965
+ /** Server storage only: standard emits four words; high emits five. */
1966
+ strength?: "standard" | "high";
1434
1967
  storage?: ProviderChoiceStorageOptions;
1435
1968
  }
1436
1969
 
@@ -1443,6 +1976,8 @@ export interface ProviderChoiceParseOptions {
1443
1976
  futureToleranceMs?: number;
1444
1977
  bind?: ProviderChoiceBindingOptions;
1445
1978
  storage?: ProviderChoiceStorageOptions;
1979
+ /** Defaults to never, preserving reusable choice-token parse semantics. */
1980
+ consume?: ProviderChoiceConsumeMode;
1446
1981
  }
1447
1982
 
1448
1983
  export interface ProviderChoiceContext {
@@ -1470,6 +2005,9 @@ export interface ProviderChoiceContext {
1470
2005
  issue<TPayload extends Record<string, unknown>>(
1471
2006
  options: ProviderChoiceIssueOptions<TPayload>,
1472
2007
  ): string | Promise<string>;
2008
+ parse(
2009
+ options: ProviderChoiceParseOptions & { readonly consume: "explicit" },
2010
+ ): Promise<ProviderChoiceExplicitParseResult>;
1473
2011
  parse(
1474
2012
  options: ProviderChoiceParseOptions & {
1475
2013
  readonly storage?: { readonly mode: "inline" };
@@ -1491,7 +2029,11 @@ export interface ProviderChoiceContext {
1491
2029
  >;
1492
2030
  },
1493
2031
  ): Record<string, unknown> | Promise<Record<string, unknown>>;
1494
- parse(options: ProviderChoiceParseOptions): Record<string, unknown>;
2032
+ parse(
2033
+ options: ProviderChoiceParseOptions,
2034
+ ):
2035
+ | Record<string, unknown>
2036
+ | Promise<Record<string, unknown> | ProviderChoiceExplicitParseResult>;
1495
2037
  }
1496
2038
 
1497
2039
  export interface ContextScratchpad {
@@ -1564,11 +2106,11 @@ export interface AuthFlowTerminalContext {
1564
2106
  }
1565
2107
  >;
1566
2108
  readonly expectedInput?: never;
1567
- }
2109
+ }
1568
2110
  | {
1569
2111
  readonly expectedInput: Record<string, unknown>;
1570
2112
  readonly fields?: never;
1571
- }
2113
+ }
1572
2114
  ),
1573
2115
  ): AuthTurn;
1574
2116
  nextPoll(options?: {
@@ -1581,16 +2123,34 @@ export interface AuthFlowTerminalContext {
1581
2123
  }
1582
2124
 
1583
2125
  export interface FlowContext {
2126
+ /** Gateway auth-flow id. Required by flow-scoped auth ceremonies. */
2127
+ flowId?: string;
1584
2128
  connectionId?: string;
1585
2129
  externalRef?: string;
1586
2130
  tenantId: string;
1587
2131
  providerId: string;
1588
2132
  http: HttpClient;
2133
+ /** Durable connection-scoped runtime state. Present when the host runtime
2134
+ * supplies one; auth ceremonies must fail closed when absent rather than
2135
+ * fall back to bypassable in-process storage.
2136
+ *
2137
+ * Scoped via `ProviderRuntimeState.forConnection`: requests that resolve no
2138
+ * connection id (pre-connection ceremonies such as first-time logins) share
2139
+ * the documented isolated missing-connection scope. That sharing is the
2140
+ * intended semantic — it lets counters keyed by caller identity (e.g. a
2141
+ * login email) persist across separate ceremonies for the same caller.
2142
+ * Flows storing entries in that scope MUST key them by caller identity;
2143
+ * un-keyed entries would be shared across all connectionless ceremonies. */
2144
+ readonly state?: ProviderRuntimeState;
2145
+ /** Present when the selected runtime supplies native network capabilities. */
2146
+ readonly native?: NativeContext;
1589
2147
  stealth: StealthClient;
1590
2148
  env: EnvContext;
1591
2149
  credential?: CredentialContext;
1592
2150
  context: ContextScratchpad;
2151
+ ocr: OcrContext;
1593
2152
  stt: SttContext;
2153
+ resolver: ResolverContext;
1594
2154
  auth: AuthFlowTerminalContext;
1595
2155
  }
1596
2156
 
@@ -1633,7 +2193,14 @@ export type ProviderStateDurationString =
1633
2193
  | `${number}${"ms" | "s" | "m" | "h" | "d"}`
1634
2194
  | `PT${string}`;
1635
2195
 
2196
+ export type StateNamespaceScope = "connection" | "provider";
2197
+
1636
2198
  export interface StateNamespaceOptions {
2199
+ /**
2200
+ * State isolation boundary. Connection scope is the default; provider scope
2201
+ * must be selected explicitly for provider-wide coordination state.
2202
+ */
2203
+ scope?: StateNamespaceScope;
1637
2204
  /** Default TTL used when a write omits ttl. Required to avoid unbounded state. */
1638
2205
  defaultTtl: ProviderStateDurationString;
1639
2206
  /** Maximum allowed TTL; writes are rejected when they exceed this policy. */
@@ -1694,6 +2261,11 @@ export interface ProviderStateNamespace {
1694
2261
  }
1695
2262
 
1696
2263
  export interface ProviderRuntimeState {
2264
+ /**
2265
+ * Returns an immutable view bound to one request connection. An unresolved
2266
+ * connection uses an isolated reserved sentinel, never the provider-global scope.
2267
+ */
2268
+ forConnection(connectionId: string | undefined): ProviderRuntimeState;
1697
2269
  namespace(
1698
2270
  name: string,
1699
2271
  options: StateNamespaceOptions,
@@ -1705,18 +2277,59 @@ export interface ProviderContext {
1705
2277
  credential: CredentialContext;
1706
2278
  request?: ProviderRequestContext;
1707
2279
  http: HttpClient;
2280
+ /** Present for requests carrying runtime-resolvable file references. */
2281
+ readonly files?: ProviderFilesContext;
2282
+ /** Native network capability selected by declaration-derived contexts. */
2283
+ readonly native: NativeContext;
1708
2284
  cache: ProviderCache;
1709
2285
  state: ProviderRuntimeState;
1710
2286
  stealth: StealthClient;
1711
2287
  browser: BrowserClient;
1712
2288
  trace: TraceContext;
1713
2289
  auth: AuthContext;
2290
+ ocr: OcrContext;
1714
2291
  stt: SttContext;
2292
+ resolver: ResolverContext;
1715
2293
  choice: ProviderChoiceContext;
1716
2294
  }
1717
2295
 
2296
+ /**
2297
+ * The operation context exposed for one provider declaration. Capability
2298
+ * bindings are present only when their corresponding declaration is present;
2299
+ * trace and request remain ambient runtime bindings.
2300
+ */
2301
+ export type ProviderContextFor<TConfig> =
2302
+ Pick<ProviderContext, "trace" | "request">
2303
+ & ("env" extends keyof TConfig ? Pick<ProviderContext, "env"> : Record<never, never>)
2304
+ & ("credential" extends keyof TConfig ? Pick<ProviderContext, "credential"> : Record<never, never>)
2305
+ & ("http" extends keyof TConfig ? Pick<ProviderContext, "http"> : Record<never, never>)
2306
+ & ("files" extends keyof TConfig ? Pick<ProviderContext, "files"> : Record<never, never>)
2307
+ & ("native" extends keyof TConfig ? Pick<ProviderContext, "native"> : Record<never, never>)
2308
+ & ("cache" extends keyof TConfig ? Pick<ProviderContext, "cache"> : Record<never, never>)
2309
+ & ("state" extends keyof TConfig ? Pick<ProviderContext, "state"> : Record<never, never>)
2310
+ & ("stealth" extends keyof TConfig ? Pick<ProviderContext, "stealth"> : Record<never, never>)
2311
+ & ("browser" extends keyof TConfig ? Pick<ProviderContext, "browser"> : Record<never, never>)
2312
+ & ("auth" extends keyof TConfig ? Pick<ProviderContext, "auth"> : Record<never, never>)
2313
+ & ("ocr" extends keyof TConfig ? Pick<ProviderContext, "ocr"> : Record<never, never>)
2314
+ & ("stt" extends keyof TConfig ? Pick<ProviderContext, "stt"> : Record<never, never>)
2315
+ & ("resolver" extends keyof TConfig ? Pick<ProviderContext, "resolver"> : Record<never, never>)
2316
+ & ("choice" extends keyof TConfig ? Pick<ProviderContext, "choice"> : Record<never, never>);
2317
+
2318
+ export interface ProxiedOAuthConfig {
2319
+ authorizeUrl: string;
2320
+ tokenUrl: string;
2321
+ customScheme: string;
2322
+ rewriteProfile: string;
2323
+ clientIdEnvKey: string;
2324
+ pkce?: "S256" | "none";
2325
+ authorizeParams?: Record<string, string>;
2326
+ tokenParams?: Record<string, string>;
2327
+ }
2328
+
1718
2329
  export interface AuthConfig {
1719
2330
  mode: AuthMode;
2331
+ /** Browser reverse-proxy contract for providers with custom-scheme OAuth callbacks. */
2332
+ proxied?: ProxiedOAuthConfig;
1720
2333
  flow?: AuthFlowDefinition;
1721
2334
  }
1722
2335
 
@@ -1758,6 +2371,7 @@ export interface OperationContractMetadata {
1758
2371
  export interface OperationDefinition<
1759
2372
  TInput extends SchemaLike = SchemaLike,
1760
2373
  TOutput extends SchemaLike = SchemaLike,
2374
+ TContext = ProviderContext,
1761
2375
  > {
1762
2376
  /**
1763
2377
  * Short English display title for the operation. The SDK passes it through
@@ -1789,7 +2403,7 @@ export interface OperationDefinition<
1789
2403
  input: TInput;
1790
2404
  output: TOutput;
1791
2405
  handler(
1792
- ctx: ProviderContext,
2406
+ ctx: TContext,
1793
2407
  input: InferSchemaOutput<TInput>,
1794
2408
  ):
1795
2409
  | OperationHandlerResult<InferSchemaOutput<TOutput>>
@@ -1797,6 +2411,11 @@ export interface OperationDefinition<
1797
2411
  fixtures?: {
1798
2412
  request: InferSchemaOutput<TInput>;
1799
2413
  response: InferSchemaOutput<TOutput>;
2414
+ /**
2415
+ * KST calendar date when `response` evidence was captured. Date fields in
2416
+ * the response align with this date, not a resolved relative request date.
2417
+ */
2418
+ recordedAt?: string;
1800
2419
  };
1801
2420
  upstream?: {
1802
2421
  baseUrl?: string;
@@ -1860,12 +2479,15 @@ export interface ProviderDefinition {
1860
2479
  */
1861
2480
  deployment?: ProviderDeploymentOverrides;
1862
2481
  allowedHosts?: string[];
2482
+ native?: NativeProviderConfig;
1863
2483
  stealth?: {
1864
2484
  profile: string;
1865
2485
  platform: StealthPlatform;
1866
2486
  };
1867
2487
  proxy?: ProviderProxyConfig;
2488
+ ocr?: ProviderOcrConfig;
1868
2489
  stt?: ProviderSttConfig;
2490
+ resolver?: ProviderResolverConfig;
1869
2491
  browser?: {
1870
2492
  engine: BrowserEngine;
1871
2493
  };