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

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 (315) hide show
  1. package/AUTHORING.md +501 -13
  2. package/CHANGELOG.md +169 -1
  3. package/README.md +72 -14
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +150 -5
  6. package/bin/apifuse-dev.ts +38 -5
  7. package/bin/apifuse-migrate-shape.ts +84 -0
  8. package/bin/apifuse-pack-check.ts +22 -2
  9. package/bin/apifuse-pack-smoke.ts +57 -2
  10. package/bin/apifuse-pack-types.ts +356 -38
  11. package/bin/apifuse-perf.ts +14 -13
  12. package/bin/apifuse-record.ts +691 -68
  13. package/bin/apifuse-submit-check.ts +2301 -282
  14. package/bin/apifuse-sync-assets.ts +117 -0
  15. package/bin/submit-check-delimited-text.ts +50 -0
  16. package/dist/auth-turn/index.d.ts +3 -3
  17. package/dist/auth-turn/index.js +1 -1
  18. package/dist/auth.d.ts +14 -0
  19. package/dist/auth.js +67 -0
  20. package/dist/ceremonies/index.d.ts +16 -0
  21. package/dist/ceremonies/index.js +141 -36
  22. package/dist/cli/commands.d.ts +1 -1
  23. package/dist/cli/commands.js +16 -0
  24. package/dist/cli/create.d.ts +3 -0
  25. package/dist/cli/create.js +40 -35
  26. package/dist/cli/migrate-provider-shape.d.ts +52 -0
  27. package/dist/cli/migrate-provider-shape.js +515 -0
  28. package/dist/cli/prompt-assets.d.ts +80 -0
  29. package/dist/cli/prompt-assets.js +743 -0
  30. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  31. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  32. package/dist/cli/templates/provider/README.md.tpl +4 -4
  33. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  34. package/dist/cli/templates/provider/operations/ping.ts.tpl +2 -1
  35. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  36. package/dist/config/loader.d.ts +177 -16
  37. package/dist/config/loader.js +424 -127
  38. package/dist/contract-serialization.js +4 -8
  39. package/dist/contract-types.d.ts +1 -0
  40. package/dist/contract.js +3 -0
  41. package/dist/declaration-validation.d.ts +32 -0
  42. package/dist/declaration-validation.js +207 -0
  43. package/dist/define.d.ts +51 -25
  44. package/dist/define.js +774 -39
  45. package/dist/error-observability.d.ts +7 -0
  46. package/dist/error-observability.js +61 -0
  47. package/dist/error-resolution.d.ts +4 -0
  48. package/dist/error-resolution.js +122 -0
  49. package/dist/errors.d.ts +33 -0
  50. package/dist/errors.js +40 -0
  51. package/dist/fixture-sanitization.d.ts +28 -0
  52. package/dist/fixture-sanitization.js +227 -0
  53. package/dist/health-scenario.d.ts +1842 -0
  54. package/dist/health-scenario.js +624 -0
  55. package/dist/index.d.ts +19 -9
  56. package/dist/index.js +10 -6
  57. package/dist/lint.d.ts +6 -1
  58. package/dist/lint.js +362 -3
  59. package/dist/native-address.d.ts +43 -0
  60. package/dist/native-address.js +281 -0
  61. package/dist/native-egress-policy.d.ts +31 -0
  62. package/dist/native-egress-policy.js +288 -0
  63. package/dist/observability.d.ts +5 -2
  64. package/dist/observability.js +48 -1
  65. package/dist/provider.d.ts +8 -2
  66. package/dist/provider.js +3 -1
  67. package/dist/runtime/auth-flow.d.ts +5 -1
  68. package/dist/runtime/auth-flow.js +6 -0
  69. package/dist/runtime/browser.d.ts +1 -0
  70. package/dist/runtime/browser.js +492 -49
  71. package/dist/runtime/cache.d.ts +1 -0
  72. package/dist/runtime/cache.js +169 -15
  73. package/dist/runtime/choice-wordlist.d.ts +9 -0
  74. package/dist/runtime/choice-wordlist.js +138 -0
  75. package/dist/runtime/choice.d.ts +13 -1
  76. package/dist/runtime/choice.js +490 -102
  77. package/dist/runtime/executor.d.ts +2 -2
  78. package/dist/runtime/executor.js +37 -3
  79. package/dist/runtime/http.d.ts +1 -0
  80. package/dist/runtime/http.js +515 -53
  81. package/dist/runtime/instrumentation.d.ts +2 -2
  82. package/dist/runtime/instrumentation.js +366 -8
  83. package/dist/runtime/native-network-errors.d.ts +33 -0
  84. package/dist/runtime/native-network-errors.js +69 -0
  85. package/dist/runtime/native-network.d.ts +96 -0
  86. package/dist/runtime/native-network.js +1232 -0
  87. package/dist/runtime/ocr.d.ts +29 -0
  88. package/dist/runtime/ocr.js +440 -0
  89. package/dist/runtime/proxy-errors.js +6 -2
  90. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  91. package/dist/runtime/proxy-nodemaven.js +146 -0
  92. package/dist/runtime/proxy-telemetry.d.ts +80 -1
  93. package/dist/runtime/proxy-telemetry.js +154 -47
  94. package/dist/runtime/redirects.d.ts +29 -0
  95. package/dist/runtime/redirects.js +36 -0
  96. package/dist/runtime/redis.d.ts +1 -1
  97. package/dist/runtime/redis.js +4 -2
  98. package/dist/runtime/request-options.d.ts +68 -1
  99. package/dist/runtime/request-options.js +548 -0
  100. package/dist/runtime/resolver-config.d.ts +6 -0
  101. package/dist/runtime/resolver-config.js +6 -0
  102. package/dist/runtime/resolver-public.d.ts +1 -0
  103. package/dist/runtime/resolver-public.js +1 -0
  104. package/dist/runtime/resolver-shared.d.ts +3 -0
  105. package/dist/runtime/resolver-shared.js +12 -0
  106. package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
  107. package/dist/runtime/resolver-vendors/bindings.js +40 -0
  108. package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
  109. package/dist/runtime/resolver-vendors/browser.js +377 -0
  110. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  111. package/dist/runtime/resolver-vendors/capsolver.js +526 -0
  112. package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
  113. package/dist/runtime/resolver-vendors/hosts.js +33 -0
  114. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  115. package/dist/runtime/resolver-vendors/twocaptcha.js +407 -0
  116. package/dist/runtime/resolver-vendors/types.d.ts +94 -0
  117. package/dist/runtime/resolver-vendors/types.js +96 -0
  118. package/dist/runtime/resolver.d.ts +60 -0
  119. package/dist/runtime/resolver.js +737 -0
  120. package/dist/runtime/secrets.d.ts +27 -0
  121. package/dist/runtime/secrets.js +51 -0
  122. package/dist/runtime/state.d.ts +3 -0
  123. package/dist/runtime/state.js +277 -71
  124. package/dist/runtime/stealth-cookies.d.ts +20 -0
  125. package/dist/runtime/stealth-cookies.js +111 -0
  126. package/dist/runtime/stealth.d.ts +28 -3
  127. package/dist/runtime/stealth.js +519 -255
  128. package/dist/runtime/stt.js +1 -12
  129. package/dist/runtime/timeout.d.ts +5 -0
  130. package/dist/runtime/timeout.js +12 -0
  131. package/dist/runtime/trace-config.d.ts +12 -0
  132. package/dist/runtime/trace-config.js +61 -0
  133. package/dist/serve.d.ts +1 -1
  134. package/dist/serve.js +1 -1
  135. package/dist/server/error-observability.d.ts +1 -0
  136. package/dist/server/error-observability.js +1 -0
  137. package/dist/server/index.d.ts +6 -3
  138. package/dist/server/index.js +3 -3
  139. package/dist/server/self-test-input-tokens.d.ts +2 -1
  140. package/dist/server/self-test-input-tokens.js +18 -14
  141. package/dist/server/self-test.d.ts +114 -0
  142. package/dist/server/self-test.js +787 -148
  143. package/dist/server/serve-implementation.d.ts +225 -0
  144. package/dist/server/serve-implementation.js +2242 -0
  145. package/dist/server/serve.d.ts +1 -70
  146. package/dist/server/serve.js +1 -1130
  147. package/dist/server/trace-output.d.ts +4 -0
  148. package/dist/server/trace-output.js +20 -0
  149. package/dist/server/types.d.ts +30 -5
  150. package/dist/server/types.js +13 -1
  151. package/dist/stateful/errors.d.ts +19 -0
  152. package/dist/stateful/errors.js +24 -0
  153. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  154. package/dist/stateful/http-provider-event-emitter.js +237 -0
  155. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  156. package/dist/stateful/http-session-owner-registry.js +210 -0
  157. package/dist/stateful/index.d.ts +18 -0
  158. package/dist/stateful/index.js +18 -0
  159. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  160. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  161. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  162. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  163. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  164. package/dist/stateful/provider-event-pipeline.js +1 -0
  165. package/dist/stateful/provider-events.d.ts +101 -0
  166. package/dist/stateful/provider-events.js +289 -0
  167. package/dist/stateful/session-key.d.ts +15 -0
  168. package/dist/stateful/session-key.js +86 -0
  169. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  170. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  171. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  172. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  173. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  174. package/dist/stateful/stateful-provider-adapter.js +287 -0
  175. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  176. package/dist/stateful/stateful-provider-observability.js +161 -0
  177. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  178. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  179. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  180. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  181. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  182. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  183. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  184. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  185. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  186. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  187. package/dist/stateful-signing.d.ts +18 -0
  188. package/dist/stateful-signing.js +27 -0
  189. package/dist/stealth/profiles.js +16 -7
  190. package/dist/stream-evidence.d.ts +74 -0
  191. package/dist/stream-evidence.js +785 -0
  192. package/dist/stream.js +7 -1
  193. package/dist/testing/index.d.ts +2 -1
  194. package/dist/testing/index.js +2 -1
  195. package/dist/testing/run.d.ts +32 -2
  196. package/dist/testing/run.js +489 -21
  197. package/dist/trace-sanitization.d.ts +5 -0
  198. package/dist/trace-sanitization.js +45 -0
  199. package/dist/types.d.ts +563 -33
  200. package/dist/types.js +1 -0
  201. package/package.json +44 -5
  202. package/src/auth-turn/index.ts +1 -1
  203. package/src/auth.ts +118 -0
  204. package/src/ceremonies/index.ts +189 -46
  205. package/src/cli/commands.ts +20 -0
  206. package/src/cli/create.ts +48 -35
  207. package/src/cli/migrate-provider-shape.ts +701 -0
  208. package/src/cli/prompt-assets.ts +865 -0
  209. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  210. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  211. package/src/cli/templates/provider/README.md.tpl +4 -4
  212. package/src/cli/templates/provider/index.ts.tpl +6 -3
  213. package/src/cli/templates/provider/operations/ping.ts.tpl +2 -1
  214. package/src/cli/templates/provider/provider.json.tpl +6 -0
  215. package/src/config/loader.ts +665 -163
  216. package/src/contract-serialization.ts +5 -7
  217. package/src/contract-types.ts +1 -0
  218. package/src/contract.ts +3 -0
  219. package/src/declaration-validation.ts +266 -0
  220. package/src/define.ts +1003 -88
  221. package/src/error-observability.ts +64 -0
  222. package/src/error-resolution.ts +127 -0
  223. package/src/errors.ts +68 -0
  224. package/src/fixture-sanitization.ts +264 -0
  225. package/src/health-scenario.ts +875 -0
  226. package/src/index.ts +205 -8
  227. package/src/lint.ts +408 -4
  228. package/src/native-address.ts +340 -0
  229. package/src/native-egress-policy.ts +358 -0
  230. package/src/observability.ts +51 -1
  231. package/src/provider.ts +134 -0
  232. package/src/runtime/auth-flow.ts +12 -0
  233. package/src/runtime/browser.ts +661 -63
  234. package/src/runtime/cache.ts +189 -14
  235. package/src/runtime/choice-wordlist.ts +145 -0
  236. package/src/runtime/choice.ts +631 -120
  237. package/src/runtime/executor.ts +53 -8
  238. package/src/runtime/http.ts +641 -61
  239. package/src/runtime/instrumentation.ts +520 -15
  240. package/src/runtime/native-network-errors.ts +99 -0
  241. package/src/runtime/native-network.ts +1605 -0
  242. package/src/runtime/ocr.ts +523 -0
  243. package/src/runtime/proxy-errors.ts +12 -4
  244. package/src/runtime/proxy-nodemaven.ts +221 -0
  245. package/src/runtime/proxy-telemetry.ts +244 -75
  246. package/src/runtime/redirects.ts +66 -0
  247. package/src/runtime/redis.ts +7 -2
  248. package/src/runtime/request-options.ts +680 -1
  249. package/src/runtime/resolver-config.ts +6 -0
  250. package/src/runtime/resolver-public.ts +20 -0
  251. package/src/runtime/resolver-shared.ts +17 -0
  252. package/src/runtime/resolver-vendors/bindings.ts +56 -0
  253. package/src/runtime/resolver-vendors/browser.ts +533 -0
  254. package/src/runtime/resolver-vendors/capsolver.ts +700 -0
  255. package/src/runtime/resolver-vendors/hosts.ts +38 -0
  256. package/src/runtime/resolver-vendors/twocaptcha.ts +539 -0
  257. package/src/runtime/resolver-vendors/types.ts +212 -0
  258. package/src/runtime/resolver.ts +1103 -0
  259. package/src/runtime/secrets.ts +64 -0
  260. package/src/runtime/state.ts +394 -77
  261. package/src/runtime/stealth-cookies.ts +132 -0
  262. package/src/runtime/stealth.ts +675 -289
  263. package/src/runtime/stt.ts +1 -19
  264. package/src/runtime/timeout.ts +18 -0
  265. package/src/runtime/trace-config.ts +77 -0
  266. package/src/serve.ts +6 -1
  267. package/src/server/error-observability.ts +1 -0
  268. package/src/server/index.ts +39 -2
  269. package/src/server/self-test-input-tokens.ts +29 -14
  270. package/src/server/self-test.ts +1030 -175
  271. package/src/server/serve-implementation.ts +3338 -0
  272. package/src/server/serve.ts +1 -1626
  273. package/src/server/trace-output.ts +32 -0
  274. package/src/server/types.ts +13 -1
  275. package/src/stateful/README.md +146 -0
  276. package/src/stateful/errors.ts +35 -0
  277. package/src/stateful/http-provider-event-emitter.ts +314 -0
  278. package/src/stateful/http-session-owner-registry.ts +306 -0
  279. package/src/stateful/index.ts +18 -0
  280. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  281. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  282. package/src/stateful/provider-event-pipeline.ts +61 -0
  283. package/src/stateful/provider-events.ts +462 -0
  284. package/src/stateful/session-key.ts +111 -0
  285. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  286. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  287. package/src/stateful/stateful-provider-adapter.ts +562 -0
  288. package/src/stateful/stateful-provider-observability.ts +261 -0
  289. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  290. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  291. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  292. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  293. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  294. package/src/stateful-signing.ts +46 -0
  295. package/src/stealth/profiles.ts +17 -7
  296. package/src/stream-evidence.ts +988 -0
  297. package/src/stream.ts +8 -1
  298. package/src/testing/index.ts +10 -1
  299. package/src/testing/run.ts +658 -15
  300. package/src/trace-sanitization.ts +63 -0
  301. package/src/types.ts +698 -65
  302. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  303. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  304. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  305. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  306. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  307. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  308. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  309. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  310. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  311. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  312. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  313. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  314. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  315. /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
  *
@@ -574,38 +760,13 @@ export interface HealthCheckCaseResult {
574
760
  * so authors get IntelliSense and compile-time errors when accessing fields
575
761
  * that do not exist on the operation's declared output schema.
576
762
  */
577
- export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
763
+ export type HealthCheckCase<TInput = unknown, TOutput = unknown> = {
578
764
  /** Human-readable case name; unique within the suite. */
579
765
  name: string;
580
766
  /** Optional longer description shown on ops dashboards. */
581
767
  description?: string;
582
768
  /** Input passed to the operation handler for this case. */
583
769
  input: TInput;
584
- /**
585
- * Optional runtime input preparation hook for volatile probes. Use this when
586
- * the durable probe input must be derived from a live read-only operation
587
- * immediately before the checked operation executes.
588
- */
589
- prepareInput?: (
590
- ctx: HealthCheckInputPreparationContext<TInput>,
591
- ) => TInput | Promise<TInput>;
592
- /**
593
- * Assertion executed against the operation's response and timing.
594
- *
595
- * - Throw to fail the case (recorded as `down`).
596
- * - Return `{ status: "degraded", label }` to flag without failing.
597
- * - Return `void` (implicit) for `ok`.
598
- *
599
- * MUST NOT access scheduler, recorder, or any runtime type — pure data
600
- * + lambda only.
601
- */
602
- assertions: (
603
- ctx: HealthCheckAssertionContext<TOutput>,
604
- ) =>
605
- | void
606
- | Promise<void>
607
- | HealthCheckCaseResult
608
- | Promise<HealthCheckCaseResult>;
609
770
  /** Override per-case degradation threshold (ms); falls back to the suite default. */
610
771
  degradedThresholdMs?: number;
611
772
  /** Override per-case timeout in milliseconds; falls back to the suite/provider/runtime default. */
@@ -614,7 +775,43 @@ export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
614
775
  expectedStatus?: "ok" | "degraded";
615
776
  /** Runtime gate (env-driven); if returns false the case is skipped & logged. */
616
777
  enabled?: () => boolean;
617
- }
778
+ } & (
779
+ | {
780
+ /**
781
+ * Optional runtime input preparation hook for volatile probes. Use this when
782
+ * the durable probe input must be derived from a live read-only operation
783
+ * immediately before the checked operation executes.
784
+ */
785
+ prepareInput?: (
786
+ ctx: HealthCheckInputPreparationContext<TInput>,
787
+ ) => TInput | Promise<TInput>;
788
+ /**
789
+ * Assertion executed against the operation's response and timing.
790
+ *
791
+ * - Throw to fail the case (recorded as `down`).
792
+ * - Return `{ status: "degraded", label }` to flag without failing.
793
+ * - Return `void` (implicit) for `ok`.
794
+ *
795
+ * MUST NOT access scheduler, recorder, or any runtime type — pure data
796
+ * + lambda only.
797
+ */
798
+ assertions: (
799
+ ctx: HealthCheckAssertionContext<TOutput>,
800
+ ) =>
801
+ | void
802
+ | Promise<void>
803
+ | HealthCheckCaseResult
804
+ | Promise<HealthCheckCaseResult>;
805
+ /** Declarative scenarios replace the imperative preparation and assertion hooks. */
806
+ scenario?: never;
807
+ }
808
+ | {
809
+ /** Declarative scenario executed by the health-monitor runtime. */
810
+ scenario: HealthScenario;
811
+ prepareInput?: never;
812
+ assertions?: never;
813
+ }
814
+ );
618
815
 
619
816
  /**
620
817
  * Operation-level health-check suite. At least one case is required when
@@ -718,9 +915,13 @@ export interface HealthMonitorProbeOverride {
718
915
  degradedThresholdMs?: number;
719
916
  }
720
917
 
918
+ export const VALID_OPERATION_ERROR_STATUSES = [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504] as const;
919
+
920
+ export type ProviderErrorStatus = (typeof VALID_OPERATION_ERROR_STATUSES)[number];
921
+
721
922
  export interface OperationErrorCode {
722
923
  code: string;
723
- status?: number;
924
+ status?: ProviderErrorStatus;
724
925
  description: string;
725
926
  retryable?: boolean;
726
927
  }
@@ -759,7 +960,12 @@ export interface StealthProfile {
759
960
  headerOrder?: string[];
760
961
  }
761
962
 
762
- export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2";
963
+ export type AuthMode =
964
+ | "none"
965
+ | "platform-managed"
966
+ | "credentials"
967
+ | "oauth2"
968
+ | "oauth2_proxied";
763
969
 
764
970
  export type ConnectionMode = AuthMode;
765
971
 
@@ -769,7 +975,27 @@ export type ProviderAccessVisibility = "public" | "early_access";
769
975
 
770
976
  export type ProviderProxyMode = "disabled" | "optional" | "required";
771
977
 
772
- export type ProviderProxyProvider = "smartproxy" | "decodo" | "custom";
978
+ /**
979
+ * Proxy egress vendors. These are FOUR DISTINCT services — do not conflate them
980
+ * (a common mistake because the names collide with a well-known rebrand):
981
+ *
982
+ * - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
983
+ * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
984
+ * endpoints). This is our own vendor. It is NOT the company formerly named
985
+ * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
986
+ * - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
987
+ * credentials; geo/session encoded in the username, no allocation API.
988
+ * - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
989
+ * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
990
+ * username params. A different company from `smartproxy` above.
991
+ * **@deprecated** — unused; no managed adapter. Declare a
992
+ * `ProviderProxyPolicy` using `smartproxy` or `nodemaven` instead; the
993
+ * `smartproxy` allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
994
+ * - `custom` — **@deprecated** static proxy marker with no managed adapter.
995
+ * Use `ProviderProxyPolicy` with `smartproxy`/`nodemaven`; the `smartproxy`
996
+ * allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
997
+ */
998
+ export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
773
999
 
774
1000
  export type ProviderProxySessionAffinity =
775
1001
  | "request"
@@ -783,7 +1009,18 @@ export interface ProviderProxyPolicy {
783
1009
  * certificate verification, and vendor allocator endpoints are SDK-owned.
784
1010
  */
785
1011
  mode: ProviderProxyMode;
1012
+ /**
1013
+ * @deprecated Use `providers: [...]` to declare an ordered vendor fallback
1014
+ * chain. A single-element `providers` list is equivalent to this field.
1015
+ */
786
1016
  provider?: ProviderProxyProvider;
1017
+ /**
1018
+ * Ordered proxy-vendor fallback chain. The SDK tries each vendor in order and
1019
+ * fails over to the next when a vendor lacks credentials or its allocation /
1020
+ * transport is exhausted. When omitted, `provider` (or the platform default)
1021
+ * is used as a single-vendor chain.
1022
+ */
1023
+ providers?: ProviderProxyProvider[];
787
1024
  geo?: {
788
1025
  /** ISO 3166-1 alpha-2 country code, for example KR or US. */
789
1026
  country?: Iso3166Alpha2CountryCode;
@@ -794,6 +1031,12 @@ export interface ProviderProxyPolicy {
794
1031
  affinity?: ProviderProxySessionAffinity;
795
1032
  lifetimeMinutes?: number;
796
1033
  poolSize?: number;
1034
+ /**
1035
+ * Seconds before hard sticky expiry at which native connections receive
1036
+ * the `expiring` event so the provider can drain and reconnect cleanly.
1037
+ * Declared by the provider; the SDK does not assume a default cut point.
1038
+ */
1039
+ drainLeadSeconds?: number;
797
1040
  };
798
1041
  }
799
1042
 
@@ -804,9 +1047,9 @@ export interface ProviderAccessConfig {
804
1047
  * Provider-level rollout visibility.
805
1048
  *
806
1049
  * - `public`: visible in public docs/catalog/OpenAPI and callable through
807
- * the existing provider policy stack.
1050
+ * the existing provider policy stack.
808
1051
  * - `early_access`: hidden from public discovery and callable only when the
809
- * active customer organization has a provider-level access grant.
1052
+ * active customer organization has a provider-level access grant.
810
1053
  *
811
1054
  * This is intentionally provider-level only. It does not alter auth mode,
812
1055
  * operation schemas, health-check authoring, `openWorld`, or Connection
@@ -828,12 +1071,12 @@ export type ProviderLogoProfile =
828
1071
  */
829
1072
  url?: string;
830
1073
  background?: string;
831
- }
1074
+ }
832
1075
  | {
833
1076
  source: "monogram" | "none";
834
1077
  background?: string;
835
1078
  fallbackReason: string;
836
- };
1079
+ };
837
1080
 
838
1081
  export type ProviderPublicConnectionMode =
839
1082
  | "apifuse_managed"
@@ -970,6 +1213,11 @@ export interface HttpRetrySummary {
970
1213
  export interface RequestOptions {
971
1214
  headers?: Record<string, string>;
972
1215
  params?: RequestParams;
1216
+ /**
1217
+ * Query parameters whose values contain credentials or other secret material.
1218
+ * They are sent like `params`, but redacted from SDK errors, traces, and recorded fixtures.
1219
+ */
1220
+ sensitiveParams?: Record<string, string>;
973
1221
  proxy?: string;
974
1222
  timeout?: number;
975
1223
  /**
@@ -978,8 +1226,32 @@ export interface RequestOptions {
978
1226
  */
979
1227
  throwOnHttpError?: boolean;
980
1228
  retry?: boolean | HttpRetryPreset | HttpRetryOptions;
1229
+ /**
1230
+ * Opt-in redirect-hop enforcement for ctx.http. When present, redirects are
1231
+ * evaluated before the next request is issued. Existing callers that omit
1232
+ * this policy retain the native fetch redirect behavior.
1233
+ */
1234
+ redirectPolicy?: HttpRedirectPolicy;
981
1235
  }
982
1236
 
1237
+ export type RedirectRunReason =
1238
+ | "completed"
1239
+ | "stopped"
1240
+ | "max_hops"
1241
+ | "missing_location"
1242
+ | "loop";
1243
+
1244
+ export type HttpRedirectPolicyMode = "same-origin";
1245
+
1246
+ export interface HttpRedirectPolicy {
1247
+ /** Only follow redirects whose canonical scheme, host, and port match the initial URL. */
1248
+ mode: HttpRedirectPolicyMode;
1249
+ /** Maximum number of redirect hops that may be followed. Must be an integer from 0 to 20. */
1250
+ maxHops: number;
1251
+ }
1252
+
1253
+ export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
1254
+
983
1255
  export type HttpMethod =
984
1256
  | "HEAD"
985
1257
  | "head"
@@ -998,10 +1270,16 @@ export type HttpMethod =
998
1270
  | "PATCH"
999
1271
  | "patch";
1000
1272
 
1001
- export interface StealthFetchOptions extends RequestOptions {
1273
+ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy"> {
1002
1274
  method?: HttpMethod;
1003
1275
  body?: string | Buffer;
1004
1276
  redirect?: "follow" | "manual" | "error";
1277
+ /**
1278
+ * Maximum decoded response-body bytes to buffer. When set, the stealth
1279
+ * transport aborts the response and throws `response_too_large` if the
1280
+ * declared or streamed body exceeds this limit.
1281
+ */
1282
+ maxBodyBytes?: number;
1005
1283
  /**
1006
1284
  * Offsets policy-managed proxy pool selection for caller-managed retries.
1007
1285
  * Use when a request receives an upstream challenge page rather than a
@@ -1022,18 +1300,45 @@ export interface StealthFetchOptions extends RequestOptions {
1022
1300
  }
1023
1301
 
1024
1302
  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;
1303
+ /** URL-less reads use the jar's response URL or session base URL. */
1304
+ get(name: string, url?: string): string | undefined;
1305
+ getAll(url?: string): Record<string, string>;
1306
+ toString(url?: string): string;
1307
+ find?(predicate: (cookie: string) => boolean, url?: string): string | undefined;
1308
+ }
1309
+
1310
+ /**
1311
+ * Version 1 of the JSON-safe, attribute-preserving stealth cookie store.
1312
+ * The nested jar is tough-cookie's serialized form and retains cookie origin,
1313
+ * Path, Secure, expiry, host-only, and other RFC attributes.
1314
+ */
1315
+ export interface StealthCookieStoreV1 {
1316
+ readonly version: 1;
1317
+ readonly jar: SerializedCookieJar;
1029
1318
  }
1030
1319
 
1320
+ /** Cookie persistence formats understood by this SDK version. */
1321
+ export type StealthCookieStore = StealthCookieStoreV1;
1322
+
1031
1323
  export interface StealthSessionCookies extends CookieJar {
1032
- has(name: string): boolean;
1033
- setFromCookieStrings(cookieStrings: readonly string[]): void;
1034
- toHeader(): string;
1324
+ has(name: string, url?: string): boolean;
1325
+ /** URL-less writes are scoped to the session base URL. */
1326
+ setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
1327
+ toHeader(url?: string): string;
1328
+ /**
1329
+ * Returns every cookie as a flat name/value map, collapsing duplicate names.
1330
+ * @deprecated Use serialize() for lossless, attribute-preserving persistence.
1331
+ */
1035
1332
  snapshot(): Record<string, string>;
1333
+ /**
1334
+ * Restores flat values as host-only, Path=/ cookies on the session base URL.
1335
+ * @deprecated Use deserialize() with state produced by serialize().
1336
+ */
1036
1337
  restore(cookies: Record<string, string>): void;
1338
+ /** Returns a versioned, JSON-safe, attribute-preserving representation of every cookie. */
1339
+ serialize(): StealthCookieStoreV1;
1340
+ /** Replaces the jar with a previously serialized, attribute-preserving cookie store. */
1341
+ deserialize(state: StealthCookieStore): void;
1037
1342
  clear(): void;
1038
1343
  }
1039
1344
 
@@ -1078,8 +1383,14 @@ export interface StealthRedirectRunOptions
1078
1383
  export interface StealthRedirectRunResult {
1079
1384
  final: StealthResponse;
1080
1385
  hops: StealthRedirectHop[];
1081
- reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
1386
+ reason: RedirectRunReason;
1387
+ /**
1388
+ * Complete flat view across all redirect hosts. Attributes and duplicate names are lost.
1389
+ * @deprecated Use cookieStore for lossless persistence.
1390
+ */
1082
1391
  cookies: Record<string, string>;
1392
+ /** Versioned, attribute-preserving cookie state accumulated across the redirect chain. */
1393
+ cookieStore: StealthCookieStoreV1;
1083
1394
  }
1084
1395
 
1085
1396
  export interface StealthSession {
@@ -1169,11 +1480,188 @@ export interface HttpClient {
1169
1480
  ): Promise<AsyncIterable<SseMessage>>;
1170
1481
  }
1171
1482
 
1483
+ /** Request-scoped file reference accepted by provider operation inputs. */
1484
+ export interface ProviderFileRef {
1485
+ readonly type: "request_file";
1486
+ readonly id: string;
1487
+ readonly filename: string;
1488
+ readonly mime_type?: string;
1489
+ readonly size: number;
1490
+ readonly sha256?: string;
1491
+ }
1492
+
1493
+ /** File body resolved from a request-scoped {@link ProviderFileRef}. */
1494
+ export type ProviderResolvedFile = Omit<ProviderFileRef, "mime_type"> & {
1495
+ readonly mimeType?: string;
1496
+ arrayBuffer(): Promise<ArrayBuffer>;
1497
+ bytes(): Promise<Uint8Array>;
1498
+ stream(): ReadableStream<Uint8Array>;
1499
+ };
1500
+
1501
+ /** Resolver supplied by runtimes that accept request-scoped file inputs. */
1502
+ export interface ProviderFilesContext {
1503
+ has(input: string | ProviderFileRef): boolean;
1504
+ resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
1505
+ }
1506
+
1507
+ export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
1508
+
1509
+ export interface NativeTcpPortRange {
1510
+ readonly start: number;
1511
+ readonly end: number;
1512
+ }
1513
+
1514
+ /** Static native TCP egress declared by a provider. */
1515
+ export interface NativeTcpEgressRule {
1516
+ readonly host: string;
1517
+ readonly ports: readonly number[];
1518
+ readonly tls: NativeTcpTlsMode;
1519
+ }
1520
+
1521
+ /**
1522
+ * Bounded native TCP egress discovered through a declared bootstrap endpoint.
1523
+ * Host suffixes are exact DNS suffixes, not wildcard patterns.
1524
+ * Dynamic rules must declare at least one target host selector through
1525
+ * targetHostSuffixes, targetIpv4Cidrs, and/or targetIpv6Cidrs. Literal grant
1526
+ * sources and targets match only same-family selectors (except exact
1527
+ * sourceHost); DNS names match only host/suffix selectors. IPv4-mapped and
1528
+ * IPv4-compatible IPv6 literals are authorized only by IPv4 CIDRs.
1529
+ *
1530
+ * Dynamic rules are ordered. The first rule whose source, target, port, and TLS
1531
+ * selectors match exclusively owns the grant; its ttlMs and maxGrants bounds
1532
+ * apply, and an exhausted/shorter rule never falls through to a later overlap.
1533
+ * Every rule must declare a source host selector, source port list/range, and
1534
+ * target port list/range; omitted ttlMs/maxGrants remain unbounded.
1535
+ */
1536
+ export interface NativeTcpDynamicEgressRule {
1537
+ readonly sourceHost?: string;
1538
+ readonly sourceHostSuffixes?: readonly string[];
1539
+ readonly sourceIpv4Cidrs?: readonly string[];
1540
+ readonly sourceIpv6Cidrs?: readonly string[];
1541
+ readonly sourcePorts?: readonly number[];
1542
+ readonly sourcePortRanges?: readonly NativeTcpPortRange[];
1543
+ readonly targetHostSuffixes?: readonly string[];
1544
+ readonly targetIpv4Cidrs?: readonly string[];
1545
+ readonly targetIpv6Cidrs?: readonly string[];
1546
+ readonly targetPorts?: readonly number[];
1547
+ readonly targetPortRanges?: readonly NativeTcpPortRange[];
1548
+ readonly tls: NativeTcpTlsMode;
1549
+ readonly ttlMs?: number;
1550
+ readonly maxGrants?: number;
1551
+ }
1552
+
1553
+ /** Common TCP/TLS connection input supported by the native runtime. */
1554
+ export interface NativeNetworkConnectInput {
1555
+ readonly host: string;
1556
+ readonly port: number;
1557
+ readonly serverName?: string;
1558
+ readonly rejectUnauthorized?: boolean;
1559
+ /**
1560
+ * Maximum time without a successful socket read before the connection is
1561
+ * closed. Opt-in; when absent, reads can remain pending indefinitely.
1562
+ */
1563
+ readonly idleTimeoutMs?: number;
1564
+ /** Maximum time allowed to establish the TCP/SOCKS/TLS connection. */
1565
+ readonly timeoutMs?: number;
1566
+ readonly signal?: AbortSignal;
1567
+ /** Overrides the credential-derived sticky affinity key. */
1568
+ readonly affinityKey?: string;
1569
+ }
1570
+
1571
+ export type NativeNetworkConnectOptions = Omit<
1572
+ NativeNetworkConnectInput,
1573
+ "serverName" | "rejectUnauthorized"
1574
+ >;
1575
+
1576
+ export type NativeTlsConnectOptions = NativeNetworkConnectInput;
1577
+
1578
+ export interface NativeNetworkDynamicGrantOptions {
1579
+ readonly sourceHost: string;
1580
+ readonly sourcePort: number;
1581
+ readonly host: string;
1582
+ readonly port: number;
1583
+ readonly tls: NativeTcpTlsMode;
1584
+ readonly ttlMs?: number;
1585
+ }
1586
+
1587
+ export interface NativeNetworkEgressGrant {
1588
+ revoke(): void;
1589
+ }
1590
+
1591
+ /** Consumer-facing alias used by native TCP providers. */
1592
+ export type NativeTcpEgressGrant = NativeNetworkEgressGrant;
1593
+
1594
+ /** Resolved egress identity for a native connection routed through a proxy. */
1595
+ export interface NativeProxyEgressInfo {
1596
+ readonly vendor: ProviderProxyProvider;
1597
+ readonly sticky: boolean;
1598
+ /** Vendor sticky session id (sid). Absent for rotating sessions. */
1599
+ readonly sessionId?: string;
1600
+ /** Hard expiry of the sticky binding, ISO 8601. */
1601
+ readonly expiresAt?: string;
1602
+ }
1603
+
1604
+ export type NativeProxyExpiringReason = "sticky_expiry";
1605
+
1606
+ export interface NativeProxyExpiringEvent {
1607
+ readonly expiresAt: string;
1608
+ readonly leadSeconds: number;
1609
+ readonly reason: NativeProxyExpiringReason;
1610
+ }
1611
+
1612
+ /**
1613
+ * Cooperative drain handler. The SDK awaits this before closing a socket whose
1614
+ * sticky proxy binding is about to expire, then force-closes at hard expiry.
1615
+ */
1616
+ export type NativeProxyDrainHandler = (
1617
+ event: NativeProxyExpiringEvent,
1618
+ ) => void | Promise<void>;
1619
+
1620
+ /** Typed reason recorded when the SDK closes a native connection intentionally. */
1621
+ export interface NativeNetworkCloseReason {
1622
+ readonly code: string;
1623
+ readonly message: string;
1624
+ }
1625
+
1626
+ /** Byte-oriented connection returned by the native TCP/TLS runtime. */
1627
+ export interface NativeNetworkConnection {
1628
+ /** Present when the connection was routed through a proxy. */
1629
+ readonly proxy?: NativeProxyEgressInfo;
1630
+ /** Present after an SDK-planned close, such as sticky proxy expiry. */
1631
+ readonly closeReason?: NativeNetworkCloseReason;
1632
+ /** Register a cooperative drain handler for sticky-expiry reconnects. */
1633
+ onExpiring?(handler: NativeProxyDrainHandler): void;
1634
+ read(): Promise<Uint8Array | null>;
1635
+ write(data: Uint8Array): Promise<void>;
1636
+ close(): Promise<void>;
1637
+ }
1638
+
1639
+ export interface NativeNetworkClient {
1640
+ connectTcp(
1641
+ input: NativeNetworkConnectOptions,
1642
+ ): Promise<NativeNetworkConnection>;
1643
+ connectTls(input: NativeTlsConnectOptions): Promise<NativeNetworkConnection>;
1644
+ grantTcpEgress(
1645
+ input: NativeNetworkDynamicGrantOptions,
1646
+ ): NativeNetworkEgressGrant;
1647
+ }
1648
+
1649
+ export interface NativeContext {
1650
+ readonly network: NativeNetworkClient;
1651
+ }
1652
+
1653
+ export interface NativeProviderConfig {
1654
+ readonly network?: {
1655
+ readonly tcp?: readonly NativeTcpEgressRule[];
1656
+ readonly dynamicTcp?: readonly NativeTcpDynamicEgressRule[];
1657
+ };
1658
+ }
1659
+
1172
1660
  export interface ProviderCacheKeyOptions {
1173
1661
  /**
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.
1662
+ * Additional field names whose values are hashed in stable key material. The
1663
+ * SDK always hashes values under known secret-bearing names such as serviceKey,
1664
+ * authorization, cookie, token, password, and secret.
1177
1665
  */
1178
1666
  redactFields?: string[];
1179
1667
  }
@@ -1268,7 +1756,19 @@ export interface BrowserFrame {
1268
1756
  locator(selector: string): BrowserLocator;
1269
1757
  }
1270
1758
 
1271
- export type BrowserResourceMethod = "GET" | "HEAD";
1759
+ export interface BrowserCookie {
1760
+ readonly name: string;
1761
+ readonly value: string;
1762
+ readonly domain: string;
1763
+ readonly path: string;
1764
+ /** Unix seconds. Absent for a session cookie. */
1765
+ readonly expires?: number;
1766
+ readonly httpOnly: boolean;
1767
+ readonly secure: boolean;
1768
+ readonly sameSite?: "Strict" | "Lax" | "None";
1769
+ }
1770
+
1771
+ export type BrowserResourceMethod = "GET" | "HEAD" | "POST";
1272
1772
 
1273
1773
  export type BrowserResourceRequest = {
1274
1774
  readonly url: string;
@@ -1280,16 +1780,19 @@ export type BrowserResourceRequest = {
1280
1780
  export type BrowserResourceBody = Buffer | Uint8Array | ArrayBuffer | string;
1281
1781
 
1282
1782
  export type BrowserResourceDecision =
1783
+ | {
1784
+ readonly action: "continue";
1785
+ }
1283
1786
  | {
1284
1787
  readonly action: "fulfill";
1285
1788
  readonly status?: number;
1286
1789
  readonly headers?: Readonly<Record<string, string>>;
1287
1790
  readonly body?: BrowserResourceBody;
1288
- }
1791
+ }
1289
1792
  | {
1290
1793
  readonly action: "block";
1291
1794
  readonly reason?: string;
1292
- };
1795
+ };
1293
1796
 
1294
1797
  export type BrowserResourceRoute = {
1295
1798
  readonly match:
@@ -1304,13 +1807,30 @@ export type BrowserResourceRoute = {
1304
1807
  export type BrowserResourcePolicy = {
1305
1808
  readonly defaultAction?: "block";
1306
1809
  readonly allowedMethods?: readonly BrowserResourceMethod[];
1810
+ /**
1811
+ * Appends an enforcing CSP header to every renderable document response
1812
+ * while the policy is active. Existing CSP headers are retained, so this
1813
+ * can only further restrict the document.
1814
+ */
1815
+ readonly documentContentSecurityPolicy?: string;
1307
1816
  readonly routes: readonly BrowserResourceRoute[];
1308
1817
  };
1309
1818
 
1310
1819
  export interface BrowserPage extends BrowserFrame {
1311
1820
  close(): Promise<void>;
1821
+ /** Returns the user agent used by this page's browser context. */
1822
+ userAgent(): Promise<string>;
1823
+ /**
1824
+ * Reads the browser context's cookie jar, including httpOnly cookies.
1825
+ * Cookie expiry values are Unix seconds and are absent for session cookies.
1826
+ */
1827
+ cookies(): Promise<readonly BrowserCookie[]>;
1312
1828
  fill(selector: string, text: string): Promise<void>;
1313
1829
  goto(url: string): Promise<void>;
1830
+ goto(
1831
+ url: string,
1832
+ options?: { readonly timeout?: number; readonly waitUntil?: "load" | "domcontentloaded" },
1833
+ ): Promise<void>;
1314
1834
  pageId?: string;
1315
1835
  screenshot(options?: { fullPage?: boolean }): Promise<Buffer>;
1316
1836
  click(selector: string): Promise<void>;
@@ -1398,10 +1918,32 @@ export interface ProviderChoiceBindingOptions {
1398
1918
  credentialKeys?: readonly string[];
1399
1919
  }
1400
1920
 
1921
+ export type ProviderChoiceConsumeMode = "never" | "on-parse" | "explicit";
1922
+
1923
+ export type ProviderChoiceConsumeResult =
1924
+ | { readonly status: "consumed" }
1925
+ | { readonly status: "already-consumed" }
1926
+ | { readonly status: "unsupported" };
1927
+
1928
+ export type ProviderChoiceExplicitParseResult =
1929
+ | {
1930
+ readonly status: "active";
1931
+ readonly payload: Record<string, unknown>;
1932
+ /** Stable, opaque key for provider-owned idempotency records. */
1933
+ readonly replayKey: string;
1934
+ /** Atomically claims a word token. Inline tokens report unsupported. */
1935
+ consume(): Promise<ProviderChoiceConsumeResult>;
1936
+ }
1937
+ | {
1938
+ readonly status: "consumed";
1939
+ /** Use this key to read the provider-owned result before returning an error. */
1940
+ readonly replayKey: string;
1941
+ };
1942
+
1401
1943
  export type ProviderChoiceStorageOptions =
1402
1944
  | {
1403
1945
  readonly mode: "inline";
1404
- }
1946
+ }
1405
1947
  | {
1406
1948
  readonly mode: "server";
1407
1949
  readonly namespace: string;
@@ -1410,7 +1952,7 @@ export type ProviderChoiceStorageOptions =
1410
1952
  readonly maxEntries: number;
1411
1953
  readonly maxValueBytes: number;
1412
1954
  readonly unavailable?: "reject";
1413
- }
1955
+ }
1414
1956
  | {
1415
1957
  readonly mode: "auto";
1416
1958
  readonly namespace: string;
@@ -1420,7 +1962,7 @@ export type ProviderChoiceStorageOptions =
1420
1962
  readonly maxEntries: number;
1421
1963
  readonly maxValueBytes: number;
1422
1964
  readonly unavailable?: "reject";
1423
- };
1965
+ };
1424
1966
 
1425
1967
  export interface ProviderChoiceIssueOptions<
1426
1968
  TPayload extends Record<string, unknown>,
@@ -1431,6 +1973,8 @@ export interface ProviderChoiceIssueOptions<
1431
1973
  ttlMs: number;
1432
1974
  nowMs?: number;
1433
1975
  bind?: ProviderChoiceBindingOptions;
1976
+ /** Server storage only: standard emits four words; high emits five. */
1977
+ strength?: "standard" | "high";
1434
1978
  storage?: ProviderChoiceStorageOptions;
1435
1979
  }
1436
1980
 
@@ -1443,6 +1987,8 @@ export interface ProviderChoiceParseOptions {
1443
1987
  futureToleranceMs?: number;
1444
1988
  bind?: ProviderChoiceBindingOptions;
1445
1989
  storage?: ProviderChoiceStorageOptions;
1990
+ /** Defaults to never, preserving reusable choice-token parse semantics. */
1991
+ consume?: ProviderChoiceConsumeMode;
1446
1992
  }
1447
1993
 
1448
1994
  export interface ProviderChoiceContext {
@@ -1470,6 +2016,9 @@ export interface ProviderChoiceContext {
1470
2016
  issue<TPayload extends Record<string, unknown>>(
1471
2017
  options: ProviderChoiceIssueOptions<TPayload>,
1472
2018
  ): string | Promise<string>;
2019
+ parse(
2020
+ options: ProviderChoiceParseOptions & { readonly consume: "explicit" },
2021
+ ): Promise<ProviderChoiceExplicitParseResult>;
1473
2022
  parse(
1474
2023
  options: ProviderChoiceParseOptions & {
1475
2024
  readonly storage?: { readonly mode: "inline" };
@@ -1491,7 +2040,11 @@ export interface ProviderChoiceContext {
1491
2040
  >;
1492
2041
  },
1493
2042
  ): Record<string, unknown> | Promise<Record<string, unknown>>;
1494
- parse(options: ProviderChoiceParseOptions): Record<string, unknown>;
2043
+ parse(
2044
+ options: ProviderChoiceParseOptions,
2045
+ ):
2046
+ | Record<string, unknown>
2047
+ | Promise<Record<string, unknown> | ProviderChoiceExplicitParseResult>;
1495
2048
  }
1496
2049
 
1497
2050
  export interface ContextScratchpad {
@@ -1564,11 +2117,11 @@ export interface AuthFlowTerminalContext {
1564
2117
  }
1565
2118
  >;
1566
2119
  readonly expectedInput?: never;
1567
- }
2120
+ }
1568
2121
  | {
1569
2122
  readonly expectedInput: Record<string, unknown>;
1570
2123
  readonly fields?: never;
1571
- }
2124
+ }
1572
2125
  ),
1573
2126
  ): AuthTurn;
1574
2127
  nextPoll(options?: {
@@ -1581,16 +2134,34 @@ export interface AuthFlowTerminalContext {
1581
2134
  }
1582
2135
 
1583
2136
  export interface FlowContext {
2137
+ /** Gateway auth-flow id. Required by flow-scoped auth ceremonies. */
2138
+ flowId?: string;
1584
2139
  connectionId?: string;
1585
2140
  externalRef?: string;
1586
2141
  tenantId: string;
1587
2142
  providerId: string;
1588
2143
  http: HttpClient;
2144
+ /** Durable connection-scoped runtime state. Present when the host runtime
2145
+ * supplies one; auth ceremonies must fail closed when absent rather than
2146
+ * fall back to bypassable in-process storage.
2147
+ *
2148
+ * Scoped via `ProviderRuntimeState.forConnection`: requests that resolve no
2149
+ * connection id (pre-connection ceremonies such as first-time logins) share
2150
+ * the documented isolated missing-connection scope. That sharing is the
2151
+ * intended semantic — it lets counters keyed by caller identity (e.g. a
2152
+ * login email) persist across separate ceremonies for the same caller.
2153
+ * Flows storing entries in that scope MUST key them by caller identity;
2154
+ * un-keyed entries would be shared across all connectionless ceremonies. */
2155
+ readonly state?: ProviderRuntimeState;
2156
+ /** Present when the selected runtime supplies native network capabilities. */
2157
+ readonly native?: NativeContext;
1589
2158
  stealth: StealthClient;
1590
2159
  env: EnvContext;
1591
2160
  credential?: CredentialContext;
1592
2161
  context: ContextScratchpad;
2162
+ ocr: OcrContext;
1593
2163
  stt: SttContext;
2164
+ resolver: ResolverContext;
1594
2165
  auth: AuthFlowTerminalContext;
1595
2166
  }
1596
2167
 
@@ -1633,7 +2204,14 @@ export type ProviderStateDurationString =
1633
2204
  | `${number}${"ms" | "s" | "m" | "h" | "d"}`
1634
2205
  | `PT${string}`;
1635
2206
 
2207
+ export type StateNamespaceScope = "connection" | "provider";
2208
+
1636
2209
  export interface StateNamespaceOptions {
2210
+ /**
2211
+ * State isolation boundary. Connection scope is the default; provider scope
2212
+ * must be selected explicitly for provider-wide coordination state.
2213
+ */
2214
+ scope?: StateNamespaceScope;
1637
2215
  /** Default TTL used when a write omits ttl. Required to avoid unbounded state. */
1638
2216
  defaultTtl: ProviderStateDurationString;
1639
2217
  /** Maximum allowed TTL; writes are rejected when they exceed this policy. */
@@ -1694,6 +2272,11 @@ export interface ProviderStateNamespace {
1694
2272
  }
1695
2273
 
1696
2274
  export interface ProviderRuntimeState {
2275
+ /**
2276
+ * Returns an immutable view bound to one request connection. An unresolved
2277
+ * connection uses an isolated reserved sentinel, never the provider-global scope.
2278
+ */
2279
+ forConnection(connectionId: string | undefined): ProviderRuntimeState;
1697
2280
  namespace(
1698
2281
  name: string,
1699
2282
  options: StateNamespaceOptions,
@@ -1705,18 +2288,59 @@ export interface ProviderContext {
1705
2288
  credential: CredentialContext;
1706
2289
  request?: ProviderRequestContext;
1707
2290
  http: HttpClient;
2291
+ /** Present for requests carrying runtime-resolvable file references. */
2292
+ readonly files?: ProviderFilesContext;
2293
+ /** Native network capability selected by declaration-derived contexts. */
2294
+ readonly native: NativeContext;
1708
2295
  cache: ProviderCache;
1709
2296
  state: ProviderRuntimeState;
1710
2297
  stealth: StealthClient;
1711
2298
  browser: BrowserClient;
1712
2299
  trace: TraceContext;
1713
2300
  auth: AuthContext;
2301
+ ocr: OcrContext;
1714
2302
  stt: SttContext;
2303
+ resolver: ResolverContext;
1715
2304
  choice: ProviderChoiceContext;
1716
2305
  }
1717
2306
 
2307
+ /**
2308
+ * The operation context exposed for one provider declaration. Capability
2309
+ * bindings are present only when their corresponding declaration is present;
2310
+ * trace and request remain ambient runtime bindings.
2311
+ */
2312
+ export type ProviderContextFor<TConfig> =
2313
+ Pick<ProviderContext, "trace" | "request">
2314
+ & ("env" extends keyof TConfig ? Pick<ProviderContext, "env"> : Record<never, never>)
2315
+ & ("credential" extends keyof TConfig ? Pick<ProviderContext, "credential"> : Record<never, never>)
2316
+ & ("http" extends keyof TConfig ? Pick<ProviderContext, "http"> : Record<never, never>)
2317
+ & ("files" extends keyof TConfig ? Pick<ProviderContext, "files"> : Record<never, never>)
2318
+ & ("native" extends keyof TConfig ? Pick<ProviderContext, "native"> : Record<never, never>)
2319
+ & ("cache" extends keyof TConfig ? Pick<ProviderContext, "cache"> : Record<never, never>)
2320
+ & ("state" extends keyof TConfig ? Pick<ProviderContext, "state"> : Record<never, never>)
2321
+ & ("stealth" extends keyof TConfig ? Pick<ProviderContext, "stealth"> : Record<never, never>)
2322
+ & ("browser" extends keyof TConfig ? Pick<ProviderContext, "browser"> : Record<never, never>)
2323
+ & ("auth" extends keyof TConfig ? Pick<ProviderContext, "auth"> : Record<never, never>)
2324
+ & ("ocr" extends keyof TConfig ? Pick<ProviderContext, "ocr"> : Record<never, never>)
2325
+ & ("stt" extends keyof TConfig ? Pick<ProviderContext, "stt"> : Record<never, never>)
2326
+ & ("resolver" extends keyof TConfig ? Pick<ProviderContext, "resolver"> : Record<never, never>)
2327
+ & ("choice" extends keyof TConfig ? Pick<ProviderContext, "choice"> : Record<never, never>);
2328
+
2329
+ export interface ProxiedOAuthConfig {
2330
+ authorizeUrl: string;
2331
+ tokenUrl: string;
2332
+ customScheme: string;
2333
+ rewriteProfile: string;
2334
+ clientIdEnvKey: string;
2335
+ pkce?: "S256" | "none";
2336
+ authorizeParams?: Record<string, string>;
2337
+ tokenParams?: Record<string, string>;
2338
+ }
2339
+
1718
2340
  export interface AuthConfig {
1719
2341
  mode: AuthMode;
2342
+ /** Browser reverse-proxy contract for providers with custom-scheme OAuth callbacks. */
2343
+ proxied?: ProxiedOAuthConfig;
1720
2344
  flow?: AuthFlowDefinition;
1721
2345
  }
1722
2346
 
@@ -1758,6 +2382,7 @@ export interface OperationContractMetadata {
1758
2382
  export interface OperationDefinition<
1759
2383
  TInput extends SchemaLike = SchemaLike,
1760
2384
  TOutput extends SchemaLike = SchemaLike,
2385
+ TContext = ProviderContext,
1761
2386
  > {
1762
2387
  /**
1763
2388
  * Short English display title for the operation. The SDK passes it through
@@ -1789,7 +2414,7 @@ export interface OperationDefinition<
1789
2414
  input: TInput;
1790
2415
  output: TOutput;
1791
2416
  handler(
1792
- ctx: ProviderContext,
2417
+ ctx: TContext,
1793
2418
  input: InferSchemaOutput<TInput>,
1794
2419
  ):
1795
2420
  | OperationHandlerResult<InferSchemaOutput<TOutput>>
@@ -1797,6 +2422,11 @@ export interface OperationDefinition<
1797
2422
  fixtures?: {
1798
2423
  request: InferSchemaOutput<TInput>;
1799
2424
  response: InferSchemaOutput<TOutput>;
2425
+ /**
2426
+ * KST calendar date when `response` evidence was captured. Date fields in
2427
+ * the response align with this date, not a resolved relative request date.
2428
+ */
2429
+ recordedAt?: string;
1800
2430
  };
1801
2431
  upstream?: {
1802
2432
  baseUrl?: string;
@@ -1860,12 +2490,15 @@ export interface ProviderDefinition {
1860
2490
  */
1861
2491
  deployment?: ProviderDeploymentOverrides;
1862
2492
  allowedHosts?: string[];
2493
+ native?: NativeProviderConfig;
1863
2494
  stealth?: {
1864
2495
  profile: string;
1865
2496
  platform: StealthPlatform;
1866
2497
  };
1867
2498
  proxy?: ProviderProxyConfig;
2499
+ ocr?: ProviderOcrConfig;
1868
2500
  stt?: ProviderSttConfig;
2501
+ resolver?: ProviderResolverConfig;
1869
2502
  browser?: {
1870
2503
  engine: BrowserEngine;
1871
2504
  };