/** * flow-captcha.ts — shared captcha-retry resolution for the in-repo Google Flow * (useapi.net) submit paths: POST /videos (R2V + omni-flash V2V), POST /images, * POST /voices, and POST /videos/upscale. * * The useapi Flow API auto-solves the Google reCAPTCHA when a submit body carries * `captchaRetry` (1-10): it "cycles through configured providers in priority * order" and draws on the 100 free CapSolver credits granted with the first * account (and any provider keys registered via POST /accounts/captcha-providers). * Passing it is the SUPPORTED way to ride through the intermittent * `403 PUBLIC_ERROR_UNUSUAL_ACTIVITY` / reCAPTCHA blocks — without it the submit * just fails and the caller is left to cool down and resubmit. * * The count comes from VCLAW_FLOW_CAPTCHA_RETRY (default 3), clamped to [1,10]; * an explicit `0`/negative opts out (no field emitted), and garbage falls back to * the default. `captchaToken`/`captchaOrder` are intentionally NOT set — the spec * marks the three mutually exclusive, and `captchaRetry` is the auto-solve knob. */ export const FLOW_CAPTCHA_RETRY_DEFAULT = 3; export const FLOW_CAPTCHA_RETRY_MAX = 10; /** * Resolve the captcha-retry count for a Flow submit body from the environment. * Returns 0 (omit the field — explicit opt-out) when VCLAW_FLOW_CAPTCHA_RETRY is * `0` or negative; the default when unset or unparseable; otherwise the clamped * value. */ export function resolveFlowCaptchaRetry(env: NodeJS.ProcessEnv = process.env): number { const raw = (env.VCLAW_FLOW_CAPTCHA_RETRY ?? '').trim(); if (raw === '') return FLOW_CAPTCHA_RETRY_DEFAULT; const n = Number.parseInt(raw, 10); if (!Number.isFinite(n)) return FLOW_CAPTCHA_RETRY_DEFAULT; if (n <= 0) return 0; return Math.min(n, FLOW_CAPTCHA_RETRY_MAX); } /** * Set `captchaRetry` on a Flow submit body when `retry > 0` (mutates and returns * the body for chaining). A retry of 0 leaves the body untouched (opt-out). */ export function applyFlowCaptcha>(body: T, retry: number): T { if (retry > 0) (body as Record).captchaRetry = retry; return body; }