@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/README.md CHANGED
@@ -1,336 +1,336 @@
1
- # @prompteryx/sdk
2
-
3
- Official TypeScript SDK for [Prompteryx](https://prompteryx.com).
4
-
5
- ```bash
6
- npm install @prompteryx/sdk
7
- ```
8
-
9
- Optional peers for the most-used features:
10
-
11
- ```bash
12
- npm install zod playwright-core
13
- ```
14
-
15
- Works on Node 18+ (global `fetch`), ESM **and** CommonJS.
16
-
17
- ## Authentication — two key families
18
-
19
- | Key | Format | Used by | Sent as | Rate limits |
20
- |---|---|---|---|---|
21
- | Platform API key | `px_live_…` | everything except `cloudBrowser` | `Authorization: Bearer` | 60 req/min, 10,000 req/day |
22
- | Cloud Browser key | `pcb_live_…` | `px.cloudBrowser.*` (sessions / fetch / search) | `x-api-key` | per-plan session quotas |
23
-
24
- Create the `px_live_` key in Settings → API Keys, and the `pcb_live_` key in
25
- Cloud Platform → API Keys. `px.cloudBrowser.*` throws a descriptive
26
- `AuthError` if you call it without `cloudBrowserKey`.
27
-
28
- ```ts
29
- const px = new Prompteryx({
30
- apiKey: process.env.PROMPTERYX_API_KEY!, // px_live_…
31
- cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY, // pcb_live_… (only for cloudBrowser)
32
- })
33
- ```
34
-
35
- ## Two AI surfaces — Copilot and Autopilot
36
-
37
- Prompteryx has two distinct ways AI helps you automate the browser:
38
-
39
- - **Copilot** — you drive Playwright; copilot helps with ONE step.
40
- You're in control, AI is the assistant.
41
- - **Autopilot** — you give a goal in plain English; autopilot drives
42
- the whole task end-to-end.
43
-
44
- ```ts
45
- import { Prompteryx } from '@prompteryx/sdk'
46
- import { chromium } from 'playwright-core'
47
- import { z } from 'zod'
48
-
49
- const px = new Prompteryx({
50
- apiKey: process.env.PROMPTERYX_API_KEY!,
51
- cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY,
52
- })
53
-
54
- // — Copilot: assisted single steps —
55
- const session = await px.cloudBrowser.sessions.create({
56
- useProxy: true, proxyLocation: 'us',
57
- })
58
- const browser = await chromium.connectOverCDP(session.connectUrl)
59
- const page = browser.contexts()[0].pages()[0]
60
- await page.goto('https://example.com/signup')
61
-
62
- await px.copilot.do(page, 'click the Sign up button')
63
- await px.copilot.do(page, 'fill the email field with hello@example.com')
64
-
65
- const plan = await px.copilot.read(page, z.object({
66
- name: z.string(),
67
- pricePerMonth: z.number(),
68
- features: z.array(z.string()),
69
- }))
70
-
71
- const actions = await px.copilot.scan(page, 'checkout flow')
72
-
73
- // — Autopilot: hand it a goal, it runs end-to-end —
74
- const result = await px.autopilot.run({
75
- goal: 'Find the cheapest direct flight from London to Lisbon next Tuesday and screenshot the booking page',
76
- maxSteps: 30, // default is 30
77
- saveAsWorkflow: true, // ← key superpower, see below
78
- })
79
- // result.usage → { aiCredits, tokensIn, tokensOut, costUSD, turns }
80
- ```
81
-
82
- ## Action caching = saved workflows
83
-
84
- This is Prompteryx's killer feature for cost-conscious users. Set
85
- `saveAsWorkflow: true` on any `autopilot.run` call and the discovered
86
- action sequence is captured as a permanent Visual Studio workflow:
87
-
88
- ```ts
89
- const result = await px.autopilot.run({
90
- goal: 'Apply for the Senior Engineer role at OpenAI',
91
- saveAsWorkflow: true,
92
- savedWorkflowName: 'apply-openai-senior',
93
- })
94
-
95
- // Replay forever at ZERO AI cost:
96
- await px.workflows.run(result.savedWorkflowId!)
97
- ```
98
-
99
- The saved workflow is a first-class platform object — schedulable,
100
- editable in Visual Studio, shareable, API-triggerable. It uses
101
- multi-option ranked selectors so it stays resilient to UI changes.
102
-
103
- ## Structured output + final-step vision
104
-
105
- ```ts
106
- const result = await px.autopilot.run({
107
- goal: 'Get the top 3 HN stories',
108
- outputSchema: { // finalAnswer becomes JSON matching this
109
- type: 'object',
110
- properties: {
111
- stories: {
112
- type: 'array',
113
- items: { type: 'object', properties: { title: { type: 'string' }, url: { type: 'string' } } },
114
- },
115
- },
116
- },
117
- finalStepVision: 'precision', // one extra high-quality look before answering
118
- })
119
- const data = JSON.parse(result.finalAnswer!)
120
- ```
121
-
122
- ## The SDK surface (verified against the live API)
123
-
124
- | Resource | What it does |
125
- |---|---|
126
- | `px.workflows.{list,get,run,runAndWait}` | Visual Studio workflows. |
127
- | `px.executions.{get,wait,logs,stream,getNodeOutput}` | Execution status + logs. |
128
- | `px.cloudBrowser.sessions.{create,get,list,close}` | Cloud browser sessions for your own Playwright code (`pcb_live_` key). |
129
- | `px.cloudBrowser.{fetch,search}` | One-shot page fetch + web search via the cloud browser, no session management (`pcb_live_` key). |
130
- | `px.copilot.{do,read,scan}` | Assisted single-step primitives on a Playwright page. |
131
- | `px.autopilot.{run,stream,stop}` | Autonomous multi-step agent with `saveAsWorkflow` action caching. |
132
- | `px.schedules.{list,get,create,update,delete}` | Server-side cron schedules — the platform fires them even when no client is connected. |
133
- | `px.profiles.{list,get,create,delete}` | Cloud and local Chrome profiles. |
134
- | `px.subscription.get` | Plan, balances, top-ups. |
135
-
136
- > Removed in 0.4.0 after a live-API audit: `connectHub`, `customNodes`,
137
- > `templates`, `apiKeys`, `recordings`, `subscription.usage`, and
138
- > `sessions.getDownloads/getRecording` — their routes don't exist on the
139
- > live API today (or, for `apiKeys`, can never accept API-key auth). A
140
- > smaller honest SDK beats a 404ing surface; they return when their
141
- > endpoints ship.
142
-
143
- ## Models
144
-
145
- `autopilot.run({ model })` defaults to **`gemini-3.5-flash`** (recommended —
146
- fast and cheap). The full catalog of 32 ids is exported as
147
- `AUTOPILOT_MODELS` (type `AutopilotModel`), mirrored from the platform's
148
- canonical list — highlights:
149
-
150
- - `gemini-3.5-flash` (default), `gemini-3.7-flash` (newest GA Flash),
151
- `gemini-3.6-flash`, `gemini-default` (legacy 2.5)
152
- - `claude-sonnet-4-6`, `claude-opus-4-8` (native computer use)
153
- - `gpt-5.6-terra`, `gpt-5.6-sol`, `gpt-5.5`
154
- - Vision-loop variants (`claude-fable-5-vision`, `gpt-5.6-luna-vision`, …)
155
- and experimental harness engines (`model-h`, `modelc`, …)
156
-
157
- Unknown ids are forwarded for forward-compatibility but hard-400 with
158
- `UNSUPPORTED_MODEL` under strict validation — stick to the catalog.
159
-
160
- ## One-shot fetch and search
161
-
162
- No Playwright, no session management — a real cloud Chromium loads the page
163
- (so JS-rendered sites work) and returns token-efficient content:
164
-
165
- ```ts
166
- const pageData = await px.cloudBrowser.fetch({
167
- url: 'https://example.com/pricing',
168
- format: 'markdown', // 'text' (default) | 'markdown' | 'html' | 'links'
169
- waitForSelector: '.pricing-table', // wait for JS-rendered content
170
- selectors: ['.pricing-table .plan'], // deterministic CSS extraction (count + text + html)
171
- screenshot: true, // base64 JPEG in .screenshotBase64
172
- })
173
-
174
- // Web search — DuckDuckGo in a real browser, structured results:
175
- const results = await px.cloudBrowser.search({ query: 'best CDP libraries', limit: 5 })
176
- // [{ title, url, snippet }, …]
177
- ```
178
-
179
- ## Local mode — use your own Chrome, zero cloud minutes
180
-
181
- If you want to skip cloud-browser minutes entirely, you can point the SDK at
182
- your own local Chrome via the **Prompteryx plugin + Electron runner**. Two
183
- paths connect your own Playwright over CDP (autopilot local mode is a third —
184
- covered just below):
185
-
186
- **1. `px.cloudBrowser.sessions.create({ target: 'local' })`** — returns a
187
- session whose `connectUrl` points at `http://127.0.0.1:9222`. Hand that to
188
- Playwright and drive your own Chrome:
189
-
190
- ```ts
191
- const s = await px.cloudBrowser.sessions.create({ target: 'local' })
192
- // s.connectUrl === 'http://127.0.0.1:9222'
193
- const browser = await chromium.connectOverCDP(s.connectUrl)
194
- // …drive it. No cloud minutes billed.
195
- await px.cloudBrowser.sessions.close(s.id) // no-op for local sessions
196
- ```
197
-
198
- **2. `px.workflows.run(id, { execution: { target: 'local' } })`** — runs
199
- a saved workflow against your local Chrome instead of the cloud browser:
200
-
201
- ```ts
202
- await px.workflows.run('wf_abc123', {
203
- execution: { target: 'local', chromeProfile: 'Work' },
204
- })
205
- ```
206
-
207
- **Prereqs (both paths):**
208
- - The **Prompteryx plugin** is installed in your Chrome.
209
- - The **Electron runner** is running on the same machine as the SDK consumer
210
- (the SDK talks to `localhost`, so they must co-locate).
211
- - Chrome is launched with remote debugging on port 9222. The plugin manages
212
- this for you when it's connected.
213
-
214
- ### Autopilot in local mode
215
-
216
- `px.autopilot.run({ target: 'local' })` runs the autonomous agent against
217
- your own local Chrome. Unlike the two CDP paths above, it talks **directly to
218
- the Prompteryx desktop app** at `http://localhost:61337` (override with
219
- `runnerUrl`):
220
-
221
- ```ts
222
- const result = await px.autopilot.run({
223
- target: 'local',
224
- goal: 'Open my Gmail and tell me how many unread emails I have',
225
- aiVision: 'balanced', // quality preset — lower = cheaper/faster, higher = more accurate
226
- maxSteps: 30,
227
- })
228
- ```
229
-
230
- **Requirements:** the **Prompteryx desktop app** must be **running and signed
231
- in** on this machine, and your code must run on the **same machine** (the SDK
232
- talks to `localhost`). Zero cloud-browser minutes are billed — AI Credits
233
- still apply — and the browser tab stays open after the run for inspection or
234
- follow-ups. It supports the same knobs as cloud: `model`, `aiVision` preset,
235
- `maxSteps`, `maxCredits`, `costSaving`.
236
-
237
- > `px.autopilot.stream({ target: 'local' })` throws a clear message —
238
- > use the blocking `autopilot.run` for local runs.
239
-
240
- ## Streaming an autopilot run
241
-
242
- `autopilot.stream()` runs the task over the keep-alive stream endpoint
243
- (`/api/v1/ai-browser/execute-stream`). Note the protocol: the server sends
244
- heartbeats while the run executes and the full result at the end — so steps
245
- arrive together when the run finishes (not one-by-one live), ending with a
246
- `{ step: -1, action: 'done' }` sentinel whose `result` carries the full
247
- `AutopilotRunResult`. Prefer `run()` unless you want the keep-alive
248
- transport for a long single-request run.
249
-
250
- ```ts
251
- for await (const step of px.autopilot.stream({ goal: 'Buy a ticket' })) {
252
- if (step.action === 'done') break
253
- console.log('Step', step.step, '→', step.action)
254
- }
255
- ```
256
-
257
- ## Stopping a job
258
-
259
- ```ts
260
- await px.autopilot.stop(jobId) // POST { jobId, mode: 'stop' } — stops at the next step boundary
261
- ```
262
-
263
- ## Configuration
264
-
265
- ```ts
266
- new Prompteryx({
267
- apiKey: '…', // required — px_live_…
268
- cloudBrowserKey: '…', // optional — pcb_live_…, for px.cloudBrowser.*
269
- baseUrl: 'https://prompteryx.com', // override for self-hosted
270
- timeoutMs: 60_000, // default per-request timeout
271
- maxRetries: 2, // retries for transient 5xx/network errors
272
- defaultHeaders: { 'X-Project-Id': '…' },
273
- fetch: customFetch, // for tests / non-default runtimes
274
- })
275
- ```
276
-
277
- ## Typed error handling
278
-
279
- ```ts
280
- import {
281
- AuthError, QuotaError, RateLimitError, NotFoundError,
282
- ValidationError, ServerError, NetworkError, TimeoutError, ParseError,
283
- } from '@prompteryx/sdk'
284
-
285
- try {
286
- await px.workflows.run('wf_abc')
287
- } catch (err) {
288
- if (err instanceof QuotaError) {
289
- // Out of AI Credits / cloud minutes / proxy data / etc.
290
- console.log('Exhausted resources:', err.resources)
291
- } else if (err instanceof RateLimitError) {
292
- // Back off — err.retryAfterSeconds is set when the server provided one
293
- } else {
294
- throw err
295
- }
296
- }
297
- ```
298
-
299
- ## Streaming log events
300
-
301
- ```ts
302
- const exec = await px.workflows.run('wf_abc')
303
- for await (const ev of px.executions.stream(exec.executionId)) {
304
- console.log(`[${ev.level || 'info'}]`, ev.message)
305
- if (ev.type === 'done') break
306
- }
307
- ```
308
-
309
- ## Future-proof customisation
310
-
311
- `autopilot.run` exposes every option the in-app AI Browser Agent UI
312
- exposes — model, AI Vision quality preset, final-step vision, structured
313
- output, max steps, credit cap, cost-saving batching, system-prompt
314
- override, allowed tools, viewport, proxy, recording, profile id, etc. New
315
- options added server-side ride through the `passthrough` field without an
316
- SDK release:
317
-
318
- ```ts
319
- await px.autopilot.run({
320
- goal: '...',
321
- model: 'gemini-3.7-flash', // catalog in AUTOPILOT_MODELS; default gemini-3.5-flash
322
- aiVision: 'balanced', // quality preset: lower = cheaper/faster, higher = more accurate
323
- maxCredits: 50, // hard AI-Credit cap (cost guardrail)
324
- costSaving: true, // batch several safe actions per screenshot
325
- allowedTools: ['click', 'extract'], // restrict capabilities for read-only tasks
326
- systemPromptOverride: 'Always confirm before submitting any form.',
327
- passthrough: { newServerOption: true },
328
- })
329
- ```
330
-
331
- Same passthrough pattern on `workflows.run` and
332
- `cloudBrowser.sessions.create`.
333
-
334
- ## License
335
-
336
- MIT
1
+ # @prompteryx/sdk
2
+
3
+ Official TypeScript SDK for [Prompteryx](https://www.prompteryx.ai).
4
+
5
+ ```bash
6
+ npm install @prompteryx/sdk
7
+ ```
8
+
9
+ Optional peers for the most-used features:
10
+
11
+ ```bash
12
+ npm install zod playwright-core
13
+ ```
14
+
15
+ Works on Node 18+ (global `fetch`), ESM **and** CommonJS.
16
+
17
+ ## Authentication — two key families
18
+
19
+ | Key | Format | Used by | Sent as | Rate limits |
20
+ |---|---|---|---|---|
21
+ | Platform API key | `px_live_…` | everything except `cloudBrowser` | `Authorization: Bearer` | 60 req/min, 10,000 req/day |
22
+ | Cloud Browser key | `pcb_live_…` | `px.cloudBrowser.*` (sessions / fetch / search) | `x-api-key` | per-plan session quotas |
23
+
24
+ Create the `px_live_` key in Settings → API Keys, and the `pcb_live_` key in
25
+ Cloud Platform → API Keys. `px.cloudBrowser.*` throws a descriptive
26
+ `AuthError` if you call it without `cloudBrowserKey`.
27
+
28
+ ```ts
29
+ const px = new Prompteryx({
30
+ apiKey: process.env.PROMPTERYX_API_KEY!, // px_live_…
31
+ cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY, // pcb_live_… (only for cloudBrowser)
32
+ })
33
+ ```
34
+
35
+ ## Two AI surfaces — Copilot and Autopilot
36
+
37
+ Prompteryx has two distinct ways AI helps you automate the browser:
38
+
39
+ - **Copilot** — you drive Playwright; copilot helps with ONE step.
40
+ You're in control, AI is the assistant.
41
+ - **Autopilot** — you give a goal in plain English; autopilot drives
42
+ the whole task end-to-end.
43
+
44
+ ```ts
45
+ import { Prompteryx } from '@prompteryx/sdk'
46
+ import { chromium } from 'playwright-core'
47
+ import { z } from 'zod'
48
+
49
+ const px = new Prompteryx({
50
+ apiKey: process.env.PROMPTERYX_API_KEY!,
51
+ cloudBrowserKey: process.env.PROMPTERYX_CLOUD_BROWSER_KEY,
52
+ })
53
+
54
+ // — Copilot: assisted single steps —
55
+ const session = await px.cloudBrowser.sessions.create({
56
+ useProxy: true, proxyLocation: 'us',
57
+ })
58
+ const browser = await chromium.connectOverCDP(session.connectUrl)
59
+ const page = browser.contexts()[0].pages()[0]
60
+ await page.goto('https://example.com/signup')
61
+
62
+ await px.copilot.do(page, 'click the Sign up button')
63
+ await px.copilot.do(page, 'fill the email field with hello@example.com')
64
+
65
+ const plan = await px.copilot.read(page, z.object({
66
+ name: z.string(),
67
+ pricePerMonth: z.number(),
68
+ features: z.array(z.string()),
69
+ }))
70
+
71
+ const actions = await px.copilot.scan(page, 'checkout flow')
72
+
73
+ // — Autopilot: hand it a goal, it runs end-to-end —
74
+ const result = await px.autopilot.run({
75
+ goal: 'Find the cheapest direct flight from London to Lisbon next Tuesday and screenshot the booking page',
76
+ maxSteps: 30, // default is 30
77
+ saveAsWorkflow: true, // ← key superpower, see below
78
+ })
79
+ // result.usage → { aiCredits, tokensIn, tokensOut, costUSD, turns }
80
+ ```
81
+
82
+ ## Action caching = saved workflows
83
+
84
+ This is Prompteryx's killer feature for cost-conscious users. Set
85
+ `saveAsWorkflow: true` on any `autopilot.run` call and the discovered
86
+ action sequence is captured as a permanent Visual Studio workflow:
87
+
88
+ ```ts
89
+ const result = await px.autopilot.run({
90
+ goal: 'Apply for the Senior Engineer role at OpenAI',
91
+ saveAsWorkflow: true,
92
+ savedWorkflowName: 'apply-openai-senior',
93
+ })
94
+
95
+ // Replay forever at ZERO AI cost:
96
+ await px.workflows.run(result.savedWorkflowId!)
97
+ ```
98
+
99
+ The saved workflow is a first-class platform object — schedulable,
100
+ editable in Visual Studio, shareable, API-triggerable. It uses
101
+ multi-option ranked selectors so it stays resilient to UI changes.
102
+
103
+ ## Structured output + final-step vision
104
+
105
+ ```ts
106
+ const result = await px.autopilot.run({
107
+ goal: 'Get the top 3 HN stories',
108
+ outputSchema: { // finalAnswer becomes JSON matching this
109
+ type: 'object',
110
+ properties: {
111
+ stories: {
112
+ type: 'array',
113
+ items: { type: 'object', properties: { title: { type: 'string' }, url: { type: 'string' } } },
114
+ },
115
+ },
116
+ },
117
+ finalStepVision: 'precision', // one extra high-quality look before answering
118
+ })
119
+ const data = JSON.parse(result.finalAnswer!)
120
+ ```
121
+
122
+ ## The SDK surface (verified against the live API)
123
+
124
+ | Resource | What it does |
125
+ |---|---|
126
+ | `px.workflows.{list,get,run,runAndWait}` | Visual Studio workflows. |
127
+ | `px.executions.{get,wait,logs,stream,getNodeOutput}` | Execution status + logs. |
128
+ | `px.cloudBrowser.sessions.{create,get,list,close}` | Cloud browser sessions for your own Playwright code (`pcb_live_` key). |
129
+ | `px.cloudBrowser.{fetch,search}` | One-shot page fetch + web search via the cloud browser, no session management (`pcb_live_` key). |
130
+ | `px.copilot.{do,read,scan}` | Assisted single-step primitives on a Playwright page. |
131
+ | `px.autopilot.{run,stream,stop}` | Autonomous multi-step agent with `saveAsWorkflow` action caching. |
132
+ | `px.schedules.{list,get,create,update,delete}` | Server-side cron schedules — the platform fires them even when no client is connected. |
133
+ | `px.profiles.{list,get,create,delete}` | Cloud and local Chrome profiles. |
134
+ | `px.subscription.get` | Plan, balances, top-ups. |
135
+
136
+ > Removed in 0.4.0 after a live-API audit: `connectHub`, `customNodes`,
137
+ > `templates`, `apiKeys`, `recordings`, `subscription.usage`, and
138
+ > `sessions.getDownloads/getRecording` — their routes don't exist on the
139
+ > live API today (or, for `apiKeys`, can never accept API-key auth). A
140
+ > smaller honest SDK beats a 404ing surface; they return when their
141
+ > endpoints ship.
142
+
143
+ ## Models
144
+
145
+ `autopilot.run({ model })` defaults to **`gemini-3.5-flash`** (recommended —
146
+ fast and cheap). The full catalog of 32 ids is exported as
147
+ `AUTOPILOT_MODELS` (type `AutopilotModel`), mirrored from the platform's
148
+ canonical list — highlights:
149
+
150
+ - `gemini-3.5-flash` (default), `gemini-3.7-flash` (newest GA Flash),
151
+ `gemini-3.6-flash`, `gemini-default` (legacy 2.5)
152
+ - `claude-sonnet-4-6`, `claude-opus-4-8` (native computer use)
153
+ - `gpt-5.6-terra`, `gpt-5.6-sol`, `gpt-5.5`
154
+ - Vision-loop variants (`claude-fable-5-vision`, `gpt-5.6-luna-vision`, …)
155
+ and experimental harness engines (`model-h`, `modelc`, …)
156
+
157
+ Unknown ids are forwarded for forward-compatibility but hard-400 with
158
+ `UNSUPPORTED_MODEL` under strict validation — stick to the catalog.
159
+
160
+ ## One-shot fetch and search
161
+
162
+ No Playwright, no session management — a real cloud Chromium loads the page
163
+ (so JS-rendered sites work) and returns token-efficient content:
164
+
165
+ ```ts
166
+ const pageData = await px.cloudBrowser.fetch({
167
+ url: 'https://example.com/pricing',
168
+ format: 'markdown', // 'text' (default) | 'markdown' | 'html' | 'links'
169
+ waitForSelector: '.pricing-table', // wait for JS-rendered content
170
+ selectors: ['.pricing-table .plan'], // deterministic CSS extraction (count + text + html)
171
+ screenshot: true, // base64 JPEG in .screenshotBase64
172
+ })
173
+
174
+ // Web search — DuckDuckGo in a real browser, structured results:
175
+ const results = await px.cloudBrowser.search({ query: 'best CDP libraries', limit: 5 })
176
+ // [{ title, url, snippet }, …]
177
+ ```
178
+
179
+ ## Local mode — use your own Chrome, zero cloud minutes
180
+
181
+ If you want to skip cloud-browser minutes entirely, you can point the SDK at
182
+ your own local Chrome via the **Prompteryx plugin + Electron runner**. Two
183
+ paths connect your own Playwright over CDP (autopilot local mode is a third —
184
+ covered just below):
185
+
186
+ **1. `px.cloudBrowser.sessions.create({ target: 'local' })`** — returns a
187
+ session whose `connectUrl` points at `http://127.0.0.1:9222`. Hand that to
188
+ Playwright and drive your own Chrome:
189
+
190
+ ```ts
191
+ const s = await px.cloudBrowser.sessions.create({ target: 'local' })
192
+ // s.connectUrl === 'http://127.0.0.1:9222'
193
+ const browser = await chromium.connectOverCDP(s.connectUrl)
194
+ // …drive it. No cloud minutes billed.
195
+ await px.cloudBrowser.sessions.close(s.id) // no-op for local sessions
196
+ ```
197
+
198
+ **2. `px.workflows.run(id, { execution: { target: 'local' } })`** — runs
199
+ a saved workflow against your local Chrome instead of the cloud browser:
200
+
201
+ ```ts
202
+ await px.workflows.run('wf_abc123', {
203
+ execution: { target: 'local', chromeProfile: 'Work' },
204
+ })
205
+ ```
206
+
207
+ **Prereqs (both paths):**
208
+ - The **Prompteryx plugin** is installed in your Chrome.
209
+ - The **Electron runner** is running on the same machine as the SDK consumer
210
+ (the SDK talks to `localhost`, so they must co-locate).
211
+ - Chrome is launched with remote debugging on port 9222. The plugin manages
212
+ this for you when it's connected.
213
+
214
+ ### Autopilot in local mode
215
+
216
+ `px.autopilot.run({ target: 'local' })` runs the autonomous agent against
217
+ your own local Chrome. Unlike the two CDP paths above, it talks **directly to
218
+ the Prompteryx desktop app** at `http://localhost:61337` (override with
219
+ `runnerUrl`):
220
+
221
+ ```ts
222
+ const result = await px.autopilot.run({
223
+ target: 'local',
224
+ goal: 'Open my Gmail and tell me how many unread emails I have',
225
+ aiVision: 'balanced', // quality preset — lower = cheaper/faster, higher = more accurate
226
+ maxSteps: 30,
227
+ })
228
+ ```
229
+
230
+ **Requirements:** the **Prompteryx desktop app** must be **running and signed
231
+ in** on this machine, and your code must run on the **same machine** (the SDK
232
+ talks to `localhost`). Zero cloud-browser minutes are billed — AI Credits
233
+ still apply — and the browser tab stays open after the run for inspection or
234
+ follow-ups. It supports the same knobs as cloud: `model`, `aiVision` preset,
235
+ `maxSteps`, `maxCredits`, `costSaving`.
236
+
237
+ > `px.autopilot.stream({ target: 'local' })` throws a clear message —
238
+ > use the blocking `autopilot.run` for local runs.
239
+
240
+ ## Streaming an autopilot run
241
+
242
+ `autopilot.stream()` runs the task over the keep-alive stream endpoint
243
+ (`/api/v1/ai-browser/execute-stream`). Note the protocol: the server sends
244
+ heartbeats while the run executes and the full result at the end — so steps
245
+ arrive together when the run finishes (not one-by-one live), ending with a
246
+ `{ step: -1, action: 'done' }` sentinel whose `result` carries the full
247
+ `AutopilotRunResult`. Prefer `run()` unless you want the keep-alive
248
+ transport for a long single-request run.
249
+
250
+ ```ts
251
+ for await (const step of px.autopilot.stream({ goal: 'Buy a ticket' })) {
252
+ if (step.action === 'done') break
253
+ console.log('Step', step.step, '→', step.action)
254
+ }
255
+ ```
256
+
257
+ ## Stopping a job
258
+
259
+ ```ts
260
+ await px.autopilot.stop(jobId) // POST { jobId, mode: 'stop' } — stops at the next step boundary
261
+ ```
262
+
263
+ ## Configuration
264
+
265
+ ```ts
266
+ new Prompteryx({
267
+ apiKey: '…', // required — px_live_…
268
+ cloudBrowserKey: '…', // optional — pcb_live_…, for px.cloudBrowser.*
269
+ baseUrl: 'https://www.prompteryx.ai', // override for self-hosted
270
+ timeoutMs: 60_000, // default per-request timeout
271
+ maxRetries: 2, // retries for transient 5xx/network errors
272
+ defaultHeaders: { 'X-Project-Id': '…' },
273
+ fetch: customFetch, // for tests / non-default runtimes
274
+ })
275
+ ```
276
+
277
+ ## Typed error handling
278
+
279
+ ```ts
280
+ import {
281
+ AuthError, QuotaError, RateLimitError, NotFoundError,
282
+ ValidationError, ServerError, NetworkError, TimeoutError, ParseError,
283
+ } from '@prompteryx/sdk'
284
+
285
+ try {
286
+ await px.workflows.run('wf_abc')
287
+ } catch (err) {
288
+ if (err instanceof QuotaError) {
289
+ // Out of AI Credits / cloud minutes / proxy data / etc.
290
+ console.log('Exhausted resources:', err.resources)
291
+ } else if (err instanceof RateLimitError) {
292
+ // Back off — err.retryAfterSeconds is set when the server provided one
293
+ } else {
294
+ throw err
295
+ }
296
+ }
297
+ ```
298
+
299
+ ## Streaming log events
300
+
301
+ ```ts
302
+ const exec = await px.workflows.run('wf_abc')
303
+ for await (const ev of px.executions.stream(exec.executionId)) {
304
+ console.log(`[${ev.level || 'info'}]`, ev.message)
305
+ if (ev.type === 'done') break
306
+ }
307
+ ```
308
+
309
+ ## Future-proof customisation
310
+
311
+ `autopilot.run` exposes every option the in-app AI Browser Agent UI
312
+ exposes — model, AI Vision quality preset, final-step vision, structured
313
+ output, max steps, credit cap, cost-saving batching, system-prompt
314
+ override, allowed tools, viewport, proxy, recording, profile id, etc. New
315
+ options added server-side ride through the `passthrough` field without an
316
+ SDK release:
317
+
318
+ ```ts
319
+ await px.autopilot.run({
320
+ goal: '...',
321
+ model: 'gemini-3.7-flash', // catalog in AUTOPILOT_MODELS; default gemini-3.5-flash
322
+ aiVision: 'balanced', // quality preset: lower = cheaper/faster, higher = more accurate
323
+ maxCredits: 50, // hard AI-Credit cap (cost guardrail)
324
+ costSaving: true, // batch several safe actions per screenshot
325
+ allowedTools: ['click', 'extract'], // restrict capabilities for read-only tasks
326
+ systemPromptOverride: 'Always confirm before submitting any form.',
327
+ passthrough: { newServerOption: true },
328
+ })
329
+ ```
330
+
331
+ Same passthrough pattern on `workflows.run` and
332
+ `cloudBrowser.sessions.create`.
333
+
334
+ ## License
335
+
336
+ MIT