@prompteryx/sdk 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -13,9 +13,15 @@ import {
13
13
  } from "./chunk-ODLNHNQT.mjs";
14
14
 
15
15
  // src/client.ts
16
- var DEFAULT_BASE_URL = "https://prompteryx.com";
16
+ var DEFAULT_BASE_URL = "https://www.prompteryx.ai";
17
17
  var DEFAULT_TIMEOUT_MS = 6e4;
18
18
  var DEFAULT_MAX_RETRIES = 2;
19
+ function unwrapEnvelope(parsed) {
20
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && "success" in parsed && "data" in parsed && typeof parsed.success === "boolean") {
21
+ return parsed.data;
22
+ }
23
+ return parsed;
24
+ }
19
25
  var HttpClient = class {
20
26
  constructor(opts) {
21
27
  if (!opts.apiKey) {
@@ -40,14 +46,16 @@ var HttpClient = class {
40
46
  const res = await this.rawRequest(path, opts);
41
47
  const text = await res.text();
42
48
  if (!text) return void 0;
49
+ let parsed;
43
50
  try {
44
- return JSON.parse(text);
51
+ parsed = JSON.parse(text);
45
52
  } catch {
46
53
  throw new ParseError(`Failed to parse JSON response from ${path}`, {
47
54
  status: res.status,
48
55
  raw: text.slice(0, 500)
49
56
  });
50
57
  }
58
+ return unwrapEnvelope(parsed);
51
59
  }
52
60
  /** Returns the raw Response. Throws typed errors on non-2xx, but does
53
61
  * not attempt to read the body. Useful for downloading binaries. */
@@ -904,11 +912,16 @@ var AUTOPILOT_MODELS = [
904
912
  "gpt-5.6-terra",
905
913
  "gpt-5.6-sol",
906
914
  "gpt-5.5",
915
+ "gpt-6-astra",
916
+ // OpenAI flagship (Sep 2026) — admin-gated in the UI for now
907
917
  // ── Generic Vision Loop (standard chat models on screenshots) ────────────
918
+ "claude-fable-5-1-vision",
908
919
  "claude-fable-5-vision",
909
920
  "claude-opus-5-vision",
910
921
  "claude-sonnet-5-vision",
911
922
  "claude-sonnet-4-6-vision",
923
+ "gpt-6-astra-vision",
924
+ // admin-gated in the UI for now
912
925
  "gpt-5.6-luna-vision",
913
926
  "gpt-5.4-vision",
914
927
  "gpt-4o-vision",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/resources/autopilot.ts","../src/resources/cloudBrowser.ts","../src/resources/executions.ts","../src/resources/profiles.ts","../src/resources/schedules.ts","../src/resources/subscription.ts","../src/resources/workflows.ts","../src/models.ts","../src/index.ts"],"sourcesContent":["/**\r\n * HTTP client for the Prompteryx SDK.\r\n *\r\n * Thin layer over `fetch` that adds:\r\n * - Bearer auth from the configured API key\r\n * - JSON serialisation + content-type\r\n * - Status-to-typed-error mapping (see errors.ts)\r\n * - Configurable timeout via AbortController\r\n * - Bounded retry for idempotent ops on 5xx / network errors\r\n * - Optional SSE streaming for execution logs / agent traces\r\n *\r\n * Anything that needs raw `Response` (e.g. downloading a recording\r\n * binary) can use `rawRequest()`. Everything else should use\r\n * `request<T>()` which returns the parsed JSON body typed as T.\r\n */\r\n\r\nimport {\r\n AuthError,\r\n NetworkError,\r\n NotFoundError,\r\n ParseError,\r\n PrompteryxError,\r\n QuotaError,\r\n RateLimitError,\r\n ServerError,\r\n TimeoutError,\r\n ValidationError,\r\n} from './errors'\r\nimport type { PrompteryxClientOptions } from './types'\r\n\r\nconst DEFAULT_BASE_URL = 'https://prompteryx.com'\r\nconst DEFAULT_TIMEOUT_MS = 60_000\r\nconst DEFAULT_MAX_RETRIES = 2\r\n\r\nexport interface RequestOptions {\r\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'\r\n /** Object that will be JSON.stringified into the body. Skip for GET/DELETE. */\r\n body?: unknown\r\n /** Extra headers merged into the defaults. */\r\n headers?: Record<string, string>\r\n /** Override the client default timeout for this single call. */\r\n timeoutMs?: number\r\n /** Whether this op is safe to retry on transient failure. Defaults\r\n * based on method: GET = yes, others = no. The caller can force\r\n * retry for idempotent POSTs (e.g. a poll loop). */\r\n retry?: boolean\r\n /** Query string params (URI-encoded automatically). */\r\n query?: Record<string, string | number | boolean | undefined | null>\r\n /** Optional AbortSignal for caller-side cancellation. */\r\n signal?: AbortSignal\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n /** Optional Cloud Browser key (`pcb_live_…`) — a separate key family used\r\n * only by the /api/v1/cloud-browser/* endpoints (sent as `x-api-key`). */\r\n public readonly cloudBrowserKey?: string\r\n private readonly baseUrl: string\r\n private readonly timeoutMs: number\r\n private readonly maxRetries: number\r\n private readonly defaultHeaders: Record<string, string>\r\n private readonly fetchImpl: typeof fetch\r\n\r\n constructor(opts: PrompteryxClientOptions) {\r\n if (!opts.apiKey) {\r\n throw new PrompteryxError('apiKey is required to construct a Prompteryx client')\r\n }\r\n this.apiKey = opts.apiKey\r\n this.cloudBrowserKey = opts.cloudBrowserKey\r\n this.baseUrl = (opts.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '')\r\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\r\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\r\n this.defaultHeaders = opts.defaultHeaders ?? {}\r\n const f = opts.fetch ?? globalThis.fetch\r\n if (!f) {\r\n throw new PrompteryxError(\r\n 'No fetch implementation found. Provide options.fetch or run on a runtime with global fetch (Node 18+, browser, Cloudflare Workers).',\r\n )\r\n }\r\n // Bind so `this` doesn't get lost on assignment.\r\n this.fetchImpl = f.bind(globalThis)\r\n }\r\n\r\n /** Returns the JSON-parsed body typed as T. Throws typed errors on non-2xx. */\r\n async request<T = unknown>(path: string, opts: RequestOptions = {}): Promise<T> {\r\n const res = await this.rawRequest(path, opts)\r\n const text = await res.text()\r\n if (!text) return undefined as T\r\n try {\r\n return JSON.parse(text) as T\r\n } catch {\r\n throw new ParseError(`Failed to parse JSON response from ${path}`, {\r\n status: res.status,\r\n raw: text.slice(0, 500),\r\n })\r\n }\r\n }\r\n\r\n /** Returns the raw Response. Throws typed errors on non-2xx, but does\r\n * not attempt to read the body. Useful for downloading binaries. */\r\n async rawRequest(path: string, opts: RequestOptions = {}): Promise<Response> {\r\n const method = opts.method ?? 'GET'\r\n const url = this.buildUrl(path, opts.query)\r\n const shouldRetry = opts.retry ?? (method === 'GET')\r\n const maxAttempts = shouldRetry ? this.maxRetries + 1 : 1\r\n let lastErr: unknown\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n const res = await this.sendOnce(url, method, opts)\r\n if (res.ok) return res\r\n // Map status → typed error. For 5xx / 429 with retries remaining,\r\n // throw a retryable subclass and try again.\r\n const err = await this.errorFromResponse(res)\r\n if (this.isRetryable(err) && attempt < maxAttempts - 1) {\r\n await this.backoff(attempt, err)\r\n lastErr = err\r\n continue\r\n }\r\n throw err\r\n } catch (e) {\r\n // Network / abort errors: treat as retryable when we have budget.\r\n if (e instanceof PrompteryxError) throw e\r\n const wrapped = this.wrapTransport(e)\r\n if (this.isRetryable(wrapped) && attempt < maxAttempts - 1) {\r\n await this.backoff(attempt, wrapped)\r\n lastErr = wrapped\r\n continue\r\n }\r\n throw wrapped\r\n }\r\n }\r\n // Shouldn't reach here, but TS likes a return.\r\n throw lastErr ?? new PrompteryxError('Unknown error after retries exhausted')\r\n }\r\n\r\n /**\r\n * Stream a Server-Sent Events response line-by-line as JSON-parsed\r\n * payloads. Yields each event's `data:` payload parsed as JSON. The\r\n * caller is responsible for breaking the loop / cancelling the\r\n * AbortSignal when done.\r\n */\r\n async *streamSse<T = unknown>(path: string, opts: RequestOptions = {}): AsyncGenerator<T, void, void> {\r\n const res = await this.rawRequest(path, {\r\n ...opts,\r\n headers: { ...opts.headers, Accept: 'text/event-stream' },\r\n })\r\n if (!res.body) return\r\n const reader = res.body.getReader()\r\n const decoder = new TextDecoder()\r\n let buf = ''\r\n while (true) {\r\n const { value, done } = await reader.read()\r\n if (done) break\r\n buf += decoder.decode(value, { stream: true })\r\n // SSE events separated by blank line. Each event has one or more\r\n // `data: ` lines we concatenate.\r\n let idx\r\n while ((idx = buf.indexOf('\\n\\n')) !== -1) {\r\n const raw = buf.slice(0, idx)\r\n buf = buf.slice(idx + 2)\r\n const dataLines = raw\r\n .split('\\n')\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trim())\r\n if (dataLines.length === 0) continue\r\n const payload = dataLines.join('\\n')\r\n if (!payload) continue\r\n try {\r\n yield JSON.parse(payload) as T\r\n } catch {\r\n // Skip malformed events rather than dropping the whole stream.\r\n // Real-world SSE has occasional keepalive comments + heartbeat\r\n // lines we don't want to crash on.\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ── internals ────────────────────────────────────────────────────────\r\n\r\n private async sendOnce(url: string, method: string, opts: RequestOptions): Promise<Response> {\r\n const timeoutMs = opts.timeoutMs ?? this.timeoutMs\r\n const ctl = new AbortController()\r\n const t = setTimeout(() => ctl.abort(), timeoutMs)\r\n // Combine caller signal with our timeout signal.\r\n if (opts.signal) {\r\n if (opts.signal.aborted) ctl.abort()\r\n else opts.signal.addEventListener('abort', () => ctl.abort(), { once: true })\r\n }\r\n try {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n Accept: 'application/json',\r\n ...this.defaultHeaders,\r\n ...(opts.headers ?? {}),\r\n }\r\n let body: BodyInit | undefined\r\n if (opts.body !== undefined) {\r\n headers['Content-Type'] = 'application/json'\r\n body = JSON.stringify(opts.body)\r\n }\r\n return await this.fetchImpl(url, {\r\n method,\r\n headers,\r\n body,\r\n signal: ctl.signal,\r\n })\r\n } finally {\r\n clearTimeout(t)\r\n }\r\n }\r\n\r\n private buildUrl(path: string, query?: RequestOptions['query']): string {\r\n const base = path.startsWith('http') ? path : `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\r\n if (!query) return base\r\n const params = new URLSearchParams()\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined || v === null) continue\r\n params.set(k, String(v))\r\n }\r\n const qs = params.toString()\r\n return qs ? `${base}${base.includes('?') ? '&' : '?'}${qs}` : base\r\n }\r\n\r\n private async errorFromResponse(res: Response): Promise<PrompteryxError> {\r\n let parsed: any = null\r\n try {\r\n const text = await res.text()\r\n parsed = text ? JSON.parse(text) : null\r\n } catch { /* ignore — body wasn't JSON */ }\r\n const message = parsed?.error?.message\r\n ?? parsed?.message\r\n ?? parsed?.error\r\n ?? `Request failed with ${res.status}`\r\n const code = parsed?.error?.code ?? parsed?.code\r\n const requestId = res.headers.get('x-request-id') ?? undefined\r\n const opts = { status: res.status, code, requestId, raw: parsed }\r\n switch (res.status) {\r\n case 401:\r\n case 403:\r\n return new AuthError(message, opts)\r\n case 402:\r\n return new QuotaError(message, { ...opts, resources: parsed?.error?.resources ?? parsed?.resources })\r\n case 404:\r\n return new NotFoundError(message, opts)\r\n case 422:\r\n return new ValidationError(message, opts)\r\n case 429: {\r\n const retryAfter = parseInt(res.headers.get('retry-after') ?? '0', 10)\r\n return new RateLimitError(message, { ...opts, retryAfterSeconds: Number.isFinite(retryAfter) ? retryAfter : undefined })\r\n }\r\n default:\r\n if (res.status >= 500) return new ServerError(message, opts)\r\n return new PrompteryxError(message, opts)\r\n }\r\n }\r\n\r\n private wrapTransport(e: unknown): PrompteryxError {\r\n const msg = e instanceof Error ? e.message : String(e)\r\n if (e instanceof Error && (e.name === 'AbortError' || msg.includes('aborted'))) {\r\n return new TimeoutError(`Request timed out: ${msg}`)\r\n }\r\n return new NetworkError(`Network error: ${msg}`)\r\n }\r\n\r\n private isRetryable(err: PrompteryxError): boolean {\r\n if (err instanceof ServerError) return true\r\n if (err instanceof RateLimitError) return true\r\n if (err instanceof NetworkError) return true\r\n if (err instanceof TimeoutError) return true\r\n return false\r\n }\r\n\r\n private async backoff(attempt: number, err: PrompteryxError): Promise<void> {\r\n // Honour `Retry-After` when the server provided one.\r\n const retryAfter = (err as RateLimitError).retryAfterSeconds\r\n if (retryAfter && retryAfter > 0) {\r\n return new Promise((r) => setTimeout(r, Math.min(retryAfter, 30) * 1000))\r\n }\r\n // Otherwise exponential backoff with jitter: 250ms, 500ms, 1s, 2s, ...\r\n const base = 250 * Math.pow(2, attempt)\r\n const jitter = Math.random() * 100\r\n return new Promise((r) => setTimeout(r, base + jitter))\r\n }\r\n}\r\n","/**\r\n * `px.autopilot.*` — autonomous browser agent.\r\n *\r\n * **Autopilot** is the autonomous, multi-step surface. You hand it\r\n * a goal in plain English; it drives the browser end-to-end and\r\n * returns a step-by-step trace. Counterpart to **Copilot** which\r\n * helps with one step at a time (see ../page.ts).\r\n *\r\n * Built on the existing AI Browser Agent runtime. Every option the\r\n * in-app UI exposes — model, max steps, system-prompt override,\r\n * tool restrictions, viewport, region, proxy, CAPTCHA, recording —\r\n * is available via the SDK. New options added to the runtime ride\r\n * through `passthrough` without an SDK release.\r\n *\r\n * **Action caching superpower** — set `saveAsWorkflow: true` and the\r\n * autopilot's discovered action sequence is captured as a permanent\r\n * Visual Studio workflow you can replay for free forever. The\r\n * response includes `savedWorkflowId`. Subsequent calls to\r\n * `px.workflows.run(savedWorkflowId)` cost no AI Credits and benefit\r\n * from multi-option-selector resilience to UI changes.\r\n */\r\n\r\nimport { ParseError, PrompteryxError } from '../errors'\r\nimport type { HttpClient } from '../client'\r\nimport type {\r\n AutopilotRunOptions,\r\n AutopilotRunResult,\r\n AutopilotStep,\r\n} from '../types'\r\n\r\nexport class AutopilotResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Run the autopilot. Blocks until the task finishes (success, step\r\n * limit, or error). Returns the trace plus optionally the saved\r\n * workflow id.\r\n *\r\n * ```ts\r\n * const result = await px.autopilot.run({\r\n * goal: 'Apply for the Senior Engineer role at OpenAI',\r\n * startUrl: 'https://openai.com/careers',\r\n * maxSteps: 40,\r\n * saveAsWorkflow: true, // Replay-forever, zero AI cost\r\n * session: { useProxy: true, useCaptcha: true },\r\n * })\r\n * if (result.savedWorkflowId) {\r\n * console.log('Saved as workflow:', result.savedWorkflowId)\r\n * // Run it later for free:\r\n * await px.workflows.run(result.savedWorkflowId)\r\n * }\r\n * ```\r\n */\r\n async run(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n if (opts.target === 'local') {\r\n // Local Chrome autopilot (v0.3+): drive the user's OWN Chrome via the\r\n // Prompteryx desktop app on THIS machine. Zero cloud-browser minutes.\r\n // The SDK talks directly to the local runner (localhost:61337) — the\r\n // cloud API can't reach the user's machine — so requirements are: the\r\n // desktop app RUNNING + SIGNED IN, and your code on the same machine.\r\n return this.runLocal(opts)\r\n }\r\n // Multi-agent swarm runs server-side and returns a MERGED result in one\r\n // response — keep it on the single-request path (unchanged).\r\n if (opts.agents && opts.agents > 1) {\r\n return this.runSwarm(opts)\r\n }\r\n // Single cloud agent: ASYNC start → run(poll) so a LONG task (e.g. filling a\r\n // form once per CSV row) never runs in one synchronous request — which would\r\n // exceed the infra GATEWAY timeout and hand the caller an HTML error page that\r\n // res.json() chokes on. Each request stays short; we loop until the job is done.\r\n return this.runAsync(opts)\r\n }\r\n\r\n /** The task params shared by the sync, swarm, and async request bodies. */\r\n private cloudTaskBody(opts: AutopilotRunOptions): Record<string, unknown> {\r\n return {\r\n instruction: opts.goal,\r\n startUrl: opts.startUrl,\r\n maxSteps: opts.maxSteps,\r\n maxCredits: opts.maxCredits,\r\n model: opts.model,\r\n aiVision: opts.aiVision,\r\n finalStepVision: opts.finalStepVision,\r\n outputSchema: opts.outputSchema,\r\n costSaving: opts.costSaving,\r\n costSavingMaxBatch: opts.costSavingMaxBatch,\r\n carefulBatching: opts.carefulBatching,\r\n saveAsWorkflow: opts.saveAsWorkflow,\r\n savedWorkflowName: opts.savedWorkflowName,\r\n sessionId: opts.sessionId,\r\n systemPromptOverride: opts.systemPromptOverride,\r\n allowedTools: opts.allowedTools,\r\n viewport: opts.viewport,\r\n session: opts.session,\r\n // Settings parity (2026-07-15) — mirror the AI Browser Agent settings dialog.\r\n safetyConsent: opts.safetyConsent,\r\n confirmUnclear: opts.confirmUnclear,\r\n enableContextCompression: opts.enableContextCompression,\r\n compressionThreshold: opts.compressionThreshold,\r\n enableSessionReset: opts.enableSessionReset,\r\n sessionResetThreshold: opts.sessionResetThreshold,\r\n ...opts.passthrough,\r\n }\r\n }\r\n\r\n /** Multi-agent swarm — one synchronous request; the server merges all lanes. */\r\n private async runSwarm(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const env = await this.http.request<{ data?: unknown }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: opts.timeoutMs ?? 10 * 60_000,\r\n body: {\r\n ...this.cloudTaskBody(opts),\r\n agents: opts.agents,\r\n collaborate: opts.collaborate,\r\n attachmentContext: opts.attachmentContext,\r\n maxRunCredits: opts.maxRunCredits,\r\n },\r\n })\r\n return this.mapResult(env?.data ?? env)\r\n }\r\n\r\n /**\r\n * Async single-agent run: POST { mode:'start' } to set up the job (returns a\r\n * jobId immediately), then POST { mode:'run' } in a loop — each advances the job\r\n * for up to ~230s server-side and returns the current status — until the job is\r\n * terminal or `opts.timeoutMs` elapses. No single request is long, so the gateway\r\n * timeout is never hit. Same `AutopilotRunResult` shape as before.\r\n */\r\n private async runAsync(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const timeoutMs = opts.timeoutMs ?? 10 * 60_000\r\n const deadline = Date.now() + timeoutMs\r\n const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\r\n\r\n // 1) START — SETUP only. Short request; returns { jobId, sessionId }.\r\n const startEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 60_000,\r\n body: { ...this.cloudTaskBody(opts), mode: 'start' },\r\n })\r\n const jobId: string | undefined = startEnv?.data?.jobId\r\n if (!jobId) {\r\n // Back-compat: an OLDER server without async mode ran the whole task\r\n // synchronously for mode:'start', so the response IS a full result. Return it.\r\n return this.mapResult(startEnv?.data ?? startEnv)\r\n }\r\n\r\n // 2) RUN — advance in ≤230s chunks until terminal (or the SDK timeout). The\r\n // chunk itself is the wait; a transport blip on a chunk is safe to retry.\r\n let view: any = null\r\n while (Date.now() < deadline) {\r\n const runEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 250_000,\r\n retry: true,\r\n body: { jobId, mode: 'run', maxSteps: opts.maxSteps },\r\n })\r\n view = runEnv?.data ?? null\r\n if (!view || view.terminal || view.status !== 'running') break\r\n await sleep(500)\r\n }\r\n\r\n // 3) If we bailed on the SDK timeout while still running, one status read gives\r\n // the latest known state (and triggers server finalize if it's since ended).\r\n if (view && view.status === 'running') {\r\n try {\r\n const statusEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n query: { jobId },\r\n timeoutMs: 30_000,\r\n })\r\n if (statusEnv?.data) view = statusEnv.data\r\n } catch { /* keep the last view */ }\r\n }\r\n\r\n return this.mapResult(view)\r\n }\r\n\r\n /** Map an execute-endpoint payload (sync result, swarm result, or async status\r\n * view — they share finalAnswer / steps / usage / savedWorkflowId / status) into\r\n * the public AutopilotRunResult shape. */\r\n private mapResult(data: any): AutopilotRunResult {\r\n const d = data || {}\r\n const status: string | undefined = d.status\r\n const success = status === 'completed' || status === 'max_steps_reached'\r\n const steps: AutopilotStep[] = Array.isArray(d.steps)\r\n ? d.steps.map((s: any, i: number) => ({\r\n step: i + 1,\r\n action: typeof s?.action === 'string' ? s.action : (s?.action?.name || 'action'),\r\n result: s?.details ?? s?.result,\r\n }))\r\n : []\r\n return {\r\n success,\r\n finalAnswer: d.finalAnswer,\r\n steps,\r\n savedWorkflowId: d.savedWorkflowId,\r\n usage: d.usage,\r\n swarm: d.swarm,\r\n }\r\n }\r\n\r\n /**\r\n * Local Chrome autopilot — talks DIRECTLY to the Prompteryx desktop app on\r\n * this machine (localhost:61337): opens your local Chrome, runs the agent\r\n * loop there, polls until done. Same options as `run` (model, aiVision\r\n * preset, maxSteps, maxCredits, costSaving). Credits still apply; cloud\r\n * minutes do not. The tab stays open after the run for follow-ups.\r\n */\r\n private async runLocal(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const fetchImpl: typeof fetch = (globalThis as any).fetch\r\n if (!fetchImpl) {\r\n throw new Error('[Prompteryx SDK] Local target needs a global fetch (Node 18+ / browser).')\r\n }\r\n const base = (opts.runnerUrl || 'http://localhost:61337').replace(/\\/$/, '')\r\n const sessionId = `sdk-local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\r\n const goal = opts.startUrl\r\n ? `First, go to ${opts.startUrl}. Then: ${opts.goal}`\r\n : opts.goal\r\n\r\n const post = async (path: string, body: unknown) => {\r\n let r: Response\r\n try {\r\n r = await fetchImpl(`${base}${path}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (e) {\r\n throw new Error(\r\n `[Prompteryx SDK] Couldn't reach the desktop app at ${base}. ` +\r\n `Make sure the Prompteryx desktop app is running and signed in on this machine. (${(e as Error).message})`,\r\n )\r\n }\r\n if (!r.ok) {\r\n let msg = `${path} failed (${r.status})`\r\n try { const j = await r.json(); if ((j as any)?.error) msg = (j as any).error } catch { /* */ }\r\n throw new Error(`[Prompteryx SDK] ${msg}`)\r\n }\r\n return r.json().catch(() => ({}))\r\n }\r\n\r\n // 1) Open the local Chrome + create the agent session.\r\n await post('/launch-gemini-browser', {\r\n sessionId,\r\n profileId: (opts.session as any)?.profileId,\r\n enableRecording: false,\r\n })\r\n\r\n // 2) Start the agent loop with the same knobs as the cloud path.\r\n await post('/local-agent/start', {\r\n sessionId,\r\n task: goal,\r\n model: opts.model,\r\n aiVision: opts.aiVision, // preset slug — resolved app-side\r\n maxTurns: opts.maxSteps,\r\n maxCredits: opts.maxCredits,\r\n costSaving: (opts.passthrough as any)?.costSaving === true,\r\n costSavingMaxBatch: (opts.passthrough as any)?.costSavingMaxBatch,\r\n })\r\n\r\n // 3) Poll state until terminal (or the SDK timeout).\r\n const deadline = Date.now() + (opts.timeoutMs ?? 10 * 60_000)\r\n const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms))\r\n let state: any = null\r\n while (Date.now() < deadline) {\r\n await sleep(1200)\r\n const r = await fetchImpl(`${base}/local-agent/state/${encodeURIComponent(sessionId)}`).catch(() => null)\r\n if (!r || !r.ok) continue\r\n state = await r.json().catch(() => null)\r\n if (!state || state.found === false) continue\r\n if (state.status && state.status !== 'running') break\r\n }\r\n\r\n const status = state?.status\r\n return {\r\n success: status === 'done' || status === 'awaiting_input',\r\n finalAnswer: state?.answer,\r\n steps: (state?.steps || []).map((s: any, i: number) => ({\r\n step: i + 1,\r\n action: s?.name || s?.action?.name || 'action',\r\n result: s?.args || s?.action?.args,\r\n })),\r\n usage: {\r\n aiCredits: Math.max(0, Math.round((state?.costUSD || 0) / 0.01)),\r\n tokensIn: state?.inTokens || 0,\r\n tokensOut: state?.outTokens || 0,\r\n costUSD: state?.costUSD || 0,\r\n turns: state?.turns || 0,\r\n },\r\n }\r\n }\r\n\r\n /**\r\n * Ask a running async job to stop at its next step boundary\r\n * (`POST { jobId, mode: 'stop' }`). Use it to wind down a job you\r\n * started via the raw API (or a run you're abandoning) instead of\r\n * leaving it stepping against a dead browser session until the step\r\n * cap — an abandoned job burns a model call + timeout per step.\r\n *\r\n * ```ts\r\n * const { stopRequested, status } = await px.autopilot.stop(jobId)\r\n * ```\r\n */\r\n async stop(jobId: string): Promise<{ jobId: string; stopRequested: boolean; status?: string }> {\r\n const env = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 30_000,\r\n body: { jobId, mode: 'stop' },\r\n })\r\n const d = env?.data ?? env ?? {}\r\n return { jobId: d.jobId ?? jobId, stopRequested: d.stopRequested === true, status: d.status }\r\n }\r\n\r\n /**\r\n * Run the autopilot over the keep-alive stream endpoint and yield the\r\n * step trace. Ends with a `{ step: -1, action: 'done' }` sentinel whose\r\n * `result` field carries the full `AutopilotRunResult`.\r\n *\r\n * ```ts\r\n * for await (const step of px.autopilot.stream({ goal: 'Buy a ticket' })) {\r\n * console.log('Step', step.step, '→', step.action)\r\n * if (step.action === 'done') break\r\n * }\r\n * ```\r\n *\r\n * PROTOCOL (matches /api/v1/ai-browser/execute-stream — it is NOT SSE):\r\n * the server emits a 1-space heartbeat every 15s while the run executes,\r\n * then the complete execute-route JSON as the final chunk, i.e. the body\r\n * is `<heartbeats>\\n<json>`. The heartbeats exist to defeat the ~300s\r\n * infra idle timeout on long synchronous runs; per-step live events are\r\n * not available on this route, so steps arrive together when the run\r\n * finishes. Prefer `run()` unless you specifically want the keep-alive\r\n * transport for a long single-request run.\r\n */\r\n async *stream(\r\n opts: AutopilotRunOptions & { signal?: AbortSignal },\r\n ): AsyncGenerator<AutopilotStep, void, void> {\r\n if (opts.target === 'local') {\r\n // Local streaming isn't wired — the local runner has no step emitter.\r\n // Use the blocking `run({ target: 'local' })` (its result includes\r\n // the full step list) for local Chrome today.\r\n throw new Error(\r\n '[Prompteryx SDK] Streaming is cloud-only. For local Chrome use ' +\r\n 'autopilot.run({ target: \"local\" }) — its result contains all steps.',\r\n )\r\n }\r\n const res = await this.http.rawRequest('/api/v1/ai-browser/execute-stream', {\r\n method: 'POST',\r\n timeoutMs: opts.timeoutMs ?? 15 * 60_000,\r\n body: this.cloudTaskBody(opts),\r\n signal: opts.signal,\r\n })\r\n // Accumulate the whole body: heartbeat spaces, then '\\n' + the JSON.\r\n let text = ''\r\n if (res.body) {\r\n const reader = res.body.getReader()\r\n const decoder = new TextDecoder()\r\n while (true) {\r\n const { value, done } = await reader.read()\r\n if (done) break\r\n if (value) text += decoder.decode(value, { stream: true })\r\n }\r\n text += decoder.decode()\r\n } else {\r\n text = await res.text()\r\n }\r\n // Strip the heartbeats — the JSON is always the last (and only) content.\r\n const payload = text.trim()\r\n let parsed: any\r\n try {\r\n parsed = JSON.parse(payload)\r\n } catch {\r\n throw new ParseError('execute-stream returned a non-JSON payload', {\r\n raw: payload.slice(0, 500),\r\n })\r\n }\r\n if (parsed && parsed.success === false) {\r\n const msg = parsed?.error?.message ?? parsed?.error ?? 'AI Browser Agent run failed'\r\n throw new PrompteryxError(String(msg), { code: parsed?.error?.code, raw: parsed })\r\n }\r\n const result = this.mapResult(parsed?.data ?? parsed)\r\n for (const step of result.steps) yield step\r\n yield { step: -1, action: 'done', result }\r\n }\r\n}\r\n","/**\n * `px.cloudBrowser.*` — sessions, one-shot fetch, search.\n *\n * The most-used path: `sessions.create()` returns a `connectUrl` you\n * pass to Playwright's `chromium.connectOverCDP(connectUrl)`. Your own\n * Playwright code drives the browser from there; we handle the\n * infrastructure (residential proxies, recording, persistence).\n *\n * ⚠️ KEY FAMILY (verified live 2026-09-03): every /api/v1/cloud-browser/*\n * route authenticates with a CLOUD BROWSER key (`pcb_live_…`) sent as\n * `x-api-key` — NOT the platform `px_live_…` Bearer key the rest of the\n * SDK uses. Pass it as `new Prompteryx({ apiKey, cloudBrowserKey })`;\n * calls throw a descriptive AuthError when it's missing.\n */\n\nimport type { HttpClient, RequestOptions } from '../client'\nimport { AuthError } from '../errors'\nimport type {\n CloudFetchOptions,\n CloudFetchResult,\n CloudSearchResult,\n CloudSession,\n CloudSessionSummary,\n CreateSessionOptions,\n} from '../types'\n\nconst MISSING_CB_KEY_MESSAGE =\n 'px.cloudBrowser.* uses a Cloud Browser API key (pcb_live_…), which is a ' +\n 'separate key family from the platform px_live_… key. Create one under ' +\n 'Cloud Platform → API Keys and pass it as ' +\n 'new Prompteryx({ apiKey, cloudBrowserKey }).'\n\n/** Sub-resource: cloud browser sessions. */\nexport class SessionsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Headers for the pcb_live_ key family (throws a clear error if absent). */\n private cbAuth(): Record<string, string> {\n const key = this.http.cloudBrowserKey\n if (!key) throw new AuthError(MISSING_CB_KEY_MESSAGE)\n return { 'x-api-key': key }\n }\n\n private cbRequest<T>(path: string, opts: RequestOptions = {}): Promise<T> {\n return this.http.request<T>(path, {\n ...opts,\n headers: { ...this.cbAuth(), ...(opts.headers ?? {}) },\n })\n }\n\n /** Create a new browser session.\n *\n * Cloud (default):\n * ```ts\n * const s = await px.cloudBrowser.sessions.create()\n * // s.connectUrl → Prompteryx Cloud CDP. Bills cloud-browser minutes.\n * ```\n *\n * Local — uses YOUR machine's Chrome via the Prompteryx plugin +\n * Electron runner. ZERO cloud-browser minutes. Requires the plugin\n * to be running on the same machine as the SDK consumer; the call\n * short-circuits to localhost and never reaches the API.\n * ```ts\n * const s = await px.cloudBrowser.sessions.create({ target: 'local' })\n * // s.connectUrl → http://localhost:9222 (your Chrome's debug port)\n * ```\n *\n * When `target: 'local'` is set, cloud-only fields (recordSession,\n * proxy, profileId) are ignored — you're driving your own Chrome\n * with whatever cookies/extensions you've already installed.\n */\n async create(opts: CreateSessionOptions = {}): Promise<CloudSession> {\n if (opts.target === 'local') {\n // Local mode short-circuit. We don't hit the API at all — the\n // session is just a thin wrapper over the user's local Chrome's\n // CDP endpoint (managed by the Prompteryx plugin). Saves cloud\n // minutes AND avoids a round-trip. Failure to connect is the\n // consumer's problem at .connectOverCDP() time.\n const localCdp = 'http://127.0.0.1:9222'\n const localId = `local_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`\n return {\n id: localId,\n connectUrl: localCdp,\n status: 'active',\n startedAt: new Date().toISOString(),\n recordSession: false,\n }\n }\n // Wire names match the route (proxy/country), while the SDK options keep\n // the friendlier useProxy/proxyLocation spelling.\n return this.cbRequest<CloudSession>('/api/v1/cloud-browser/sessions', {\n method: 'POST',\n body: {\n recordSession: opts.recordSession,\n captureDownloads: opts.captureDownloads,\n extensions: opts.extensions,\n proxy: opts.useProxy,\n country: opts.proxyLocation,\n sessionTimeoutMinutes: opts.sessionTimeoutMinutes,\n profileId: opts.profileId,\n persistContext: opts.persistContext,\n viewport: opts.viewport,\n ...(opts.passthrough || {}),\n },\n })\n }\n\n /** Retrieve a session's history record (status/duration/recording flag).\n * Note: this is durable history, not a live handle — it has no\n * `connectUrl`. Keep the `create()` response for connecting. */\n async get(sessionId: string): Promise<CloudSessionSummary> {\n return this.cbRequest(\n `/api/v1/cloud-browser/sessions/${encodeURIComponent(sessionId)}`,\n )\n }\n\n /** List recent sessions for your account, newest first. */\n async list(opts: { limit?: number } = {}): Promise<CloudSessionSummary[]> {\n const res = await this.cbRequest<{ sessions: CloudSessionSummary[] }>(\n '/api/v1/cloud-browser/sessions',\n { query: { limit: opts.limit } },\n )\n return res.sessions ?? []\n }\n\n /** Close a session, finalising the recording (if any) + releasing the\n * cloud-browser slot. Idempotent. No-op for local sessions\n * (target: 'local') — those don't have a slot to release. */\n async close(sessionId: string): Promise<{ ok: boolean; proxyMB?: number }> {\n // Local sessions are pure client-side handles — nothing to release.\n if (sessionId.startsWith('local_')) return { ok: true }\n return this.cbRequest(\n `/api/v1/cloud-browser/sessions/${encodeURIComponent(sessionId)}`,\n { method: 'DELETE' },\n )\n }\n}\n\nexport class CloudBrowserResource {\n readonly sessions: SessionsResource\n\n constructor(private readonly http: HttpClient) {\n this.sessions = new SessionsResource(http)\n }\n\n private cbAuth(): Record<string, string> {\n const key = this.http.cloudBrowserKey\n if (!key) throw new AuthError(MISSING_CB_KEY_MESSAGE)\n return { 'x-api-key': key }\n }\n\n /**\n * One-shot fetch through the cloud browser. Spins up a short-lived\n * session, loads the page in real Chromium (so JS-rendered sites work),\n * extracts the content, and tears down. Use this when you only need ONE\n * page and don't want to manage Playwright yourself.\n *\n * ```ts\n * const page = await px.cloudBrowser.fetch({\n * url: 'https://example.com/pricing',\n * format: 'markdown', // 'text' (default) | 'markdown' | 'html' | 'links'\n * waitForSelector: '.pricing-table', // for JS-rendered content\n * selectors: ['.pricing-table .plan'], // deterministic CSS extraction\n * })\n * // page.content, page.extracted, page.title, page.finalUrl …\n * ```\n */\n async fetch(opts: CloudFetchOptions): Promise<CloudFetchResult> {\n return this.http.request('/api/v1/cloud-browser/fetch', {\n method: 'POST',\n body: opts,\n headers: this.cbAuth(),\n timeoutMs: Math.max(90_000, (opts.timeoutMs ?? 30_000) + 30_000),\n })\n }\n\n /**\n * Search the web through the cloud browser and get structured results\n * (title/url/snippet). Runs the query against DuckDuckGo's server-rendered\n * HTML endpoint in a real browser — there is no engine choice today.\n */\n async search(opts: {\n query: string\n /** Max results, 1–25. Default 10. */\n limit?: number\n /** Route through a residential proxy. */\n proxy?: boolean\n /** Proxy exit country (with `proxy: true`), e.g. 'us'. */\n country?: string\n }): Promise<CloudSearchResult[]> {\n const res = await this.http.request<{ query: string; results: CloudSearchResult[] }>(\n '/api/v1/cloud-browser/search',\n { method: 'POST', body: opts, headers: this.cbAuth(), timeoutMs: 90_000 },\n )\n return res.results ?? []\n }\n}\n","/**\r\n * `px.executions.*` — status, logs (polled OR streamed), wait.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport { TimeoutError } from '../errors'\r\nimport type { ExecutionLogEvent, ExecutionRecord, ExecutionStatus } from '../types'\r\n\r\nconst TERMINAL_STATES: ExecutionStatus[] = [\r\n 'completed',\r\n 'failed',\r\n 'cancelled',\r\n 'timed_out',\r\n]\r\n\r\nexport class ExecutionsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Get current execution record. */\r\n async get(executionId: string): Promise<ExecutionRecord> {\r\n return this.http.request(`/api/v1/executions/${encodeURIComponent(executionId)}`)\r\n }\r\n\r\n /**\r\n * Block until the execution reaches a terminal state. Polls every\r\n * `pollIntervalMs` (default 2s) until it's `completed`/`failed`/\r\n * `cancelled`/`timed_out`, OR until `timeoutMs` elapses (default 5min).\r\n *\r\n * Throws `TimeoutError` on timeout; otherwise returns the final record.\r\n */\r\n async wait(\r\n executionId: string,\r\n opts: { timeoutMs?: number; pollIntervalMs?: number; signal?: AbortSignal } = {},\r\n ): Promise<ExecutionRecord> {\r\n const timeoutMs = opts.timeoutMs ?? 5 * 60_000\r\n const pollIntervalMs = opts.pollIntervalMs ?? 2_000\r\n const deadline = Date.now() + timeoutMs\r\n while (true) {\r\n if (opts.signal?.aborted) throw new TimeoutError(`Wait cancelled for ${executionId}`)\r\n const exec = await this.get(executionId)\r\n if (TERMINAL_STATES.includes(exec.status)) return exec\r\n if (Date.now() > deadline) {\r\n throw new TimeoutError(`Execution ${executionId} did not finish within ${timeoutMs}ms`)\r\n }\r\n await new Promise((r) => setTimeout(r, pollIntervalMs))\r\n }\r\n }\r\n\r\n /**\r\n * Get the logs for a finished (or in-progress) execution as a one-shot\r\n * fetch. For real-time streaming use `stream(executionId)` instead.\r\n */\r\n async logs(executionId: string): Promise<ExecutionLogEvent[]> {\r\n const res = await this.http.request<{ logs: ExecutionLogEvent[] }>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/logs`,\r\n )\r\n return res.logs ?? []\r\n }\r\n\r\n /**\r\n * Stream log events as they arrive. Async iterable:\r\n *\r\n * for await (const ev of px.executions.stream(execId)) {\r\n * console.log(ev.message)\r\n * if (ev.type === 'done') break\r\n * }\r\n */\r\n async *stream(\r\n executionId: string,\r\n opts: { signal?: AbortSignal } = {},\r\n ): AsyncGenerator<ExecutionLogEvent, void, void> {\r\n yield* this.http.streamSse<ExecutionLogEvent>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/logs/stream`,\r\n { signal: opts.signal },\r\n )\r\n }\r\n\r\n /** Get a single node's output from a finished execution. */\r\n async getNodeOutput(executionId: string, nodeId: string): Promise<unknown> {\r\n return this.http.request(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/nodes/${encodeURIComponent(nodeId)}/output`,\r\n )\r\n }\r\n}\r\n","/**\r\n * `px.profiles.*` — Chrome profile management.\r\n *\r\n * Profiles are persistent browser identities — they store cookies,\r\n * local storage, extensions, and login state across sessions. Two\r\n * kinds:\r\n * • `cloud` — lives on the Prompteryx cloud browser infrastructure.\r\n * Accessible from any device, but starts logged out (you have to\r\n * log in once after creating).\r\n * • `local` — runs on the user's own Chrome via the Prompteryx\r\n * plugin. Reuses whatever Chrome profile the user is already\r\n * signed into (Gmail, banking, internal SSO). Cloud-only\r\n * workloads can't access this.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { ProfileSummary } from '../types'\r\n\r\nexport class ProfilesResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { kind?: 'cloud' | 'local' } = {}): Promise<ProfileSummary[]> {\r\n const res = await this.http.request<{ profiles: ProfileSummary[] }>(\r\n '/api/v1/profiles',\r\n { query: { kind: opts.kind } },\r\n )\r\n return res.profiles ?? []\r\n }\r\n\r\n async get(profileId: string): Promise<ProfileSummary> {\r\n return this.http.request(`/api/v1/profiles/${encodeURIComponent(profileId)}`)\r\n }\r\n\r\n /** Create a new CLOUD profile. Local profiles are managed by the\r\n * plugin and cannot be created via the API. */\r\n async create(opts: { name: string }): Promise<ProfileSummary> {\r\n return this.http.request('/api/v1/profiles', {\r\n method: 'POST',\r\n body: { name: opts.name, kind: 'cloud' },\r\n })\r\n }\r\n\r\n async delete(profileId: string): Promise<{ ok: true }> {\r\n return this.http.request(`/api/v1/profiles/${encodeURIComponent(profileId)}`, {\r\n method: 'DELETE',\r\n })\r\n }\r\n}\r\n","/**\r\n * `px.schedules.*` — server-side workflow scheduling.\r\n *\r\n * Set a workflow to run on cron / interval; the platform's Cloud\r\n * Scheduler will fire it on schedule even when no client is connected.\r\n * Wraps the same scheduling primitive the Visual Studio \"Active\"\r\n * toggle uses.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { CreateScheduleOptions, ScheduleSummary } from '../types'\r\n\r\nexport class SchedulesResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { active?: boolean; workflowId?: string } = {}): Promise<ScheduleSummary[]> {\r\n const res = await this.http.request<{ schedules: ScheduleSummary[] }>(\r\n '/api/v1/schedules',\r\n { query: { active: opts.active, workflowId: opts.workflowId } },\r\n )\r\n return res.schedules ?? []\r\n }\r\n\r\n async get(scheduleId: string): Promise<ScheduleSummary> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`)\r\n }\r\n\r\n /** Create a new schedule. Returns the created record. */\r\n async create(opts: CreateScheduleOptions): Promise<ScheduleSummary> {\r\n return this.http.request('/api/v1/schedules', {\r\n method: 'POST',\r\n body: opts,\r\n })\r\n }\r\n\r\n /** Pause / resume / change cron / timezone. */\r\n async update(scheduleId: string, patch: Partial<CreateScheduleOptions> & { active?: boolean }): Promise<ScheduleSummary> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`, {\r\n method: 'PATCH',\r\n body: patch,\r\n })\r\n }\r\n\r\n async delete(scheduleId: string): Promise<{ ok: true }> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`, {\r\n method: 'DELETE',\r\n })\r\n }\r\n}\r\n","/**\r\n * `px.subscription.*` — plan + balance + usage telemetry.\r\n *\r\n * Programmatic access to the same numbers the in-app `/subscription`\r\n * and `/cloud-platform/plans` pages display. Use this to:\r\n * • Check the user's remaining AI Credits before kicking off a\r\n * long workflow.\r\n * • Read monthly execution counts for your own dashboards.\r\n * • Detect a plan downgrade and react in your code.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { SubscriptionStatus } from '../types'\r\n\r\nexport class SubscriptionResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Get the current plan + balances + usage. */\r\n async get(): Promise<SubscriptionStatus> {\r\n return this.http.request('/api/v1/subscription')\r\n }\r\n\r\n // NOT SHIPPED (2026-09-03, v0.4.0): usage() was removed — the route it\r\n // targeted (/api/v1/subscription/usage) does not exist on the live API\r\n // (the only usage route is /api/v1/usage, with a different shape).\r\n // Re-add once a real time-series endpoint ships.\r\n}\r\n","/**\r\n * `px.workflows.*` — Visual Studio workflows.\r\n *\r\n * Trigger workflows you (or anyone you share with) built in Visual\r\n * Studio. Workflows are first-class platform objects: they have\r\n * permanent IDs, can be scheduled, shared, templated, and edited\r\n * visually. Triggering one via the SDK is fully equivalent to\r\n * pressing Run in the UI — same runtime, same node executor, same\r\n * billing path.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport { TimeoutError } from '../errors'\r\nimport type {\r\n ExecutionRecord,\r\n RunWorkflowOptions,\r\n RunWorkflowResult,\r\n WorkflowSummary,\r\n} from '../types'\r\n\r\nexport class WorkflowsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { limit?: number; search?: string; tag?: string } = {}): Promise<WorkflowSummary[]> {\r\n const res = await this.http.request<{ workflows: WorkflowSummary[] }>(\r\n '/api/v1/workflows',\r\n { query: { limit: opts.limit, q: opts.search, tag: opts.tag } },\r\n )\r\n return res.workflows ?? []\r\n }\r\n\r\n async get(workflowId: string): Promise<WorkflowSummary & { nodes?: unknown[] }> {\r\n return this.http.request(`/api/v1/workflows/${encodeURIComponent(workflowId)}`)\r\n }\r\n\r\n /**\r\n * Trigger a workflow. Returns immediately with `executionId`. Use\r\n * `px.executions.wait(id)` to block until completion or\r\n * `px.executions.stream(id)` to follow log events live.\r\n *\r\n * The `execution` options override the workflow's saved settings\r\n * for this one run — you don't have to edit the workflow in VS to\r\n * change the proxy, region, profile, etc.\r\n */\r\n async run(workflowId: string, opts: RunWorkflowOptions = {}): Promise<RunWorkflowResult> {\r\n return this.http.request<RunWorkflowResult>(\r\n `/api/v1/workflows/${encodeURIComponent(workflowId)}/execute`,\r\n {\r\n method: 'POST',\r\n body: {\r\n variables: opts.input,\r\n executionOptions: opts.execution,\r\n },\r\n },\r\n )\r\n }\r\n\r\n /**\r\n * Run + block. Returns the final ExecutionRecord. Throws\r\n * `TimeoutError` if the run takes longer than `timeoutMs`\r\n * (default 5 minutes).\r\n */\r\n async runAndWait(\r\n workflowId: string,\r\n opts: RunWorkflowOptions & { timeoutMs?: number; pollIntervalMs?: number } = {},\r\n ): Promise<ExecutionRecord> {\r\n const started = await this.run(workflowId, opts)\r\n return this.waitInternal(started.executionId, opts.timeoutMs ?? 5 * 60_000, opts.pollIntervalMs ?? 2_000)\r\n }\r\n\r\n private async waitInternal(executionId: string, timeoutMs: number, pollIntervalMs: number): Promise<ExecutionRecord> {\r\n const deadline = Date.now() + timeoutMs\r\n while (true) {\r\n const exec = await this.http.request<ExecutionRecord>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}`,\r\n )\r\n if (['completed', 'failed', 'cancelled', 'timed_out'].includes(exec.status)) return exec\r\n if (Date.now() > deadline) {\r\n throw new TimeoutError(`Execution ${executionId} did not finish within ${timeoutMs}ms`)\r\n }\r\n await new Promise((r) => setTimeout(r, pollIntervalMs))\r\n }\r\n }\r\n}\r\n","/**\n * Browser-agent model catalog — the ids `px.autopilot.run({ model })` accepts.\n *\n * ⚠️ MUST MIRROR `components/unified-chat-v2/browser-models.ts`\n * `V2_BROWSER_MODELS` in the platform repo — that file is the canonical\n * catalog the server validates against (an unknown id hard-400s with\n * `UNSUPPORTED_MODEL` under strict validation). When that list changes,\n * regenerate this one. Last synced: 2026-09-03 — 32 ids.\n *\n * The type stays open (`| (string & {})`) so a model the server adds\n * tomorrow works without an SDK release, while editors still autocomplete\n * the known catalog.\n */\n\nexport const AUTOPILOT_MODELS = [\n // ── Standard (Gemini native Computer Use) ────────────────────────────────\n 'gemini-3.5-flash', // Recommended — fast and cheap. THE DEFAULT.\n 'gemini-3.7-flash', // Newest GA Flash — Google-recommended for computer use\n 'gemini-3.6-flash', // Newest Flash (Computer Use preview)\n 'gemini-default', // Gemini 2.5 Computer Use (legacy)\n // ── Experimental (Gemini) ────────────────────────────────────────────────\n 'gemini-3-flash-preview',\n 'gemini-3.5-flash-lite',\n // Harness aliases — resolved server-side to an underlying brain + prompt.\n 'model-a',\n 'model-a1',\n 'model-b',\n 'model-j',\n 'model-k',\n 'model-k37',\n // ── Anthropic / OpenAI native Computer Use ───────────────────────────────\n 'claude-sonnet-4-6',\n 'claude-opus-4-8',\n 'gpt-5.6-terra',\n 'gpt-5.6-sol',\n 'gpt-5.5',\n // ── Generic Vision Loop (standard chat models on screenshots) ────────────\n 'claude-fable-5-vision',\n 'claude-opus-5-vision',\n 'claude-sonnet-5-vision',\n 'claude-sonnet-4-6-vision',\n 'gpt-5.6-luna-vision',\n 'gpt-5.4-vision',\n 'gpt-4o-vision',\n 'kimi-k3-vision',\n // ── Experimental server-side harness engines ─────────────────────────────\n 'modelc',\n 'model-d',\n 'model-d1',\n 'model-e',\n 'model-f',\n 'model-h',\n 'model-i',\n] as const\n\n/** A model id from the known catalog. */\nexport type AutopilotModelId = (typeof AUTOPILOT_MODELS)[number]\n\n/** Open union: known ids autocomplete, forward-compatible strings still pass. */\nexport type AutopilotModel = AutopilotModelId | (string & {})\n\n/** The platform default when `model` is omitted. */\nexport const DEFAULT_AUTOPILOT_MODEL = 'gemini-3.5-flash'\n","/**\n * @prompteryx/sdk\n *\n * Official TypeScript SDK for the Prompteryx platform.\n *\n * Two AI surfaces:\n *\n * • **Copilot** — helps with ONE step you describe in plain English.\n * Your code drives Playwright; copilot just figures out the\n * selector to click / the data to pull / what's on the page.\n *\n * ```ts\n * await px.copilot.do(page, 'click the Sign up button')\n * const product = await px.copilot.read(page, productSchema)\n * const actions = await px.copilot.scan(page, 'checkout buttons')\n * ```\n *\n * • **Autopilot** — runs an autonomous multi-step task end-to-end\n * with no per-action involvement from you.\n *\n * ```ts\n * const result = await px.autopilot.run({\n * goal: 'Apply for the Senior Engineer role at OpenAI',\n * saveAsWorkflow: true, // permanent zero-AI-cost replay\n * })\n * ```\n *\n * Plus workflows, executions, cloud browser sessions / fetch / search,\n * schedules, profiles, and subscription telemetry.\n *\n * TWO KEY FAMILIES:\n * • `apiKey` (`px_live_…`) — the platform API key; sent as\n * `Authorization: Bearer`. 60 requests/minute, 10,000/day.\n * • `cloudBrowserKey` (`pcb_live_…`) — the Cloud Browser key; required\n * only for `px.cloudBrowser.*`, sent as `x-api-key`.\n *\n * Quick start:\n *\n * ```ts\n * import { Prompteryx } from '@prompteryx/sdk'\n * import { chromium } from 'playwright-core'\n *\n * const px = new Prompteryx({\n * apiKey: process.env.PROMPTERYX_API_KEY!, // px_live_…\n * cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY, // pcb_live_…\n * })\n *\n * // 1. Cloud browser session\n * const session = await px.cloudBrowser.sessions.create({\n * useProxy: true, proxyLocation: 'us',\n * })\n * const browser = await chromium.connectOverCDP(session.connectUrl)\n * const page = browser.contexts()[0].pages()[0]\n *\n * // 2. Copilot on top of Playwright\n * await page.goto('https://news.ycombinator.com')\n * const top = await px.copilot.read(page, z.object({\n * stories: z.array(z.object({ title: z.string(), url: z.string() })),\n * }))\n * ```\n *\n * See PROMPTERYX_SDK.md in docs/ for the full design + reference.\n */\n\nimport { HttpClient } from './client'\nimport { AutopilotResource } from './resources/autopilot'\nimport { CloudBrowserResource } from './resources/cloudBrowser'\nimport { ExecutionsResource } from './resources/executions'\nimport { ProfilesResource } from './resources/profiles'\nimport { SchedulesResource } from './resources/schedules'\nimport { SubscriptionResource } from './resources/subscription'\nimport { WorkflowsResource } from './resources/workflows'\nimport { CopilotHelpers, type PageLike } from './page'\nimport type {\n CopilotDoResult,\n DiscoveredAction,\n PrompteryxClientOptions,\n} from './types'\n\n// Public re-exports\nexport * from './errors'\nexport * from './types'\nexport * from './models'\nexport type { PageLike }\n\n// v0.4.0 (2026-09-03): the connectHub, customNodes, templates, apiKeys and\n// recordings namespaces plus subscription.usage() were REMOVED from the\n// public surface — the routes they target don't exist on the live API (or,\n// for api-keys, can never accept API-key auth). The source files remain in\n// src/resources/ with dated NOT-SHIPPED headers for a future release.\n\n/**\n * Copilot surface — bundles the three on-page primitives behind a\n * single namespace so calling code reads as\n * `px.copilot.do(...)` / `px.copilot.read(...)` / `px.copilot.scan(...)`.\n * Used internally by the Prompteryx class.\n */\nclass Copilot {\n constructor(private readonly helpers: CopilotHelpers) {}\n /** Execute a natural-language action on a connected Playwright page. */\n do(page: PageLike, instruction: string, opts?: { timeout?: number }): Promise<CopilotDoResult> {\n return this.helpers.do(page, instruction, opts)\n }\n /** Pull typed data from the page (Zod schema or raw JSON Schema). */\n read<T>(page: PageLike, schema: { parse(input: unknown): T } | { jsonSchema: unknown }): Promise<T> {\n return this.helpers.read<T>(page, schema as any)\n }\n /** Discover available actions on the page; useful pre-`do` step. */\n scan(page: PageLike, hint?: string): Promise<DiscoveredAction[]> {\n return this.helpers.scan(page, hint)\n }\n}\n\nexport class Prompteryx {\n private readonly http: HttpClient\n\n // Core resources — the verified live surface.\n public readonly workflows: WorkflowsResource\n public readonly executions: ExecutionsResource\n public readonly cloudBrowser: CloudBrowserResource\n public readonly autopilot: AutopilotResource\n public readonly copilot: Copilot\n public readonly schedules: SchedulesResource\n public readonly profiles: ProfilesResource\n public readonly subscription: SubscriptionResource\n\n constructor(opts: PrompteryxClientOptions) {\n this.http = new HttpClient(opts)\n this.workflows = new WorkflowsResource(this.http)\n this.executions = new ExecutionsResource(this.http)\n this.cloudBrowser = new CloudBrowserResource(this.http)\n this.autopilot = new AutopilotResource(this.http)\n this.copilot = new Copilot(new CopilotHelpers(this.http))\n this.schedules = new SchedulesResource(this.http)\n this.profiles = new ProfilesResource(this.http)\n this.subscription = new SubscriptionResource(this.http)\n }\n}\n\nexport default Prompteryx\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/resources/autopilot.ts","../src/resources/cloudBrowser.ts","../src/resources/executions.ts","../src/resources/profiles.ts","../src/resources/schedules.ts","../src/resources/subscription.ts","../src/resources/workflows.ts","../src/models.ts","../src/index.ts"],"sourcesContent":["/**\r\n * HTTP client for the Prompteryx SDK.\r\n *\r\n * Thin layer over `fetch` that adds:\r\n * - Bearer auth from the configured API key\r\n * - JSON serialisation + content-type\r\n * - Status-to-typed-error mapping (see errors.ts)\r\n * - Configurable timeout via AbortController\r\n * - Bounded retry for idempotent ops on 5xx / network errors\r\n * - Optional SSE streaming for execution logs / agent traces\r\n *\r\n * Anything that needs raw `Response` (e.g. downloading a recording\r\n * binary) can use `rawRequest()`. Everything else should use\r\n * `request<T>()` which returns the parsed JSON body typed as T.\r\n */\r\n\r\nimport {\r\n AuthError,\r\n NetworkError,\r\n NotFoundError,\r\n ParseError,\r\n PrompteryxError,\r\n QuotaError,\r\n RateLimitError,\r\n ServerError,\r\n TimeoutError,\r\n ValidationError,\r\n} from './errors'\r\nimport type { PrompteryxClientOptions } from './types'\r\n\r\nconst DEFAULT_BASE_URL = 'https://www.prompteryx.ai'\r\nconst DEFAULT_TIMEOUT_MS = 60_000\r\nconst DEFAULT_MAX_RETRIES = 2\r\n\r\nexport interface RequestOptions {\r\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'\r\n /** Object that will be JSON.stringified into the body. Skip for GET/DELETE. */\r\n body?: unknown\r\n /** Extra headers merged into the defaults. */\r\n headers?: Record<string, string>\r\n /** Override the client default timeout for this single call. */\r\n timeoutMs?: number\r\n /** Whether this op is safe to retry on transient failure. Defaults\r\n * based on method: GET = yes, others = no. The caller can force\r\n * retry for idempotent POSTs (e.g. a poll loop). */\r\n retry?: boolean\r\n /** Query string params (URI-encoded automatically). */\r\n query?: Record<string, string | number | boolean | undefined | null>\r\n /** Optional AbortSignal for caller-side cancellation. */\r\n signal?: AbortSignal\r\n}\r\n\r\n/**\r\n * Every /api/v1 route answers `{ success, data, meta }`. Resources read the\r\n * payload directly (`res.workflows`, `res.apps`, …), so unwrap the envelope\r\n * here. Before 0.4.1 the raw envelope was returned and every list() came\r\n * back empty. Non-envelope bodies (webhooks, raw payloads) pass through.\r\n */\r\nfunction unwrapEnvelope(parsed: unknown): unknown {\r\n if (\r\n parsed &&\r\n typeof parsed === 'object' &&\r\n !Array.isArray(parsed) &&\r\n 'success' in parsed &&\r\n 'data' in parsed &&\r\n typeof (parsed as { success: unknown }).success === 'boolean'\r\n ) {\r\n return (parsed as { data: unknown }).data\r\n }\r\n return parsed\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n /** Optional Cloud Browser key (`pcb_live_…`) — a separate key family used\r\n * only by the /api/v1/cloud-browser/* endpoints (sent as `x-api-key`). */\r\n public readonly cloudBrowserKey?: string\r\n private readonly baseUrl: string\r\n private readonly timeoutMs: number\r\n private readonly maxRetries: number\r\n private readonly defaultHeaders: Record<string, string>\r\n private readonly fetchImpl: typeof fetch\r\n\r\n constructor(opts: PrompteryxClientOptions) {\r\n if (!opts.apiKey) {\r\n throw new PrompteryxError('apiKey is required to construct a Prompteryx client')\r\n }\r\n this.apiKey = opts.apiKey\r\n this.cloudBrowserKey = opts.cloudBrowserKey\r\n this.baseUrl = (opts.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '')\r\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\r\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\r\n this.defaultHeaders = opts.defaultHeaders ?? {}\r\n const f = opts.fetch ?? globalThis.fetch\r\n if (!f) {\r\n throw new PrompteryxError(\r\n 'No fetch implementation found. Provide options.fetch or run on a runtime with global fetch (Node 18+, browser, Cloudflare Workers).',\r\n )\r\n }\r\n // Bind so `this` doesn't get lost on assignment.\r\n this.fetchImpl = f.bind(globalThis)\r\n }\r\n\r\n /** Returns the JSON-parsed body typed as T. Throws typed errors on non-2xx. */\r\n async request<T = unknown>(path: string, opts: RequestOptions = {}): Promise<T> {\r\n const res = await this.rawRequest(path, opts)\r\n const text = await res.text()\r\n if (!text) return undefined as T\r\n let parsed: unknown\r\n try {\r\n parsed = JSON.parse(text)\r\n } catch {\r\n throw new ParseError(`Failed to parse JSON response from ${path}`, {\r\n status: res.status,\r\n raw: text.slice(0, 500),\r\n })\r\n }\r\n return unwrapEnvelope(parsed) as T\r\n }\r\n\r\n /** Returns the raw Response. Throws typed errors on non-2xx, but does\r\n * not attempt to read the body. Useful for downloading binaries. */\r\n async rawRequest(path: string, opts: RequestOptions = {}): Promise<Response> {\r\n const method = opts.method ?? 'GET'\r\n const url = this.buildUrl(path, opts.query)\r\n const shouldRetry = opts.retry ?? (method === 'GET')\r\n const maxAttempts = shouldRetry ? this.maxRetries + 1 : 1\r\n let lastErr: unknown\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n const res = await this.sendOnce(url, method, opts)\r\n if (res.ok) return res\r\n // Map status → typed error. For 5xx / 429 with retries remaining,\r\n // throw a retryable subclass and try again.\r\n const err = await this.errorFromResponse(res)\r\n if (this.isRetryable(err) && attempt < maxAttempts - 1) {\r\n await this.backoff(attempt, err)\r\n lastErr = err\r\n continue\r\n }\r\n throw err\r\n } catch (e) {\r\n // Network / abort errors: treat as retryable when we have budget.\r\n if (e instanceof PrompteryxError) throw e\r\n const wrapped = this.wrapTransport(e)\r\n if (this.isRetryable(wrapped) && attempt < maxAttempts - 1) {\r\n await this.backoff(attempt, wrapped)\r\n lastErr = wrapped\r\n continue\r\n }\r\n throw wrapped\r\n }\r\n }\r\n // Shouldn't reach here, but TS likes a return.\r\n throw lastErr ?? new PrompteryxError('Unknown error after retries exhausted')\r\n }\r\n\r\n /**\r\n * Stream a Server-Sent Events response line-by-line as JSON-parsed\r\n * payloads. Yields each event's `data:` payload parsed as JSON. The\r\n * caller is responsible for breaking the loop / cancelling the\r\n * AbortSignal when done.\r\n */\r\n async *streamSse<T = unknown>(path: string, opts: RequestOptions = {}): AsyncGenerator<T, void, void> {\r\n const res = await this.rawRequest(path, {\r\n ...opts,\r\n headers: { ...opts.headers, Accept: 'text/event-stream' },\r\n })\r\n if (!res.body) return\r\n const reader = res.body.getReader()\r\n const decoder = new TextDecoder()\r\n let buf = ''\r\n while (true) {\r\n const { value, done } = await reader.read()\r\n if (done) break\r\n buf += decoder.decode(value, { stream: true })\r\n // SSE events separated by blank line. Each event has one or more\r\n // `data: ` lines we concatenate.\r\n let idx\r\n while ((idx = buf.indexOf('\\n\\n')) !== -1) {\r\n const raw = buf.slice(0, idx)\r\n buf = buf.slice(idx + 2)\r\n const dataLines = raw\r\n .split('\\n')\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trim())\r\n if (dataLines.length === 0) continue\r\n const payload = dataLines.join('\\n')\r\n if (!payload) continue\r\n try {\r\n yield JSON.parse(payload) as T\r\n } catch {\r\n // Skip malformed events rather than dropping the whole stream.\r\n // Real-world SSE has occasional keepalive comments + heartbeat\r\n // lines we don't want to crash on.\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ── internals ────────────────────────────────────────────────────────\r\n\r\n private async sendOnce(url: string, method: string, opts: RequestOptions): Promise<Response> {\r\n const timeoutMs = opts.timeoutMs ?? this.timeoutMs\r\n const ctl = new AbortController()\r\n const t = setTimeout(() => ctl.abort(), timeoutMs)\r\n // Combine caller signal with our timeout signal.\r\n if (opts.signal) {\r\n if (opts.signal.aborted) ctl.abort()\r\n else opts.signal.addEventListener('abort', () => ctl.abort(), { once: true })\r\n }\r\n try {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n Accept: 'application/json',\r\n ...this.defaultHeaders,\r\n ...(opts.headers ?? {}),\r\n }\r\n let body: BodyInit | undefined\r\n if (opts.body !== undefined) {\r\n headers['Content-Type'] = 'application/json'\r\n body = JSON.stringify(opts.body)\r\n }\r\n return await this.fetchImpl(url, {\r\n method,\r\n headers,\r\n body,\r\n signal: ctl.signal,\r\n })\r\n } finally {\r\n clearTimeout(t)\r\n }\r\n }\r\n\r\n private buildUrl(path: string, query?: RequestOptions['query']): string {\r\n const base = path.startsWith('http') ? path : `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\r\n if (!query) return base\r\n const params = new URLSearchParams()\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined || v === null) continue\r\n params.set(k, String(v))\r\n }\r\n const qs = params.toString()\r\n return qs ? `${base}${base.includes('?') ? '&' : '?'}${qs}` : base\r\n }\r\n\r\n private async errorFromResponse(res: Response): Promise<PrompteryxError> {\r\n let parsed: any = null\r\n try {\r\n const text = await res.text()\r\n parsed = text ? JSON.parse(text) : null\r\n } catch { /* ignore — body wasn't JSON */ }\r\n const message = parsed?.error?.message\r\n ?? parsed?.message\r\n ?? parsed?.error\r\n ?? `Request failed with ${res.status}`\r\n const code = parsed?.error?.code ?? parsed?.code\r\n const requestId = res.headers.get('x-request-id') ?? undefined\r\n const opts = { status: res.status, code, requestId, raw: parsed }\r\n switch (res.status) {\r\n case 401:\r\n case 403:\r\n return new AuthError(message, opts)\r\n case 402:\r\n return new QuotaError(message, { ...opts, resources: parsed?.error?.resources ?? parsed?.resources })\r\n case 404:\r\n return new NotFoundError(message, opts)\r\n case 422:\r\n return new ValidationError(message, opts)\r\n case 429: {\r\n const retryAfter = parseInt(res.headers.get('retry-after') ?? '0', 10)\r\n return new RateLimitError(message, { ...opts, retryAfterSeconds: Number.isFinite(retryAfter) ? retryAfter : undefined })\r\n }\r\n default:\r\n if (res.status >= 500) return new ServerError(message, opts)\r\n return new PrompteryxError(message, opts)\r\n }\r\n }\r\n\r\n private wrapTransport(e: unknown): PrompteryxError {\r\n const msg = e instanceof Error ? e.message : String(e)\r\n if (e instanceof Error && (e.name === 'AbortError' || msg.includes('aborted'))) {\r\n return new TimeoutError(`Request timed out: ${msg}`)\r\n }\r\n return new NetworkError(`Network error: ${msg}`)\r\n }\r\n\r\n private isRetryable(err: PrompteryxError): boolean {\r\n if (err instanceof ServerError) return true\r\n if (err instanceof RateLimitError) return true\r\n if (err instanceof NetworkError) return true\r\n if (err instanceof TimeoutError) return true\r\n return false\r\n }\r\n\r\n private async backoff(attempt: number, err: PrompteryxError): Promise<void> {\r\n // Honour `Retry-After` when the server provided one.\r\n const retryAfter = (err as RateLimitError).retryAfterSeconds\r\n if (retryAfter && retryAfter > 0) {\r\n return new Promise((r) => setTimeout(r, Math.min(retryAfter, 30) * 1000))\r\n }\r\n // Otherwise exponential backoff with jitter: 250ms, 500ms, 1s, 2s, ...\r\n const base = 250 * Math.pow(2, attempt)\r\n const jitter = Math.random() * 100\r\n return new Promise((r) => setTimeout(r, base + jitter))\r\n }\r\n}\r\n","/**\r\n * `px.autopilot.*` — autonomous browser agent.\r\n *\r\n * **Autopilot** is the autonomous, multi-step surface. You hand it\r\n * a goal in plain English; it drives the browser end-to-end and\r\n * returns a step-by-step trace. Counterpart to **Copilot** which\r\n * helps with one step at a time (see ../page.ts).\r\n *\r\n * Built on the existing AI Browser Agent runtime. Every option the\r\n * in-app UI exposes — model, max steps, system-prompt override,\r\n * tool restrictions, viewport, region, proxy, CAPTCHA, recording —\r\n * is available via the SDK. New options added to the runtime ride\r\n * through `passthrough` without an SDK release.\r\n *\r\n * **Action caching superpower** — set `saveAsWorkflow: true` and the\r\n * autopilot's discovered action sequence is captured as a permanent\r\n * Visual Studio workflow you can replay for free forever. The\r\n * response includes `savedWorkflowId`. Subsequent calls to\r\n * `px.workflows.run(savedWorkflowId)` cost no AI Credits and benefit\r\n * from multi-option-selector resilience to UI changes.\r\n */\r\n\r\nimport { ParseError, PrompteryxError } from '../errors'\r\nimport type { HttpClient } from '../client'\r\nimport type {\r\n AutopilotRunOptions,\r\n AutopilotRunResult,\r\n AutopilotStep,\r\n} from '../types'\r\n\r\nexport class AutopilotResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Run the autopilot. Blocks until the task finishes (success, step\r\n * limit, or error). Returns the trace plus optionally the saved\r\n * workflow id.\r\n *\r\n * ```ts\r\n * const result = await px.autopilot.run({\r\n * goal: 'Apply for the Senior Engineer role at OpenAI',\r\n * startUrl: 'https://openai.com/careers',\r\n * maxSteps: 40,\r\n * saveAsWorkflow: true, // Replay-forever, zero AI cost\r\n * session: { useProxy: true, useCaptcha: true },\r\n * })\r\n * if (result.savedWorkflowId) {\r\n * console.log('Saved as workflow:', result.savedWorkflowId)\r\n * // Run it later for free:\r\n * await px.workflows.run(result.savedWorkflowId)\r\n * }\r\n * ```\r\n */\r\n async run(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n if (opts.target === 'local') {\r\n // Local Chrome autopilot (v0.3+): drive the user's OWN Chrome via the\r\n // Prompteryx desktop app on THIS machine. Zero cloud-browser minutes.\r\n // The SDK talks directly to the local runner (localhost:61337) — the\r\n // cloud API can't reach the user's machine — so requirements are: the\r\n // desktop app RUNNING + SIGNED IN, and your code on the same machine.\r\n return this.runLocal(opts)\r\n }\r\n // Multi-agent swarm runs server-side and returns a MERGED result in one\r\n // response — keep it on the single-request path (unchanged).\r\n if (opts.agents && opts.agents > 1) {\r\n return this.runSwarm(opts)\r\n }\r\n // Single cloud agent: ASYNC start → run(poll) so a LONG task (e.g. filling a\r\n // form once per CSV row) never runs in one synchronous request — which would\r\n // exceed the infra GATEWAY timeout and hand the caller an HTML error page that\r\n // res.json() chokes on. Each request stays short; we loop until the job is done.\r\n return this.runAsync(opts)\r\n }\r\n\r\n /** The task params shared by the sync, swarm, and async request bodies. */\r\n private cloudTaskBody(opts: AutopilotRunOptions): Record<string, unknown> {\r\n return {\r\n instruction: opts.goal,\r\n startUrl: opts.startUrl,\r\n maxSteps: opts.maxSteps,\r\n maxCredits: opts.maxCredits,\r\n model: opts.model,\r\n aiVision: opts.aiVision,\r\n finalStepVision: opts.finalStepVision,\r\n outputSchema: opts.outputSchema,\r\n costSaving: opts.costSaving,\r\n costSavingMaxBatch: opts.costSavingMaxBatch,\r\n carefulBatching: opts.carefulBatching,\r\n saveAsWorkflow: opts.saveAsWorkflow,\r\n savedWorkflowName: opts.savedWorkflowName,\r\n sessionId: opts.sessionId,\r\n systemPromptOverride: opts.systemPromptOverride,\r\n allowedTools: opts.allowedTools,\r\n viewport: opts.viewport,\r\n session: opts.session,\r\n // Settings parity (2026-07-15) — mirror the AI Browser Agent settings dialog.\r\n safetyConsent: opts.safetyConsent,\r\n confirmUnclear: opts.confirmUnclear,\r\n enableContextCompression: opts.enableContextCompression,\r\n compressionThreshold: opts.compressionThreshold,\r\n enableSessionReset: opts.enableSessionReset,\r\n sessionResetThreshold: opts.sessionResetThreshold,\r\n ...opts.passthrough,\r\n }\r\n }\r\n\r\n /** Multi-agent swarm — one synchronous request; the server merges all lanes. */\r\n private async runSwarm(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const env = await this.http.request<{ data?: unknown }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: opts.timeoutMs ?? 10 * 60_000,\r\n body: {\r\n ...this.cloudTaskBody(opts),\r\n agents: opts.agents,\r\n collaborate: opts.collaborate,\r\n attachmentContext: opts.attachmentContext,\r\n maxRunCredits: opts.maxRunCredits,\r\n },\r\n })\r\n return this.mapResult(env?.data ?? env)\r\n }\r\n\r\n /**\r\n * Async single-agent run: POST { mode:'start' } to set up the job (returns a\r\n * jobId immediately), then POST { mode:'run' } in a loop — each advances the job\r\n * for up to ~230s server-side and returns the current status — until the job is\r\n * terminal or `opts.timeoutMs` elapses. No single request is long, so the gateway\r\n * timeout is never hit. Same `AutopilotRunResult` shape as before.\r\n */\r\n private async runAsync(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const timeoutMs = opts.timeoutMs ?? 10 * 60_000\r\n const deadline = Date.now() + timeoutMs\r\n const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\r\n\r\n // 1) START — SETUP only. Short request; returns { jobId, sessionId }.\r\n const startEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 60_000,\r\n body: { ...this.cloudTaskBody(opts), mode: 'start' },\r\n })\r\n const jobId: string | undefined = startEnv?.data?.jobId\r\n if (!jobId) {\r\n // Back-compat: an OLDER server without async mode ran the whole task\r\n // synchronously for mode:'start', so the response IS a full result. Return it.\r\n return this.mapResult(startEnv?.data ?? startEnv)\r\n }\r\n\r\n // 2) RUN — advance in ≤230s chunks until terminal (or the SDK timeout). The\r\n // chunk itself is the wait; a transport blip on a chunk is safe to retry.\r\n let view: any = null\r\n while (Date.now() < deadline) {\r\n const runEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 250_000,\r\n retry: true,\r\n body: { jobId, mode: 'run', maxSteps: opts.maxSteps },\r\n })\r\n view = runEnv?.data ?? null\r\n if (!view || view.terminal || view.status !== 'running') break\r\n await sleep(500)\r\n }\r\n\r\n // 3) If we bailed on the SDK timeout while still running, one status read gives\r\n // the latest known state (and triggers server finalize if it's since ended).\r\n if (view && view.status === 'running') {\r\n try {\r\n const statusEnv = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n query: { jobId },\r\n timeoutMs: 30_000,\r\n })\r\n if (statusEnv?.data) view = statusEnv.data\r\n } catch { /* keep the last view */ }\r\n }\r\n\r\n return this.mapResult(view)\r\n }\r\n\r\n /** Map an execute-endpoint payload (sync result, swarm result, or async status\r\n * view — they share finalAnswer / steps / usage / savedWorkflowId / status) into\r\n * the public AutopilotRunResult shape. */\r\n private mapResult(data: any): AutopilotRunResult {\r\n const d = data || {}\r\n const status: string | undefined = d.status\r\n const success = status === 'completed' || status === 'max_steps_reached'\r\n const steps: AutopilotStep[] = Array.isArray(d.steps)\r\n ? d.steps.map((s: any, i: number) => ({\r\n step: i + 1,\r\n action: typeof s?.action === 'string' ? s.action : (s?.action?.name || 'action'),\r\n result: s?.details ?? s?.result,\r\n }))\r\n : []\r\n return {\r\n success,\r\n finalAnswer: d.finalAnswer,\r\n steps,\r\n savedWorkflowId: d.savedWorkflowId,\r\n usage: d.usage,\r\n swarm: d.swarm,\r\n }\r\n }\r\n\r\n /**\r\n * Local Chrome autopilot — talks DIRECTLY to the Prompteryx desktop app on\r\n * this machine (localhost:61337): opens your local Chrome, runs the agent\r\n * loop there, polls until done. Same options as `run` (model, aiVision\r\n * preset, maxSteps, maxCredits, costSaving). Credits still apply; cloud\r\n * minutes do not. The tab stays open after the run for follow-ups.\r\n */\r\n private async runLocal(opts: AutopilotRunOptions): Promise<AutopilotRunResult> {\r\n const fetchImpl: typeof fetch = (globalThis as any).fetch\r\n if (!fetchImpl) {\r\n throw new Error('[Prompteryx SDK] Local target needs a global fetch (Node 18+ / browser).')\r\n }\r\n const base = (opts.runnerUrl || 'http://localhost:61337').replace(/\\/$/, '')\r\n const sessionId = `sdk-local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\r\n const goal = opts.startUrl\r\n ? `First, go to ${opts.startUrl}. Then: ${opts.goal}`\r\n : opts.goal\r\n\r\n const post = async (path: string, body: unknown) => {\r\n let r: Response\r\n try {\r\n r = await fetchImpl(`${base}${path}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (e) {\r\n throw new Error(\r\n `[Prompteryx SDK] Couldn't reach the desktop app at ${base}. ` +\r\n `Make sure the Prompteryx desktop app is running and signed in on this machine. (${(e as Error).message})`,\r\n )\r\n }\r\n if (!r.ok) {\r\n let msg = `${path} failed (${r.status})`\r\n try { const j = await r.json(); if ((j as any)?.error) msg = (j as any).error } catch { /* */ }\r\n throw new Error(`[Prompteryx SDK] ${msg}`)\r\n }\r\n return r.json().catch(() => ({}))\r\n }\r\n\r\n // 1) Open the local Chrome + create the agent session.\r\n await post('/launch-gemini-browser', {\r\n sessionId,\r\n profileId: (opts.session as any)?.profileId,\r\n enableRecording: false,\r\n })\r\n\r\n // 2) Start the agent loop with the same knobs as the cloud path.\r\n await post('/local-agent/start', {\r\n sessionId,\r\n task: goal,\r\n model: opts.model,\r\n aiVision: opts.aiVision, // preset slug — resolved app-side\r\n maxTurns: opts.maxSteps,\r\n maxCredits: opts.maxCredits,\r\n costSaving: (opts.passthrough as any)?.costSaving === true,\r\n costSavingMaxBatch: (opts.passthrough as any)?.costSavingMaxBatch,\r\n })\r\n\r\n // 3) Poll state until terminal (or the SDK timeout).\r\n const deadline = Date.now() + (opts.timeoutMs ?? 10 * 60_000)\r\n const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms))\r\n let state: any = null\r\n while (Date.now() < deadline) {\r\n await sleep(1200)\r\n const r = await fetchImpl(`${base}/local-agent/state/${encodeURIComponent(sessionId)}`).catch(() => null)\r\n if (!r || !r.ok) continue\r\n state = await r.json().catch(() => null)\r\n if (!state || state.found === false) continue\r\n if (state.status && state.status !== 'running') break\r\n }\r\n\r\n const status = state?.status\r\n return {\r\n success: status === 'done' || status === 'awaiting_input',\r\n finalAnswer: state?.answer,\r\n steps: (state?.steps || []).map((s: any, i: number) => ({\r\n step: i + 1,\r\n action: s?.name || s?.action?.name || 'action',\r\n result: s?.args || s?.action?.args,\r\n })),\r\n usage: {\r\n aiCredits: Math.max(0, Math.round((state?.costUSD || 0) / 0.01)),\r\n tokensIn: state?.inTokens || 0,\r\n tokensOut: state?.outTokens || 0,\r\n costUSD: state?.costUSD || 0,\r\n turns: state?.turns || 0,\r\n },\r\n }\r\n }\r\n\r\n /**\r\n * Ask a running async job to stop at its next step boundary\r\n * (`POST { jobId, mode: 'stop' }`). Use it to wind down a job you\r\n * started via the raw API (or a run you're abandoning) instead of\r\n * leaving it stepping against a dead browser session until the step\r\n * cap — an abandoned job burns a model call + timeout per step.\r\n *\r\n * ```ts\r\n * const { stopRequested, status } = await px.autopilot.stop(jobId)\r\n * ```\r\n */\r\n async stop(jobId: string): Promise<{ jobId: string; stopRequested: boolean; status?: string }> {\r\n const env = await this.http.request<{ data?: any }>('/api/v1/ai-browser/execute', {\r\n method: 'POST',\r\n timeoutMs: 30_000,\r\n body: { jobId, mode: 'stop' },\r\n })\r\n const d = env?.data ?? env ?? {}\r\n return { jobId: d.jobId ?? jobId, stopRequested: d.stopRequested === true, status: d.status }\r\n }\r\n\r\n /**\r\n * Run the autopilot over the keep-alive stream endpoint and yield the\r\n * step trace. Ends with a `{ step: -1, action: 'done' }` sentinel whose\r\n * `result` field carries the full `AutopilotRunResult`.\r\n *\r\n * ```ts\r\n * for await (const step of px.autopilot.stream({ goal: 'Buy a ticket' })) {\r\n * console.log('Step', step.step, '→', step.action)\r\n * if (step.action === 'done') break\r\n * }\r\n * ```\r\n *\r\n * PROTOCOL (matches /api/v1/ai-browser/execute-stream — it is NOT SSE):\r\n * the server emits a 1-space heartbeat every 15s while the run executes,\r\n * then the complete execute-route JSON as the final chunk, i.e. the body\r\n * is `<heartbeats>\\n<json>`. The heartbeats exist to defeat the ~300s\r\n * infra idle timeout on long synchronous runs; per-step live events are\r\n * not available on this route, so steps arrive together when the run\r\n * finishes. Prefer `run()` unless you specifically want the keep-alive\r\n * transport for a long single-request run.\r\n */\r\n async *stream(\r\n opts: AutopilotRunOptions & { signal?: AbortSignal },\r\n ): AsyncGenerator<AutopilotStep, void, void> {\r\n if (opts.target === 'local') {\r\n // Local streaming isn't wired — the local runner has no step emitter.\r\n // Use the blocking `run({ target: 'local' })` (its result includes\r\n // the full step list) for local Chrome today.\r\n throw new Error(\r\n '[Prompteryx SDK] Streaming is cloud-only. For local Chrome use ' +\r\n 'autopilot.run({ target: \"local\" }) — its result contains all steps.',\r\n )\r\n }\r\n const res = await this.http.rawRequest('/api/v1/ai-browser/execute-stream', {\r\n method: 'POST',\r\n timeoutMs: opts.timeoutMs ?? 15 * 60_000,\r\n body: this.cloudTaskBody(opts),\r\n signal: opts.signal,\r\n })\r\n // Accumulate the whole body: heartbeat spaces, then '\\n' + the JSON.\r\n let text = ''\r\n if (res.body) {\r\n const reader = res.body.getReader()\r\n const decoder = new TextDecoder()\r\n while (true) {\r\n const { value, done } = await reader.read()\r\n if (done) break\r\n if (value) text += decoder.decode(value, { stream: true })\r\n }\r\n text += decoder.decode()\r\n } else {\r\n text = await res.text()\r\n }\r\n // Strip the heartbeats — the JSON is always the last (and only) content.\r\n const payload = text.trim()\r\n let parsed: any\r\n try {\r\n parsed = JSON.parse(payload)\r\n } catch {\r\n throw new ParseError('execute-stream returned a non-JSON payload', {\r\n raw: payload.slice(0, 500),\r\n })\r\n }\r\n if (parsed && parsed.success === false) {\r\n const msg = parsed?.error?.message ?? parsed?.error ?? 'AI Browser Agent run failed'\r\n throw new PrompteryxError(String(msg), { code: parsed?.error?.code, raw: parsed })\r\n }\r\n const result = this.mapResult(parsed?.data ?? parsed)\r\n for (const step of result.steps) yield step\r\n yield { step: -1, action: 'done', result }\r\n }\r\n}\r\n","/**\r\n * `px.cloudBrowser.*` — sessions, one-shot fetch, search.\r\n *\r\n * The most-used path: `sessions.create()` returns a `connectUrl` you\r\n * pass to Playwright's `chromium.connectOverCDP(connectUrl)`. Your own\r\n * Playwright code drives the browser from there; we handle the\r\n * infrastructure (residential proxies, recording, persistence).\r\n *\r\n * ⚠️ KEY FAMILY (verified live 2026-09-03): every /api/v1/cloud-browser/*\r\n * route authenticates with a CLOUD BROWSER key (`pcb_live_…`) sent as\r\n * `x-api-key` — NOT the platform `px_live_…` Bearer key the rest of the\r\n * SDK uses. Pass it as `new Prompteryx({ apiKey, cloudBrowserKey })`;\r\n * calls throw a descriptive AuthError when it's missing.\r\n */\r\n\r\nimport type { HttpClient, RequestOptions } from '../client'\r\nimport { AuthError } from '../errors'\r\nimport type {\r\n CloudFetchOptions,\r\n CloudFetchResult,\r\n CloudSearchResult,\r\n CloudSession,\r\n CloudSessionSummary,\r\n CreateSessionOptions,\r\n} from '../types'\r\n\r\nconst MISSING_CB_KEY_MESSAGE =\r\n 'px.cloudBrowser.* uses a Cloud Browser API key (pcb_live_…), which is a ' +\r\n 'separate key family from the platform px_live_… key. Create one under ' +\r\n 'Cloud Platform → API Keys and pass it as ' +\r\n 'new Prompteryx({ apiKey, cloudBrowserKey }).'\r\n\r\n/** Sub-resource: cloud browser sessions. */\r\nexport class SessionsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Headers for the pcb_live_ key family (throws a clear error if absent). */\r\n private cbAuth(): Record<string, string> {\r\n const key = this.http.cloudBrowserKey\r\n if (!key) throw new AuthError(MISSING_CB_KEY_MESSAGE)\r\n return { 'x-api-key': key }\r\n }\r\n\r\n private cbRequest<T>(path: string, opts: RequestOptions = {}): Promise<T> {\r\n return this.http.request<T>(path, {\r\n ...opts,\r\n headers: { ...this.cbAuth(), ...(opts.headers ?? {}) },\r\n })\r\n }\r\n\r\n /** Create a new browser session.\r\n *\r\n * Cloud (default):\r\n * ```ts\r\n * const s = await px.cloudBrowser.sessions.create()\r\n * // s.connectUrl → Prompteryx Cloud CDP. Bills cloud-browser minutes.\r\n * ```\r\n *\r\n * Local — uses YOUR machine's Chrome via the Prompteryx plugin +\r\n * Electron runner. ZERO cloud-browser minutes. Requires the plugin\r\n * to be running on the same machine as the SDK consumer; the call\r\n * short-circuits to localhost and never reaches the API.\r\n * ```ts\r\n * const s = await px.cloudBrowser.sessions.create({ target: 'local' })\r\n * // s.connectUrl → http://localhost:9222 (your Chrome's debug port)\r\n * ```\r\n *\r\n * When `target: 'local'` is set, cloud-only fields (recordSession,\r\n * proxy, profileId) are ignored — you're driving your own Chrome\r\n * with whatever cookies/extensions you've already installed.\r\n */\r\n async create(opts: CreateSessionOptions = {}): Promise<CloudSession> {\r\n if (opts.target === 'local') {\r\n // Local mode short-circuit. We don't hit the API at all — the\r\n // session is just a thin wrapper over the user's local Chrome's\r\n // CDP endpoint (managed by the Prompteryx plugin). Saves cloud\r\n // minutes AND avoids a round-trip. Failure to connect is the\r\n // consumer's problem at .connectOverCDP() time.\r\n const localCdp = 'http://127.0.0.1:9222'\r\n const localId = `local_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`\r\n return {\r\n id: localId,\r\n connectUrl: localCdp,\r\n status: 'active',\r\n startedAt: new Date().toISOString(),\r\n recordSession: false,\r\n }\r\n }\r\n // Wire names match the route (proxy/country), while the SDK options keep\r\n // the friendlier useProxy/proxyLocation spelling.\r\n return this.cbRequest<CloudSession>('/api/v1/cloud-browser/sessions', {\r\n method: 'POST',\r\n body: {\r\n recordSession: opts.recordSession,\r\n captureDownloads: opts.captureDownloads,\r\n extensions: opts.extensions,\r\n proxy: opts.useProxy,\r\n country: opts.proxyLocation,\r\n sessionTimeoutMinutes: opts.sessionTimeoutMinutes,\r\n profileId: opts.profileId,\r\n persistContext: opts.persistContext,\r\n viewport: opts.viewport,\r\n ...(opts.passthrough || {}),\r\n },\r\n })\r\n }\r\n\r\n /** Retrieve a session's history record (status/duration/recording flag).\r\n * Note: this is durable history, not a live handle — it has no\r\n * `connectUrl`. Keep the `create()` response for connecting. */\r\n async get(sessionId: string): Promise<CloudSessionSummary> {\r\n return this.cbRequest(\r\n `/api/v1/cloud-browser/sessions/${encodeURIComponent(sessionId)}`,\r\n )\r\n }\r\n\r\n /** List recent sessions for your account, newest first. */\r\n async list(opts: { limit?: number } = {}): Promise<CloudSessionSummary[]> {\r\n const res = await this.cbRequest<{ sessions: CloudSessionSummary[] }>(\r\n '/api/v1/cloud-browser/sessions',\r\n { query: { limit: opts.limit } },\r\n )\r\n return res.sessions ?? []\r\n }\r\n\r\n /** Close a session, finalising the recording (if any) + releasing the\r\n * cloud-browser slot. Idempotent. No-op for local sessions\r\n * (target: 'local') — those don't have a slot to release. */\r\n async close(sessionId: string): Promise<{ ok: boolean; proxyMB?: number }> {\r\n // Local sessions are pure client-side handles — nothing to release.\r\n if (sessionId.startsWith('local_')) return { ok: true }\r\n return this.cbRequest(\r\n `/api/v1/cloud-browser/sessions/${encodeURIComponent(sessionId)}`,\r\n { method: 'DELETE' },\r\n )\r\n }\r\n}\r\n\r\nexport class CloudBrowserResource {\r\n readonly sessions: SessionsResource\r\n\r\n constructor(private readonly http: HttpClient) {\r\n this.sessions = new SessionsResource(http)\r\n }\r\n\r\n private cbAuth(): Record<string, string> {\r\n const key = this.http.cloudBrowserKey\r\n if (!key) throw new AuthError(MISSING_CB_KEY_MESSAGE)\r\n return { 'x-api-key': key }\r\n }\r\n\r\n /**\r\n * One-shot fetch through the cloud browser. Spins up a short-lived\r\n * session, loads the page in real Chromium (so JS-rendered sites work),\r\n * extracts the content, and tears down. Use this when you only need ONE\r\n * page and don't want to manage Playwright yourself.\r\n *\r\n * ```ts\r\n * const page = await px.cloudBrowser.fetch({\r\n * url: 'https://example.com/pricing',\r\n * format: 'markdown', // 'text' (default) | 'markdown' | 'html' | 'links'\r\n * waitForSelector: '.pricing-table', // for JS-rendered content\r\n * selectors: ['.pricing-table .plan'], // deterministic CSS extraction\r\n * })\r\n * // page.content, page.extracted, page.title, page.finalUrl …\r\n * ```\r\n */\r\n async fetch(opts: CloudFetchOptions): Promise<CloudFetchResult> {\r\n return this.http.request('/api/v1/cloud-browser/fetch', {\r\n method: 'POST',\r\n body: opts,\r\n headers: this.cbAuth(),\r\n timeoutMs: Math.max(90_000, (opts.timeoutMs ?? 30_000) + 30_000),\r\n })\r\n }\r\n\r\n /**\r\n * Search the web through the cloud browser and get structured results\r\n * (title/url/snippet). Runs the query against DuckDuckGo's server-rendered\r\n * HTML endpoint in a real browser — there is no engine choice today.\r\n */\r\n async search(opts: {\r\n query: string\r\n /** Max results, 1–25. Default 10. */\r\n limit?: number\r\n /** Route through a residential proxy. */\r\n proxy?: boolean\r\n /** Proxy exit country (with `proxy: true`), e.g. 'us'. */\r\n country?: string\r\n }): Promise<CloudSearchResult[]> {\r\n const res = await this.http.request<{ query: string; results: CloudSearchResult[] }>(\r\n '/api/v1/cloud-browser/search',\r\n { method: 'POST', body: opts, headers: this.cbAuth(), timeoutMs: 90_000 },\r\n )\r\n return res.results ?? []\r\n }\r\n}\r\n","/**\r\n * `px.executions.*` — status, logs (polled OR streamed), wait.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport { TimeoutError } from '../errors'\r\nimport type { ExecutionLogEvent, ExecutionRecord, ExecutionStatus } from '../types'\r\n\r\nconst TERMINAL_STATES: ExecutionStatus[] = [\r\n 'completed',\r\n 'failed',\r\n 'cancelled',\r\n 'timed_out',\r\n]\r\n\r\nexport class ExecutionsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Get current execution record. */\r\n async get(executionId: string): Promise<ExecutionRecord> {\r\n return this.http.request(`/api/v1/executions/${encodeURIComponent(executionId)}`)\r\n }\r\n\r\n /**\r\n * Block until the execution reaches a terminal state. Polls every\r\n * `pollIntervalMs` (default 2s) until it's `completed`/`failed`/\r\n * `cancelled`/`timed_out`, OR until `timeoutMs` elapses (default 5min).\r\n *\r\n * Throws `TimeoutError` on timeout; otherwise returns the final record.\r\n */\r\n async wait(\r\n executionId: string,\r\n opts: { timeoutMs?: number; pollIntervalMs?: number; signal?: AbortSignal } = {},\r\n ): Promise<ExecutionRecord> {\r\n const timeoutMs = opts.timeoutMs ?? 5 * 60_000\r\n const pollIntervalMs = opts.pollIntervalMs ?? 2_000\r\n const deadline = Date.now() + timeoutMs\r\n while (true) {\r\n if (opts.signal?.aborted) throw new TimeoutError(`Wait cancelled for ${executionId}`)\r\n const exec = await this.get(executionId)\r\n if (TERMINAL_STATES.includes(exec.status)) return exec\r\n if (Date.now() > deadline) {\r\n throw new TimeoutError(`Execution ${executionId} did not finish within ${timeoutMs}ms`)\r\n }\r\n await new Promise((r) => setTimeout(r, pollIntervalMs))\r\n }\r\n }\r\n\r\n /**\r\n * Get the logs for a finished (or in-progress) execution as a one-shot\r\n * fetch. For real-time streaming use `stream(executionId)` instead.\r\n */\r\n async logs(executionId: string): Promise<ExecutionLogEvent[]> {\r\n const res = await this.http.request<{ logs: ExecutionLogEvent[] }>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/logs`,\r\n )\r\n return res.logs ?? []\r\n }\r\n\r\n /**\r\n * Stream log events as they arrive. Async iterable:\r\n *\r\n * for await (const ev of px.executions.stream(execId)) {\r\n * console.log(ev.message)\r\n * if (ev.type === 'done') break\r\n * }\r\n */\r\n async *stream(\r\n executionId: string,\r\n opts: { signal?: AbortSignal } = {},\r\n ): AsyncGenerator<ExecutionLogEvent, void, void> {\r\n yield* this.http.streamSse<ExecutionLogEvent>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/logs/stream`,\r\n { signal: opts.signal },\r\n )\r\n }\r\n\r\n /** Get a single node's output from a finished execution. */\r\n async getNodeOutput(executionId: string, nodeId: string): Promise<unknown> {\r\n return this.http.request(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}/nodes/${encodeURIComponent(nodeId)}/output`,\r\n )\r\n }\r\n}\r\n","/**\r\n * `px.profiles.*` — Chrome profile management.\r\n *\r\n * Profiles are persistent browser identities — they store cookies,\r\n * local storage, extensions, and login state across sessions. Two\r\n * kinds:\r\n * • `cloud` — lives on the Prompteryx cloud browser infrastructure.\r\n * Accessible from any device, but starts logged out (you have to\r\n * log in once after creating).\r\n * • `local` — runs on the user's own Chrome via the Prompteryx\r\n * plugin. Reuses whatever Chrome profile the user is already\r\n * signed into (Gmail, banking, internal SSO). Cloud-only\r\n * workloads can't access this.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { ProfileSummary } from '../types'\r\n\r\nexport class ProfilesResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { kind?: 'cloud' | 'local' } = {}): Promise<ProfileSummary[]> {\r\n const res = await this.http.request<{ profiles: ProfileSummary[] }>(\r\n '/api/v1/profiles',\r\n { query: { kind: opts.kind } },\r\n )\r\n return res.profiles ?? []\r\n }\r\n\r\n async get(profileId: string): Promise<ProfileSummary> {\r\n return this.http.request(`/api/v1/profiles/${encodeURIComponent(profileId)}`)\r\n }\r\n\r\n /** Create a new CLOUD profile. Local profiles are managed by the\r\n * plugin and cannot be created via the API. */\r\n async create(opts: { name: string }): Promise<ProfileSummary> {\r\n return this.http.request('/api/v1/profiles', {\r\n method: 'POST',\r\n body: { name: opts.name, kind: 'cloud' },\r\n })\r\n }\r\n\r\n async delete(profileId: string): Promise<{ ok: true }> {\r\n return this.http.request(`/api/v1/profiles/${encodeURIComponent(profileId)}`, {\r\n method: 'DELETE',\r\n })\r\n }\r\n}\r\n","/**\r\n * `px.schedules.*` — server-side workflow scheduling.\r\n *\r\n * Set a workflow to run on cron / interval; the platform's Cloud\r\n * Scheduler will fire it on schedule even when no client is connected.\r\n * Wraps the same scheduling primitive the Visual Studio \"Active\"\r\n * toggle uses.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { CreateScheduleOptions, ScheduleSummary } from '../types'\r\n\r\nexport class SchedulesResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { active?: boolean; workflowId?: string } = {}): Promise<ScheduleSummary[]> {\r\n const res = await this.http.request<{ schedules: ScheduleSummary[] }>(\r\n '/api/v1/schedules',\r\n { query: { active: opts.active, workflowId: opts.workflowId } },\r\n )\r\n return res.schedules ?? []\r\n }\r\n\r\n async get(scheduleId: string): Promise<ScheduleSummary> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`)\r\n }\r\n\r\n /** Create a new schedule. Returns the created record. */\r\n async create(opts: CreateScheduleOptions): Promise<ScheduleSummary> {\r\n return this.http.request('/api/v1/schedules', {\r\n method: 'POST',\r\n body: opts,\r\n })\r\n }\r\n\r\n /** Pause / resume / change cron / timezone. */\r\n async update(scheduleId: string, patch: Partial<CreateScheduleOptions> & { active?: boolean }): Promise<ScheduleSummary> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`, {\r\n method: 'PATCH',\r\n body: patch,\r\n })\r\n }\r\n\r\n async delete(scheduleId: string): Promise<{ ok: true }> {\r\n return this.http.request(`/api/v1/schedules/${encodeURIComponent(scheduleId)}`, {\r\n method: 'DELETE',\r\n })\r\n }\r\n}\r\n","/**\r\n * `px.subscription.*` — plan + balance + usage telemetry.\r\n *\r\n * Programmatic access to the same numbers the in-app `/subscription`\r\n * and `/cloud-platform/plans` pages display. Use this to:\r\n * • Check the user's remaining AI Credits before kicking off a\r\n * long workflow.\r\n * • Read monthly execution counts for your own dashboards.\r\n * • Detect a plan downgrade and react in your code.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport type { SubscriptionStatus } from '../types'\r\n\r\nexport class SubscriptionResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Get the current plan + balances + usage. */\r\n async get(): Promise<SubscriptionStatus> {\r\n return this.http.request('/api/v1/subscription')\r\n }\r\n\r\n // NOT SHIPPED (2026-09-03, v0.4.0): usage() was removed — the route it\r\n // targeted (/api/v1/subscription/usage) does not exist on the live API\r\n // (the only usage route is /api/v1/usage, with a different shape).\r\n // Re-add once a real time-series endpoint ships.\r\n}\r\n","/**\r\n * `px.workflows.*` — Visual Studio workflows.\r\n *\r\n * Trigger workflows you (or anyone you share with) built in Visual\r\n * Studio. Workflows are first-class platform objects: they have\r\n * permanent IDs, can be scheduled, shared, templated, and edited\r\n * visually. Triggering one via the SDK is fully equivalent to\r\n * pressing Run in the UI — same runtime, same node executor, same\r\n * billing path.\r\n */\r\n\r\nimport type { HttpClient } from '../client'\r\nimport { TimeoutError } from '../errors'\r\nimport type {\r\n ExecutionRecord,\r\n RunWorkflowOptions,\r\n RunWorkflowResult,\r\n WorkflowSummary,\r\n} from '../types'\r\n\r\nexport class WorkflowsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n async list(opts: { limit?: number; search?: string; tag?: string } = {}): Promise<WorkflowSummary[]> {\r\n const res = await this.http.request<{ workflows: WorkflowSummary[] }>(\r\n '/api/v1/workflows',\r\n { query: { limit: opts.limit, q: opts.search, tag: opts.tag } },\r\n )\r\n return res.workflows ?? []\r\n }\r\n\r\n async get(workflowId: string): Promise<WorkflowSummary & { nodes?: unknown[] }> {\r\n return this.http.request(`/api/v1/workflows/${encodeURIComponent(workflowId)}`)\r\n }\r\n\r\n /**\r\n * Trigger a workflow. Returns immediately with `executionId`. Use\r\n * `px.executions.wait(id)` to block until completion or\r\n * `px.executions.stream(id)` to follow log events live.\r\n *\r\n * The `execution` options override the workflow's saved settings\r\n * for this one run — you don't have to edit the workflow in VS to\r\n * change the proxy, region, profile, etc.\r\n */\r\n async run(workflowId: string, opts: RunWorkflowOptions = {}): Promise<RunWorkflowResult> {\r\n return this.http.request<RunWorkflowResult>(\r\n `/api/v1/workflows/${encodeURIComponent(workflowId)}/execute`,\r\n {\r\n method: 'POST',\r\n body: {\r\n variables: opts.input,\r\n executionOptions: opts.execution,\r\n },\r\n },\r\n )\r\n }\r\n\r\n /**\r\n * Run + block. Returns the final ExecutionRecord. Throws\r\n * `TimeoutError` if the run takes longer than `timeoutMs`\r\n * (default 5 minutes).\r\n */\r\n async runAndWait(\r\n workflowId: string,\r\n opts: RunWorkflowOptions & { timeoutMs?: number; pollIntervalMs?: number } = {},\r\n ): Promise<ExecutionRecord> {\r\n const started = await this.run(workflowId, opts)\r\n return this.waitInternal(started.executionId, opts.timeoutMs ?? 5 * 60_000, opts.pollIntervalMs ?? 2_000)\r\n }\r\n\r\n private async waitInternal(executionId: string, timeoutMs: number, pollIntervalMs: number): Promise<ExecutionRecord> {\r\n const deadline = Date.now() + timeoutMs\r\n while (true) {\r\n const exec = await this.http.request<ExecutionRecord>(\r\n `/api/v1/executions/${encodeURIComponent(executionId)}`,\r\n )\r\n if (['completed', 'failed', 'cancelled', 'timed_out'].includes(exec.status)) return exec\r\n if (Date.now() > deadline) {\r\n throw new TimeoutError(`Execution ${executionId} did not finish within ${timeoutMs}ms`)\r\n }\r\n await new Promise((r) => setTimeout(r, pollIntervalMs))\r\n }\r\n }\r\n}\r\n","/**\r\n * Browser-agent model catalog — the ids `px.autopilot.run({ model })` accepts.\r\n *\r\n * ⚠️ MUST MIRROR `components/unified-chat-v2/browser-models.ts`\r\n * `V2_BROWSER_MODELS` in the platform repo — that file is the canonical\r\n * catalog the server validates against (an unknown id hard-400s with\r\n * `UNSUPPORTED_MODEL` under strict validation). When that list changes,\r\n * regenerate this one. Last synced: 2026-09-07 — 35 ids.\r\n *\r\n * The type stays open (`| (string & {})`) so a model the server adds\r\n * tomorrow works without an SDK release, while editors still autocomplete\r\n * the known catalog.\r\n */\r\n\r\nexport const AUTOPILOT_MODELS = [\r\n // ── Standard (Gemini native Computer Use) ────────────────────────────────\r\n 'gemini-3.5-flash', // Recommended — fast and cheap. THE DEFAULT.\r\n 'gemini-3.7-flash', // Newest GA Flash — Google-recommended for computer use\r\n 'gemini-3.6-flash', // Newest Flash (Computer Use preview)\r\n 'gemini-default', // Gemini 2.5 Computer Use (legacy)\r\n // ── Experimental (Gemini) ────────────────────────────────────────────────\r\n 'gemini-3-flash-preview',\r\n 'gemini-3.5-flash-lite',\r\n // Harness aliases — resolved server-side to an underlying brain + prompt.\r\n 'model-a',\r\n 'model-a1',\r\n 'model-b',\r\n 'model-j',\r\n 'model-k',\r\n 'model-k37',\r\n // ── Anthropic / OpenAI native Computer Use ───────────────────────────────\r\n 'claude-sonnet-4-6',\r\n 'claude-opus-4-8',\r\n 'gpt-5.6-terra',\r\n 'gpt-5.6-sol',\r\n 'gpt-5.5',\r\n 'gpt-6-astra', // OpenAI flagship (Sep 2026) — admin-gated in the UI for now\r\n // ── Generic Vision Loop (standard chat models on screenshots) ────────────\r\n 'claude-fable-5-1-vision',\r\n 'claude-fable-5-vision',\r\n 'claude-opus-5-vision',\r\n 'claude-sonnet-5-vision',\r\n 'claude-sonnet-4-6-vision',\r\n 'gpt-6-astra-vision', // admin-gated in the UI for now\r\n 'gpt-5.6-luna-vision',\r\n 'gpt-5.4-vision',\r\n 'gpt-4o-vision',\r\n 'kimi-k3-vision',\r\n // ── Experimental server-side harness engines ─────────────────────────────\r\n 'modelc',\r\n 'model-d',\r\n 'model-d1',\r\n 'model-e',\r\n 'model-f',\r\n 'model-h',\r\n 'model-i',\r\n] as const\r\n\r\n/** A model id from the known catalog. */\r\nexport type AutopilotModelId = (typeof AUTOPILOT_MODELS)[number]\r\n\r\n/** Open union: known ids autocomplete, forward-compatible strings still pass. */\r\nexport type AutopilotModel = AutopilotModelId | (string & {})\r\n\r\n/** The platform default when `model` is omitted. */\r\nexport const DEFAULT_AUTOPILOT_MODEL = 'gemini-3.5-flash'\r\n","/**\r\n * @prompteryx/sdk\r\n *\r\n * Official TypeScript SDK for the Prompteryx platform.\r\n *\r\n * Two AI surfaces:\r\n *\r\n * • **Copilot** — helps with ONE step you describe in plain English.\r\n * Your code drives Playwright; copilot just figures out the\r\n * selector to click / the data to pull / what's on the page.\r\n *\r\n * ```ts\r\n * await px.copilot.do(page, 'click the Sign up button')\r\n * const product = await px.copilot.read(page, productSchema)\r\n * const actions = await px.copilot.scan(page, 'checkout buttons')\r\n * ```\r\n *\r\n * • **Autopilot** — runs an autonomous multi-step task end-to-end\r\n * with no per-action involvement from you.\r\n *\r\n * ```ts\r\n * const result = await px.autopilot.run({\r\n * goal: 'Apply for the Senior Engineer role at OpenAI',\r\n * saveAsWorkflow: true, // permanent zero-AI-cost replay\r\n * })\r\n * ```\r\n *\r\n * Plus workflows, executions, cloud browser sessions / fetch / search,\r\n * schedules, profiles, and subscription telemetry.\r\n *\r\n * TWO KEY FAMILIES:\r\n * • `apiKey` (`px_live_…`) — the platform API key; sent as\r\n * `Authorization: Bearer`. 60 requests/minute, 10,000/day.\r\n * • `cloudBrowserKey` (`pcb_live_…`) — the Cloud Browser key; required\r\n * only for `px.cloudBrowser.*`, sent as `x-api-key`.\r\n *\r\n * Quick start:\r\n *\r\n * ```ts\r\n * import { Prompteryx } from '@prompteryx/sdk'\r\n * import { chromium } from 'playwright-core'\r\n *\r\n * const px = new Prompteryx({\r\n * apiKey: process.env.PROMPTERYX_API_KEY!, // px_live_…\r\n * cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY, // pcb_live_…\r\n * })\r\n *\r\n * // 1. Cloud browser session\r\n * const session = await px.cloudBrowser.sessions.create({\r\n * useProxy: true, proxyLocation: 'us',\r\n * })\r\n * const browser = await chromium.connectOverCDP(session.connectUrl)\r\n * const page = browser.contexts()[0].pages()[0]\r\n *\r\n * // 2. Copilot on top of Playwright\r\n * await page.goto('https://news.ycombinator.com')\r\n * const top = await px.copilot.read(page, z.object({\r\n * stories: z.array(z.object({ title: z.string(), url: z.string() })),\r\n * }))\r\n * ```\r\n *\r\n * See PROMPTERYX_SDK.md in docs/ for the full design + reference.\r\n */\r\n\r\nimport { HttpClient } from './client'\r\nimport { AutopilotResource } from './resources/autopilot'\r\nimport { CloudBrowserResource } from './resources/cloudBrowser'\r\nimport { ExecutionsResource } from './resources/executions'\r\nimport { ProfilesResource } from './resources/profiles'\r\nimport { SchedulesResource } from './resources/schedules'\r\nimport { SubscriptionResource } from './resources/subscription'\r\nimport { WorkflowsResource } from './resources/workflows'\r\nimport { CopilotHelpers, type PageLike } from './page'\r\nimport type {\r\n CopilotDoResult,\r\n DiscoveredAction,\r\n PrompteryxClientOptions,\r\n} from './types'\r\n\r\n// Public re-exports\r\nexport * from './errors'\r\nexport * from './types'\r\nexport * from './models'\r\nexport type { PageLike }\r\n\r\n// v0.4.0 (2026-09-03): the connectHub, customNodes, templates, apiKeys and\r\n// recordings namespaces plus subscription.usage() were REMOVED from the\r\n// public surface — the routes they target don't exist on the live API (or,\r\n// for api-keys, can never accept API-key auth). The source files remain in\r\n// src/resources/ with dated NOT-SHIPPED headers for a future release.\r\n\r\n/**\r\n * Copilot surface — bundles the three on-page primitives behind a\r\n * single namespace so calling code reads as\r\n * `px.copilot.do(...)` / `px.copilot.read(...)` / `px.copilot.scan(...)`.\r\n * Used internally by the Prompteryx class.\r\n */\r\nclass Copilot {\r\n constructor(private readonly helpers: CopilotHelpers) {}\r\n /** Execute a natural-language action on a connected Playwright page. */\r\n do(page: PageLike, instruction: string, opts?: { timeout?: number }): Promise<CopilotDoResult> {\r\n return this.helpers.do(page, instruction, opts)\r\n }\r\n /** Pull typed data from the page (Zod schema or raw JSON Schema). */\r\n read<T>(page: PageLike, schema: { parse(input: unknown): T } | { jsonSchema: unknown }): Promise<T> {\r\n return this.helpers.read<T>(page, schema as any)\r\n }\r\n /** Discover available actions on the page; useful pre-`do` step. */\r\n scan(page: PageLike, hint?: string): Promise<DiscoveredAction[]> {\r\n return this.helpers.scan(page, hint)\r\n }\r\n}\r\n\r\nexport class Prompteryx {\r\n private readonly http: HttpClient\r\n\r\n // Core resources — the verified live surface.\r\n public readonly workflows: WorkflowsResource\r\n public readonly executions: ExecutionsResource\r\n public readonly cloudBrowser: CloudBrowserResource\r\n public readonly autopilot: AutopilotResource\r\n public readonly copilot: Copilot\r\n public readonly schedules: SchedulesResource\r\n public readonly profiles: ProfilesResource\r\n public readonly subscription: SubscriptionResource\r\n\r\n constructor(opts: PrompteryxClientOptions) {\r\n this.http = new HttpClient(opts)\r\n this.workflows = new WorkflowsResource(this.http)\r\n this.executions = new ExecutionsResource(this.http)\r\n this.cloudBrowser = new CloudBrowserResource(this.http)\r\n this.autopilot = new AutopilotResource(this.http)\r\n this.copilot = new Copilot(new CopilotHelpers(this.http))\r\n this.schedules = new SchedulesResource(this.http)\r\n this.profiles = new ProfilesResource(this.http)\r\n this.subscription = new SubscriptionResource(this.http)\r\n }\r\n}\r\n\r\nexport default Prompteryx\r\n"],"mappings":";;;;;;;;;;;;;;;AA8BA,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;AA0B5B,SAAS,eAAe,QAA0B;AAChD,MACE,UACA,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,MAAM,KACrB,aAAa,UACb,UAAU,UACV,OAAQ,OAAgC,YAAY,WACpD;AACA,WAAQ,OAA6B;AAAA,EACvC;AACA,SAAO;AACT;AAEO,IAAM,aAAN,MAAiB;AAAA,EAWtB,YAAY,MAA+B;AACzC,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI,gBAAgB,qDAAqD;AAAA,IACjF;AACA,SAAK,SAAS,KAAK;AACnB,SAAK,kBAAkB,KAAK;AAC5B,SAAK,WAAW,KAAK,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACpE,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,iBAAiB,KAAK,kBAAkB,CAAC;AAC9C,UAAM,IAAI,KAAK,SAAS,WAAW;AACnC,QAAI,CAAC,GAAG;AACN,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,YAAY,EAAE,KAAK,UAAU;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,QAAqB,MAAc,OAAuB,CAAC,GAAe;AAC9E,UAAM,MAAM,MAAM,KAAK,WAAW,MAAM,IAAI;AAC5C,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACN,YAAM,IAAI,WAAW,sCAAsC,IAAI,IAAI;AAAA,QACjE,QAAQ,IAAI;AAAA,QACZ,KAAK,KAAK,MAAM,GAAG,GAAG;AAAA,MACxB,CAAC;AAAA,IACH;AACA,WAAO,eAAe,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA,EAIA,MAAM,WAAW,MAAc,OAAuB,CAAC,GAAsB;AAC3E,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,MAAM,KAAK,SAAS,MAAM,KAAK,KAAK;AAC1C,UAAM,cAAc,KAAK,SAAU,WAAW;AAC9C,UAAM,cAAc,cAAc,KAAK,aAAa,IAAI;AACxD,QAAI;AAEJ,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAI;AACF,cAAM,MAAM,MAAM,KAAK,SAAS,KAAK,QAAQ,IAAI;AACjD,YAAI,IAAI,GAAI,QAAO;AAGnB,cAAM,MAAM,MAAM,KAAK,kBAAkB,GAAG;AAC5C,YAAI,KAAK,YAAY,GAAG,KAAK,UAAU,cAAc,GAAG;AACtD,gBAAM,KAAK,QAAQ,SAAS,GAAG;AAC/B,oBAAU;AACV;AAAA,QACF;AACA,cAAM;AAAA,MACR,SAAS,GAAG;AAEV,YAAI,aAAa,gBAAiB,OAAM;AACxC,cAAM,UAAU,KAAK,cAAc,CAAC;AACpC,YAAI,KAAK,YAAY,OAAO,KAAK,UAAU,cAAc,GAAG;AAC1D,gBAAM,KAAK,QAAQ,SAAS,OAAO;AACnC,oBAAU;AACV;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,WAAW,IAAI,gBAAgB,uCAAuC;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,UAAuB,MAAc,OAAuB,CAAC,GAAkC;AACpG,UAAM,MAAM,MAAM,KAAK,WAAW,MAAM;AAAA,MACtC,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,KAAK,SAAS,QAAQ,oBAAoB;AAAA,IAC1D,CAAC;AACD,QAAI,CAAC,IAAI,KAAM;AACf,UAAM,SAAS,IAAI,KAAK,UAAU;AAClC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,MAAM;AACV,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,aAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAG7C,UAAI;AACJ,cAAQ,MAAM,IAAI,QAAQ,MAAM,OAAO,IAAI;AACzC,cAAM,MAAM,IAAI,MAAM,GAAG,GAAG;AAC5B,cAAM,IAAI,MAAM,MAAM,CAAC;AACvB,cAAM,YAAY,IACf,MAAM,IAAI,EACV,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC,EACnC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;AAC/B,YAAI,UAAU,WAAW,EAAG;AAC5B,cAAM,UAAU,UAAU,KAAK,IAAI;AACnC,YAAI,CAAC,QAAS;AACd,YAAI;AACF,gBAAM,KAAK,MAAM,OAAO;AAAA,QAC1B,QAAQ;AAAA,QAIR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,SAAS,KAAa,QAAgB,MAAyC;AAC3F,UAAM,YAAY,KAAK,aAAa,KAAK;AACzC,UAAM,MAAM,IAAI,gBAAgB;AAChC,UAAM,IAAI,WAAW,MAAM,IAAI,MAAM,GAAG,SAAS;AAEjD,QAAI,KAAK,QAAQ;AACf,UAAI,KAAK,OAAO,QAAS,KAAI,MAAM;AAAA,UAC9B,MAAK,OAAO,iBAAiB,SAAS,MAAM,IAAI,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,IAC9E;AACA,QAAI;AACF,YAAM,UAAkC;AAAA,QACtC,eAAe,UAAU,KAAK,MAAM;AAAA,QACpC,QAAQ;AAAA,QACR,GAAG,KAAK;AAAA,QACR,GAAI,KAAK,WAAW,CAAC;AAAA,MACvB;AACA,UAAI;AACJ,UAAI,KAAK,SAAS,QAAW;AAC3B,gBAAQ,cAAc,IAAI;AAC1B,eAAO,KAAK,UAAU,KAAK,IAAI;AAAA,MACjC;AACA,aAAO,MAAM,KAAK,UAAU,KAAK;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH,UAAE;AACA,mBAAa,CAAC;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,SAAS,MAAc,OAAyC;AACtE,UAAM,OAAO,KAAK,WAAW,MAAM,IAAI,OAAO,GAAG,KAAK,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AACxG,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,SAAS,IAAI,gBAAgB;AACnC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,UAAI,MAAM,UAAa,MAAM,KAAM;AACnC,aAAO,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACzB;AACA,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,KAAK;AAAA,EAChE;AAAA,EAEA,MAAc,kBAAkB,KAAyC;AACvE,QAAI,SAAc;AAClB,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,eAAS,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,IACrC,QAAQ;AAAA,IAAkC;AAC1C,UAAM,UAAU,QAAQ,OAAO,WAC1B,QAAQ,WACR,QAAQ,SACR,uBAAuB,IAAI,MAAM;AACtC,UAAM,OAAO,QAAQ,OAAO,QAAQ,QAAQ;AAC5C,UAAM,YAAY,IAAI,QAAQ,IAAI,cAAc,KAAK;AACrD,UAAM,OAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM,WAAW,KAAK,OAAO;AAChE,YAAQ,IAAI,QAAQ;AAAA,MAClB,KAAK;AAAA,MACL,KAAK;AACH,eAAO,IAAI,UAAU,SAAS,IAAI;AAAA,MACpC,KAAK;AACH,eAAO,IAAI,WAAW,SAAS,EAAE,GAAG,MAAM,WAAW,QAAQ,OAAO,aAAa,QAAQ,UAAU,CAAC;AAAA,MACtG,KAAK;AACH,eAAO,IAAI,cAAc,SAAS,IAAI;AAAA,MACxC,KAAK;AACH,eAAO,IAAI,gBAAgB,SAAS,IAAI;AAAA,MAC1C,KAAK,KAAK;AACR,cAAM,aAAa,SAAS,IAAI,QAAQ,IAAI,aAAa,KAAK,KAAK,EAAE;AACrE,eAAO,IAAI,eAAe,SAAS,EAAE,GAAG,MAAM,mBAAmB,OAAO,SAAS,UAAU,IAAI,aAAa,OAAU,CAAC;AAAA,MACzH;AAAA,MACA;AACE,YAAI,IAAI,UAAU,IAAK,QAAO,IAAI,YAAY,SAAS,IAAI;AAC3D,eAAO,IAAI,gBAAgB,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEQ,cAAc,GAA6B;AACjD,UAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,QAAI,aAAa,UAAU,EAAE,SAAS,gBAAgB,IAAI,SAAS,SAAS,IAAI;AAC9E,aAAO,IAAI,aAAa,sBAAsB,GAAG,EAAE;AAAA,IACrD;AACA,WAAO,IAAI,aAAa,kBAAkB,GAAG,EAAE;AAAA,EACjD;AAAA,EAEQ,YAAY,KAA+B;AACjD,QAAI,eAAe,YAAa,QAAO;AACvC,QAAI,eAAe,eAAgB,QAAO;AAC1C,QAAI,eAAe,aAAc,QAAO;AACxC,QAAI,eAAe,aAAc,QAAO;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,QAAQ,SAAiB,KAAqC;AAE1E,UAAM,aAAc,IAAuB;AAC3C,QAAI,cAAc,aAAa,GAAG;AAChC,aAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,YAAY,EAAE,IAAI,GAAI,CAAC;AAAA,IAC1E;AAEA,UAAM,OAAO,MAAM,KAAK,IAAI,GAAG,OAAO;AACtC,UAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,WAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,OAAO,MAAM,CAAC;AAAA,EACxD;AACF;;;ACrRO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBhD,MAAM,IAAI,MAAwD;AAChE,QAAI,KAAK,WAAW,SAAS;AAM3B,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B;AAGA,QAAI,KAAK,UAAU,KAAK,SAAS,GAAG;AAClC,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B;AAKA,WAAO,KAAK,SAAS,IAAI;AAAA,EAC3B;AAAA;AAAA,EAGQ,cAAc,MAAoD;AACxE,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,iBAAiB,KAAK;AAAA,MACtB,cAAc,KAAK;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,oBAAoB,KAAK;AAAA,MACzB,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,KAAK;AAAA,MACrB,mBAAmB,KAAK;AAAA,MACxB,WAAW,KAAK;AAAA,MAChB,sBAAsB,KAAK;AAAA,MAC3B,cAAc,KAAK;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA;AAAA,MAEd,eAAe,KAAK;AAAA,MACpB,gBAAgB,KAAK;AAAA,MACrB,0BAA0B,KAAK;AAAA,MAC/B,sBAAsB,KAAK;AAAA,MAC3B,oBAAoB,KAAK;AAAA,MACzB,uBAAuB,KAAK;AAAA,MAC5B,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,SAAS,MAAwD;AAC7E,UAAM,MAAM,MAAM,KAAK,KAAK,QAA4B,8BAA8B;AAAA,MACpF,QAAQ;AAAA,MACR,WAAW,KAAK,aAAa,KAAK;AAAA,MAClC,MAAM;AAAA,QACJ,GAAG,KAAK,cAAc,IAAI;AAAA,QAC1B,QAAQ,KAAK;AAAA,QACb,aAAa,KAAK;AAAA,QAClB,mBAAmB,KAAK;AAAA,QACxB,eAAe,KAAK;AAAA,MACtB;AAAA,IACF,CAAC;AACD,WAAO,KAAK,UAAU,KAAK,QAAQ,GAAG;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,SAAS,MAAwD;AAC7E,UAAM,YAAY,KAAK,aAAa,KAAK;AACzC,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,UAAM,QAAQ,CAAC,OAAe,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAGlE,UAAM,WAAW,MAAM,KAAK,KAAK,QAAwB,8BAA8B;AAAA,MACrF,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,MAAM,EAAE,GAAG,KAAK,cAAc,IAAI,GAAG,MAAM,QAAQ;AAAA,IACrD,CAAC;AACD,UAAM,QAA4B,UAAU,MAAM;AAClD,QAAI,CAAC,OAAO;AAGV,aAAO,KAAK,UAAU,UAAU,QAAQ,QAAQ;AAAA,IAClD;AAIA,QAAI,OAAY;AAChB,WAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,YAAM,SAAS,MAAM,KAAK,KAAK,QAAwB,8BAA8B;AAAA,QACnF,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,OAAO;AAAA,QACP,MAAM,EAAE,OAAO,MAAM,OAAO,UAAU,KAAK,SAAS;AAAA,MACtD,CAAC;AACD,aAAO,QAAQ,QAAQ;AACvB,UAAI,CAAC,QAAQ,KAAK,YAAY,KAAK,WAAW,UAAW;AACzD,YAAM,MAAM,GAAG;AAAA,IACjB;AAIA,QAAI,QAAQ,KAAK,WAAW,WAAW;AACrC,UAAI;AACF,cAAM,YAAY,MAAM,KAAK,KAAK,QAAwB,8BAA8B;AAAA,UACtF,OAAO,EAAE,MAAM;AAAA,UACf,WAAW;AAAA,QACb,CAAC;AACD,YAAI,WAAW,KAAM,QAAO,UAAU;AAAA,MACxC,QAAQ;AAAA,MAA2B;AAAA,IACrC;AAEA,WAAO,KAAK,UAAU,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,MAA+B;AAC/C,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,SAA6B,EAAE;AACrC,UAAM,UAAU,WAAW,eAAe,WAAW;AACrD,UAAM,QAAyB,MAAM,QAAQ,EAAE,KAAK,IAChD,EAAE,MAAM,IAAI,CAAC,GAAQ,OAAe;AAAA,MAClC,MAAM,IAAI;AAAA,MACV,QAAQ,OAAO,GAAG,WAAW,WAAW,EAAE,SAAU,GAAG,QAAQ,QAAQ;AAAA,MACvE,QAAQ,GAAG,WAAW,GAAG;AAAA,IAC3B,EAAE,IACF,CAAC;AACL,WAAO;AAAA,MACL;AAAA,MACA,aAAa,EAAE;AAAA,MACf;AAAA,MACA,iBAAiB,EAAE;AAAA,MACnB,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,SAAS,MAAwD;AAC7E,UAAM,YAA2B,WAAmB;AACpD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,0EAA0E;AAAA,IAC5F;AACA,UAAM,QAAQ,KAAK,aAAa,0BAA0B,QAAQ,OAAO,EAAE;AAC3E,UAAM,YAAY,aAAa,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AACnF,UAAM,OAAO,KAAK,WACd,gBAAgB,KAAK,QAAQ,WAAW,KAAK,IAAI,KACjD,KAAK;AAET,UAAM,OAAO,OAAO,MAAc,SAAkB;AAClD,UAAI;AACJ,UAAI;AACF,YAAI,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,IAAI;AAAA,UACpC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,QAC3B,CAAC;AAAA,MACH,SAAS,GAAG;AACV,cAAM,IAAI;AAAA,UACR,sDAAsD,IAAI,qFAC0B,EAAY,OAAO;AAAA,QACzG;AAAA,MACF;AACA,UAAI,CAAC,EAAE,IAAI;AACT,YAAI,MAAM,GAAG,IAAI,YAAY,EAAE,MAAM;AACrC,YAAI;AAAE,gBAAM,IAAI,MAAM,EAAE,KAAK;AAAG,cAAK,GAAW,MAAO,OAAO,EAAU;AAAA,QAAM,QAAQ;AAAA,QAAQ;AAC9F,cAAM,IAAI,MAAM,oBAAoB,GAAG,EAAE;AAAA,MAC3C;AACA,aAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,IAClC;AAGA,UAAM,KAAK,0BAA0B;AAAA,MACnC;AAAA,MACA,WAAY,KAAK,SAAiB;AAAA,MAClC,iBAAiB;AAAA,IACnB,CAAC;AAGD,UAAM,KAAK,sBAAsB;AAAA,MAC/B;AAAA,MACA,MAAM;AAAA,MACN,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,YAAa,KAAK,aAAqB,eAAe;AAAA,MACtD,oBAAqB,KAAK,aAAqB;AAAA,IACjD,CAAC;AAGD,UAAM,WAAW,KAAK,IAAI,KAAK,KAAK,aAAa,KAAK;AACtD,UAAM,QAAQ,CAAC,OAAe,IAAI,QAAQ,CAAC,QAAQ,WAAW,KAAK,EAAE,CAAC;AACtE,QAAI,QAAa;AACjB,WAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,YAAM,MAAM,IAAI;AAChB,YAAM,IAAI,MAAM,UAAU,GAAG,IAAI,sBAAsB,mBAAmB,SAAS,CAAC,EAAE,EAAE,MAAM,MAAM,IAAI;AACxG,UAAI,CAAC,KAAK,CAAC,EAAE,GAAI;AACjB,cAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,IAAI;AACvC,UAAI,CAAC,SAAS,MAAM,UAAU,MAAO;AACrC,UAAI,MAAM,UAAU,MAAM,WAAW,UAAW;AAAA,IAClD;AAEA,UAAM,SAAS,OAAO;AACtB,WAAO;AAAA,MACL,SAAS,WAAW,UAAU,WAAW;AAAA,MACzC,aAAa,OAAO;AAAA,MACpB,QAAQ,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,GAAQ,OAAe;AAAA,QACtD,MAAM,IAAI;AAAA,QACV,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAAQ;AAAA,QACtC,QAAQ,GAAG,QAAQ,GAAG,QAAQ;AAAA,MAChC,EAAE;AAAA,MACF,OAAO;AAAA,QACL,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,WAAW,KAAK,IAAI,CAAC;AAAA,QAC/D,UAAU,OAAO,YAAY;AAAA,QAC7B,WAAW,OAAO,aAAa;AAAA,QAC/B,SAAS,OAAO,WAAW;AAAA,QAC3B,OAAO,OAAO,SAAS;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,KAAK,OAAoF;AAC7F,UAAM,MAAM,MAAM,KAAK,KAAK,QAAwB,8BAA8B;AAAA,MAChF,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,MAAM,EAAE,OAAO,MAAM,OAAO;AAAA,IAC9B,CAAC;AACD,UAAM,IAAI,KAAK,QAAQ,OAAO,CAAC;AAC/B,WAAO,EAAE,OAAO,EAAE,SAAS,OAAO,eAAe,EAAE,kBAAkB,MAAM,QAAQ,EAAE,OAAO;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,OAAO,OACL,MAC2C;AAC3C,QAAI,KAAK,WAAW,SAAS;AAI3B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,MAAM,MAAM,KAAK,KAAK,WAAW,qCAAqC;AAAA,MAC1E,QAAQ;AAAA,MACR,WAAW,KAAK,aAAa,KAAK;AAAA,MAClC,MAAM,KAAK,cAAc,IAAI;AAAA,MAC7B,QAAQ,KAAK;AAAA,IACf,CAAC;AAED,QAAI,OAAO;AACX,QAAI,IAAI,MAAM;AACZ,YAAM,SAAS,IAAI,KAAK,UAAU;AAClC,YAAM,UAAU,IAAI,YAAY;AAChC,aAAO,MAAM;AACX,cAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AACV,YAAI,MAAO,SAAQ,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,MAC3D;AACA,cAAQ,QAAQ,OAAO;AAAA,IACzB,OAAO;AACL,aAAO,MAAM,IAAI,KAAK;AAAA,IACxB;AAEA,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,OAAO;AAAA,IAC7B,QAAQ;AACN,YAAM,IAAI,WAAW,8CAA8C;AAAA,QACjE,KAAK,QAAQ,MAAM,GAAG,GAAG;AAAA,MAC3B,CAAC;AAAA,IACH;AACA,QAAI,UAAU,OAAO,YAAY,OAAO;AACtC,YAAM,MAAM,QAAQ,OAAO,WAAW,QAAQ,SAAS;AACvD,YAAM,IAAI,gBAAgB,OAAO,GAAG,GAAG,EAAE,MAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,CAAC;AAAA,IACnF;AACA,UAAM,SAAS,KAAK,UAAU,QAAQ,QAAQ,MAAM;AACpD,eAAW,QAAQ,OAAO,MAAO,OAAM;AACvC,UAAM,EAAE,MAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,EAC3C;AACF;;;ACtWA,IAAM,yBACJ;AAMK,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA,EAGxC,SAAiC;AACvC,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,CAAC,IAAK,OAAM,IAAI,UAAU,sBAAsB;AACpD,WAAO,EAAE,aAAa,IAAI;AAAA,EAC5B;AAAA,EAEQ,UAAa,MAAc,OAAuB,CAAC,GAAe;AACxE,WAAO,KAAK,KAAK,QAAW,MAAM;AAAA,MAChC,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,KAAK,OAAO,GAAG,GAAI,KAAK,WAAW,CAAC,EAAG;AAAA,IACvD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,OAAO,OAA6B,CAAC,GAA0B;AACnE,QAAI,KAAK,WAAW,SAAS;AAM3B,YAAM,WAAW;AACjB,YAAM,UAAU,SAAS,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC1F,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,WAAO,KAAK,UAAwB,kCAAkC;AAAA,MACpE,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,eAAe,KAAK;AAAA,QACpB,kBAAkB,KAAK;AAAA,QACvB,YAAY,KAAK;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,uBAAuB,KAAK;AAAA,QAC5B,WAAW,KAAK;AAAA,QAChB,gBAAgB,KAAK;AAAA,QACrB,UAAU,KAAK;AAAA,QACf,GAAI,KAAK,eAAe,CAAC;AAAA,MAC3B;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,WAAiD;AACzD,WAAO,KAAK;AAAA,MACV,kCAAkC,mBAAmB,SAAS,CAAC;AAAA,IACjE;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,OAA2B,CAAC,GAAmC;AACxE,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB;AAAA,MACA,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,EAAE;AAAA,IACjC;AACA,WAAO,IAAI,YAAY,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,WAA+D;AAEzE,QAAI,UAAU,WAAW,QAAQ,EAAG,QAAO,EAAE,IAAI,KAAK;AACtD,WAAO,KAAK;AAAA,MACV,kCAAkC,mBAAmB,SAAS,CAAC;AAAA,MAC/D,EAAE,QAAQ,SAAS;AAAA,IACrB;AAAA,EACF;AACF;AAEO,IAAM,uBAAN,MAA2B;AAAA,EAGhC,YAA6B,MAAkB;AAAlB;AAC3B,SAAK,WAAW,IAAI,iBAAiB,IAAI;AAAA,EAC3C;AAAA,EAEQ,SAAiC;AACvC,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,CAAC,IAAK,OAAM,IAAI,UAAU,sBAAsB;AACpD,WAAO,EAAE,aAAa,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,MAAM,MAAoD;AAC9D,WAAO,KAAK,KAAK,QAAQ,+BAA+B;AAAA,MACtD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS,KAAK,OAAO;AAAA,MACrB,WAAW,KAAK,IAAI,MAAS,KAAK,aAAa,OAAU,GAAM;AAAA,IACjE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,MAQoB;AAC/B,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA,EAAE,QAAQ,QAAQ,MAAM,MAAM,SAAS,KAAK,OAAO,GAAG,WAAW,IAAO;AAAA,IAC1E;AACA,WAAO,IAAI,WAAW,CAAC;AAAA,EACzB;AACF;;;AC5LA,IAAM,kBAAqC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,IAAI,aAA+C;AACvD,WAAO,KAAK,KAAK,QAAQ,sBAAsB,mBAAmB,WAAW,CAAC,EAAE;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KACJ,aACA,OAA8E,CAAC,GACrD;AAC1B,UAAM,YAAY,KAAK,aAAa,IAAI;AACxC,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,WAAO,MAAM;AACX,UAAI,KAAK,QAAQ,QAAS,OAAM,IAAI,aAAa,sBAAsB,WAAW,EAAE;AACpF,YAAM,OAAO,MAAM,KAAK,IAAI,WAAW;AACvC,UAAI,gBAAgB,SAAS,KAAK,MAAM,EAAG,QAAO;AAClD,UAAI,KAAK,IAAI,IAAI,UAAU;AACzB,cAAM,IAAI,aAAa,aAAa,WAAW,0BAA0B,SAAS,IAAI;AAAA,MACxF;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAK,aAAmD;AAC5D,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,sBAAsB,mBAAmB,WAAW,CAAC;AAAA,IACvD;AACA,WAAO,IAAI,QAAQ,CAAC;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,OACL,aACA,OAAiC,CAAC,GACa;AAC/C,WAAO,KAAK,KAAK;AAAA,MACf,sBAAsB,mBAAmB,WAAW,CAAC;AAAA,MACrD,EAAE,QAAQ,KAAK,OAAO;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cAAc,aAAqB,QAAkC;AACzE,WAAO,KAAK,KAAK;AAAA,MACf,sBAAsB,mBAAmB,WAAW,CAAC,UAAU,mBAAmB,MAAM,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;;;ACjEO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,MAAM,KAAK,OAAqC,CAAC,GAA8B;AAC7E,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK,EAAE;AAAA,IAC/B;AACA,WAAO,IAAI,YAAY,CAAC;AAAA,EAC1B;AAAA,EAEA,MAAM,IAAI,WAA4C;AACpD,WAAO,KAAK,KAAK,QAAQ,oBAAoB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC9E;AAAA;AAAA;AAAA,EAIA,MAAM,OAAO,MAAiD;AAC5D,WAAO,KAAK,KAAK,QAAQ,oBAAoB;AAAA,MAC3C,QAAQ;AAAA,MACR,MAAM,EAAE,MAAM,KAAK,MAAM,MAAM,QAAQ;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,WAA0C;AACrD,WAAO,KAAK,KAAK,QAAQ,oBAAoB,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAC5E,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;;;ACnCO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,MAAM,KAAK,OAAkD,CAAC,GAA+B;AAC3F,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA,EAAE,OAAO,EAAE,QAAQ,KAAK,QAAQ,YAAY,KAAK,WAAW,EAAE;AAAA,IAChE;AACA,WAAO,IAAI,aAAa,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,IAAI,YAA8C;AACtD,WAAO,KAAK,KAAK,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,EAAE;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,OAAO,MAAuD;AAClE,WAAO,KAAK,KAAK,QAAQ,qBAAqB;AAAA,MAC5C,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAO,YAAoB,OAAwF;AACvH,WAAO,KAAK,KAAK,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MAC9E,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,YAA2C;AACtD,WAAO,KAAK,KAAK,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MAC9E,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;;;AClCO,IAAM,uBAAN,MAA2B;AAAA,EAChC,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,MAAmC;AACvC,WAAO,KAAK,KAAK,QAAQ,sBAAsB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAMF;;;ACNO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,MAAM,KAAK,OAA0D,CAAC,GAA+B;AACnG,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,IAAI,EAAE;AAAA,IAChE;AACA,WAAO,IAAI,aAAa,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,IAAI,YAAsE;AAC9E,WAAO,KAAK,KAAK,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,EAAE;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,IAAI,YAAoB,OAA2B,CAAC,GAA+B;AACvF,WAAO,KAAK,KAAK;AAAA,MACf,qBAAqB,mBAAmB,UAAU,CAAC;AAAA,MACnD;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,WAAW,KAAK;AAAA,UAChB,kBAAkB,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WACJ,YACA,OAA6E,CAAC,GACpD;AAC1B,UAAM,UAAU,MAAM,KAAK,IAAI,YAAY,IAAI;AAC/C,WAAO,KAAK,aAAa,QAAQ,aAAa,KAAK,aAAa,IAAI,KAAQ,KAAK,kBAAkB,GAAK;AAAA,EAC1G;AAAA,EAEA,MAAc,aAAa,aAAqB,WAAmB,gBAAkD;AACnH,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,KAAK,KAAK;AAAA,QAC3B,sBAAsB,mBAAmB,WAAW,CAAC;AAAA,MACvD;AACA,UAAI,CAAC,aAAa,UAAU,aAAa,WAAW,EAAE,SAAS,KAAK,MAAM,EAAG,QAAO;AACpF,UAAI,KAAK,IAAI,IAAI,UAAU;AACzB,cAAM,IAAI,aAAa,aAAa,WAAW,0BAA0B,SAAS,IAAI;AAAA,MACxF;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAAA,IACxD;AAAA,EACF;AACF;;;ACrEO,IAAM,mBAAmB;AAAA;AAAA,EAE9B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASO,IAAM,0BAA0B;;;ACgCvC,IAAM,UAAN,MAAc;AAAA,EACZ,YAA6B,SAAyB;AAAzB;AAAA,EAA0B;AAAA;AAAA,EAEvD,GAAG,MAAgB,aAAqB,MAAuD;AAC7F,WAAO,KAAK,QAAQ,GAAG,MAAM,aAAa,IAAI;AAAA,EAChD;AAAA;AAAA,EAEA,KAAQ,MAAgB,QAA4E;AAClG,WAAO,KAAK,QAAQ,KAAQ,MAAM,MAAa;AAAA,EACjD;AAAA;AAAA,EAEA,KAAK,MAAgB,MAA4C;AAC/D,WAAO,KAAK,QAAQ,KAAK,MAAM,IAAI;AAAA,EACrC;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EAatB,YAAY,MAA+B;AACzC,SAAK,OAAO,IAAI,WAAW,IAAI;AAC/B,SAAK,YAAY,IAAI,kBAAkB,KAAK,IAAI;AAChD,SAAK,aAAa,IAAI,mBAAmB,KAAK,IAAI;AAClD,SAAK,eAAe,IAAI,qBAAqB,KAAK,IAAI;AACtD,SAAK,YAAY,IAAI,kBAAkB,KAAK,IAAI;AAChD,SAAK,UAAU,IAAI,QAAQ,IAAI,eAAe,KAAK,IAAI,CAAC;AACxD,SAAK,YAAY,IAAI,kBAAkB,KAAK,IAAI;AAChD,SAAK,WAAW,IAAI,iBAAiB,KAAK,IAAI;AAC9C,SAAK,eAAe,IAAI,qBAAqB,KAAK,IAAI;AAAA,EACxD;AACF;AAEA,IAAO,cAAQ;","names":[]}
@@ -5,13 +5,13 @@
5
5
  * `V2_BROWSER_MODELS` in the platform repo — that file is the canonical
6
6
  * catalog the server validates against (an unknown id hard-400s with
7
7
  * `UNSUPPORTED_MODEL` under strict validation). When that list changes,
8
- * regenerate this one. Last synced: 2026-09-0332 ids.
8
+ * regenerate this one. Last synced: 2026-09-0735 ids.
9
9
  *
10
10
  * The type stays open (`| (string & {})`) so a model the server adds
11
11
  * tomorrow works without an SDK release, while editors still autocomplete
12
12
  * the known catalog.
13
13
  */
14
- declare const AUTOPILOT_MODELS: readonly ["gemini-3.5-flash", "gemini-3.7-flash", "gemini-3.6-flash", "gemini-default", "gemini-3-flash-preview", "gemini-3.5-flash-lite", "model-a", "model-a1", "model-b", "model-j", "model-k", "model-k37", "claude-sonnet-4-6", "claude-opus-4-8", "gpt-5.6-terra", "gpt-5.6-sol", "gpt-5.5", "claude-fable-5-vision", "claude-opus-5-vision", "claude-sonnet-5-vision", "claude-sonnet-4-6-vision", "gpt-5.6-luna-vision", "gpt-5.4-vision", "gpt-4o-vision", "kimi-k3-vision", "modelc", "model-d", "model-d1", "model-e", "model-f", "model-h", "model-i"];
14
+ declare const AUTOPILOT_MODELS: readonly ["gemini-3.5-flash", "gemini-3.7-flash", "gemini-3.6-flash", "gemini-default", "gemini-3-flash-preview", "gemini-3.5-flash-lite", "model-a", "model-a1", "model-b", "model-j", "model-k", "model-k37", "claude-sonnet-4-6", "claude-opus-4-8", "gpt-5.6-terra", "gpt-5.6-sol", "gpt-5.5", "gpt-6-astra", "claude-fable-5-1-vision", "claude-fable-5-vision", "claude-opus-5-vision", "claude-sonnet-5-vision", "claude-sonnet-4-6-vision", "gpt-6-astra-vision", "gpt-5.6-luna-vision", "gpt-5.4-vision", "gpt-4o-vision", "kimi-k3-vision", "modelc", "model-d", "model-d1", "model-e", "model-f", "model-h", "model-i"];
15
15
  /** A model id from the known catalog. */
16
16
  type AutopilotModelId = (typeof AUTOPILOT_MODELS)[number];
17
17
  /** Open union: known ids autocomplete, forward-compatible strings still pass. */
@@ -5,13 +5,13 @@
5
5
  * `V2_BROWSER_MODELS` in the platform repo — that file is the canonical
6
6
  * catalog the server validates against (an unknown id hard-400s with
7
7
  * `UNSUPPORTED_MODEL` under strict validation). When that list changes,
8
- * regenerate this one. Last synced: 2026-09-0332 ids.
8
+ * regenerate this one. Last synced: 2026-09-0735 ids.
9
9
  *
10
10
  * The type stays open (`| (string & {})`) so a model the server adds
11
11
  * tomorrow works without an SDK release, while editors still autocomplete
12
12
  * the known catalog.
13
13
  */
14
- declare const AUTOPILOT_MODELS: readonly ["gemini-3.5-flash", "gemini-3.7-flash", "gemini-3.6-flash", "gemini-default", "gemini-3-flash-preview", "gemini-3.5-flash-lite", "model-a", "model-a1", "model-b", "model-j", "model-k", "model-k37", "claude-sonnet-4-6", "claude-opus-4-8", "gpt-5.6-terra", "gpt-5.6-sol", "gpt-5.5", "claude-fable-5-vision", "claude-opus-5-vision", "claude-sonnet-5-vision", "claude-sonnet-4-6-vision", "gpt-5.6-luna-vision", "gpt-5.4-vision", "gpt-4o-vision", "kimi-k3-vision", "modelc", "model-d", "model-d1", "model-e", "model-f", "model-h", "model-i"];
14
+ declare const AUTOPILOT_MODELS: readonly ["gemini-3.5-flash", "gemini-3.7-flash", "gemini-3.6-flash", "gemini-default", "gemini-3-flash-preview", "gemini-3.5-flash-lite", "model-a", "model-a1", "model-b", "model-j", "model-k", "model-k37", "claude-sonnet-4-6", "claude-opus-4-8", "gpt-5.6-terra", "gpt-5.6-sol", "gpt-5.5", "gpt-6-astra", "claude-fable-5-1-vision", "claude-fable-5-vision", "claude-opus-5-vision", "claude-sonnet-5-vision", "claude-sonnet-4-6-vision", "gpt-6-astra-vision", "gpt-5.6-luna-vision", "gpt-5.4-vision", "gpt-4o-vision", "kimi-k3-vision", "modelc", "model-d", "model-d1", "model-e", "model-f", "model-h", "model-i"];
15
15
  /** A model id from the known catalog. */
16
16
  type AutopilotModelId = (typeof AUTOPILOT_MODELS)[number];
17
17
  /** Open union: known ids autocomplete, forward-compatible strings still pass. */
package/dist/page.d.mts CHANGED
@@ -1 +1 @@
1
- export { l as CopilotHelpers, m as PageLike } from './page-8LsjwpEo.mjs';
1
+ export { l as CopilotHelpers, m as PageLike } from './page-CjBjLBLN.mjs';
package/dist/page.d.ts CHANGED
@@ -1 +1 @@
1
- export { l as CopilotHelpers, m as PageLike } from './page-8LsjwpEo.js';
1
+ export { l as CopilotHelpers, m as PageLike } from './page-CjBjLBLN.js';