@oya-ai/browser 1.0.77 → 1.0.79

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
@@ -44,14 +44,17 @@ const answer = await browser.ask("What are the top 3 stories and their points?")
44
44
  console.log(answer);
45
45
  ```
46
46
 
47
- ### Data pass-through: the model never sees your values
47
+ ### Data and secrets
48
48
 
49
49
  ```ts
50
- await browser.ask("Search for order {{orderNumber}} and download its invoice", {
51
- data: { orderNumber: "1042" }, // typed into the page; the LLM only reads {{orderNumber}}
50
+ await browser.ask("Log in as {{user}} with {{password}}, then book {{patient}} born {{dob}}", {
51
+ data: { patient: "John Smith", dob: "Jan 5, 1970" }, // the agent reads these
52
+ secrets: { user: "ops", password: process.env.PORTAL_PASSWORD! }, // the agent never sees these
52
53
  });
53
54
  ```
54
55
 
56
+ The agent types every value as a placeholder, transforming it with filters when a form needs a piece or another format: `{{patient|first}}`, `{{patient|last}}`, `{{dob|date:MM/DD/YYYY}}`, `{{dob|date:YYYY}}`, `{{phone|digits}}`. A playbook saved from the run stores the placeholders, never the values.
57
+
55
58
  ### Playbooks: ask once, replay without the LLM
56
59
 
57
60
  ```ts
package/dist/index.cjs CHANGED
@@ -187,18 +187,19 @@ var Browser = class {
187
187
  return result;
188
188
  }
189
189
  /**
190
- * Natural-language control, using this key's configured model. Refer to `data`
191
- * as `{{name}}` in the prompt: the agent types the placeholder, the page gets the
192
- * value, and the model never sees it.
190
+ * Natural-language control, using this key's configured model. Refer to values as
191
+ * `{{name}}` in the prompt. `data` the agent can read, so it can split a name or pick
192
+ * the matching option; `secrets` it never sees. It types both through placeholders,
193
+ * with filters like `{{name|first}}`, so a playbook saved from the run stores no values.
193
194
  */
194
- async ask(prompt, { data } = {}) {
195
+ async ask(prompt, { data, secrets } = {}) {
195
196
  const res = await this.http.request(
196
197
  "POST",
197
198
  `/api/browsers/${this.id}/chat`,
198
- { messages: [{ role: "user", content: prompt }], data },
199
+ { messages: [{ role: "user", content: prompt }], data, secrets },
199
200
  6e5
200
201
  );
201
- if (res.error) throw new OyaError(res.error, 500, res);
202
+ if (res.error) throw new OyaError(res.error, res.status ?? 500, res);
202
203
  return res.text;
203
204
  }
204
205
  /**
@@ -223,7 +224,7 @@ var Browser = class {
223
224
  { variables: data, autoHeal },
224
225
  6e5
225
226
  );
226
- if (res.error) throw new OyaError(res.error, 500, res);
227
+ if (res.error) throw new OyaError(res.error, res.status ?? 500, res);
227
228
  return res;
228
229
  }
229
230
  /**
@@ -366,7 +367,7 @@ var Run = class {
366
367
  return result;
367
368
  }
368
369
  if (run.status === "failed") {
369
- const failure = new OyaError(run.error || "Run failed", 500, run);
370
+ const failure = new OyaError(run.error || "Run failed", run.errorStatus ?? 500, run);
370
371
  await call(() => cb.onFailure?.(failure));
371
372
  throw failure;
372
373
  }
package/dist/index.d.cts CHANGED
@@ -83,7 +83,11 @@ interface PlaybookSummary extends Playbook {
83
83
  healedFrom: number;
84
84
  }) | null;
85
85
  }
86
- /** Values passed through to the page as `{{name}}` placeholders; the model never sees them. */
86
+ /**
87
+ * Task values, referred to as `{{name}}` in prompts. As `data` the agent can read them
88
+ * (to split a name or pick the right option); as `secrets` it never sees them. Either
89
+ * way they are typed through placeholders, so playbooks store no values.
90
+ */
87
91
  type RunData = Record<string, string | number>;
88
92
  interface AttentionRequest {
89
93
  id: string;
@@ -105,10 +109,14 @@ interface RunInfo {
105
109
  attention: AttentionRequest | null;
106
110
  result?: RunResult;
107
111
  error?: string;
112
+ /** HTTP-style status of a failure: 429 when a quota stopped the run. */
113
+ errorStatus?: number;
108
114
  }
109
115
  interface SubmitOptions {
110
- /** Passed through as `{{name}}` placeholders; for a playbook, its variables. */
116
+ /** Task values the agent can read; for a playbook, its variables (secret ones included). */
111
117
  data?: RunData;
118
+ /** Prompts only: values the agent never sees, like passwords. A playbook already knows which of its variables are secret. */
119
+ secrets?: RunData;
112
120
  /** Playbooks only: let the agent finish a broken replay and save its fix as a draft. Default true. */
113
121
  autoHeal?: boolean;
114
122
  onSuccess?: (result: RunResult) => unknown;
@@ -426,12 +434,14 @@ declare class Browser {
426
434
  */
427
435
  completeMfa(): Promise<MfaResult>;
428
436
  /**
429
- * Natural-language control, using this key's configured model. Refer to `data`
430
- * as `{{name}}` in the prompt: the agent types the placeholder, the page gets the
431
- * value, and the model never sees it.
437
+ * Natural-language control, using this key's configured model. Refer to values as
438
+ * `{{name}}` in the prompt. `data` the agent can read, so it can split a name or pick
439
+ * the matching option; `secrets` it never sees. It types both through placeholders,
440
+ * with filters like `{{name|first}}`, so a playbook saved from the run stores no values.
432
441
  */
433
- ask(prompt: string, { data }?: {
442
+ ask(prompt: string, { data, secrets }?: {
434
443
  data?: RunData;
444
+ secrets?: RunData;
435
445
  }): Promise<string>;
436
446
  /**
437
447
  * Save the last `ask()` on this browser as a named playbook. Values that came
package/dist/index.d.ts CHANGED
@@ -83,7 +83,11 @@ interface PlaybookSummary extends Playbook {
83
83
  healedFrom: number;
84
84
  }) | null;
85
85
  }
86
- /** Values passed through to the page as `{{name}}` placeholders; the model never sees them. */
86
+ /**
87
+ * Task values, referred to as `{{name}}` in prompts. As `data` the agent can read them
88
+ * (to split a name or pick the right option); as `secrets` it never sees them. Either
89
+ * way they are typed through placeholders, so playbooks store no values.
90
+ */
87
91
  type RunData = Record<string, string | number>;
88
92
  interface AttentionRequest {
89
93
  id: string;
@@ -105,10 +109,14 @@ interface RunInfo {
105
109
  attention: AttentionRequest | null;
106
110
  result?: RunResult;
107
111
  error?: string;
112
+ /** HTTP-style status of a failure: 429 when a quota stopped the run. */
113
+ errorStatus?: number;
108
114
  }
109
115
  interface SubmitOptions {
110
- /** Passed through as `{{name}}` placeholders; for a playbook, its variables. */
116
+ /** Task values the agent can read; for a playbook, its variables (secret ones included). */
111
117
  data?: RunData;
118
+ /** Prompts only: values the agent never sees, like passwords. A playbook already knows which of its variables are secret. */
119
+ secrets?: RunData;
112
120
  /** Playbooks only: let the agent finish a broken replay and save its fix as a draft. Default true. */
113
121
  autoHeal?: boolean;
114
122
  onSuccess?: (result: RunResult) => unknown;
@@ -426,12 +434,14 @@ declare class Browser {
426
434
  */
427
435
  completeMfa(): Promise<MfaResult>;
428
436
  /**
429
- * Natural-language control, using this key's configured model. Refer to `data`
430
- * as `{{name}}` in the prompt: the agent types the placeholder, the page gets the
431
- * value, and the model never sees it.
437
+ * Natural-language control, using this key's configured model. Refer to values as
438
+ * `{{name}}` in the prompt. `data` the agent can read, so it can split a name or pick
439
+ * the matching option; `secrets` it never sees. It types both through placeholders,
440
+ * with filters like `{{name|first}}`, so a playbook saved from the run stores no values.
432
441
  */
433
- ask(prompt: string, { data }?: {
442
+ ask(prompt: string, { data, secrets }?: {
434
443
  data?: RunData;
444
+ secrets?: RunData;
435
445
  }): Promise<string>;
436
446
  /**
437
447
  * Save the last `ask()` on this browser as a named playbook. Values that came
package/dist/index.js CHANGED
@@ -157,18 +157,19 @@ var Browser = class {
157
157
  return result;
158
158
  }
159
159
  /**
160
- * Natural-language control, using this key's configured model. Refer to `data`
161
- * as `{{name}}` in the prompt: the agent types the placeholder, the page gets the
162
- * value, and the model never sees it.
160
+ * Natural-language control, using this key's configured model. Refer to values as
161
+ * `{{name}}` in the prompt. `data` the agent can read, so it can split a name or pick
162
+ * the matching option; `secrets` it never sees. It types both through placeholders,
163
+ * with filters like `{{name|first}}`, so a playbook saved from the run stores no values.
163
164
  */
164
- async ask(prompt, { data } = {}) {
165
+ async ask(prompt, { data, secrets } = {}) {
165
166
  const res = await this.http.request(
166
167
  "POST",
167
168
  `/api/browsers/${this.id}/chat`,
168
- { messages: [{ role: "user", content: prompt }], data },
169
+ { messages: [{ role: "user", content: prompt }], data, secrets },
169
170
  6e5
170
171
  );
171
- if (res.error) throw new OyaError(res.error, 500, res);
172
+ if (res.error) throw new OyaError(res.error, res.status ?? 500, res);
172
173
  return res.text;
173
174
  }
174
175
  /**
@@ -193,7 +194,7 @@ var Browser = class {
193
194
  { variables: data, autoHeal },
194
195
  6e5
195
196
  );
196
- if (res.error) throw new OyaError(res.error, 500, res);
197
+ if (res.error) throw new OyaError(res.error, res.status ?? 500, res);
197
198
  return res;
198
199
  }
199
200
  /**
@@ -336,7 +337,7 @@ var Run = class {
336
337
  return result;
337
338
  }
338
339
  if (run.status === "failed") {
339
- const failure = new OyaError(run.error || "Run failed", 500, run);
340
+ const failure = new OyaError(run.error || "Run failed", run.errorStatus ?? 500, run);
340
341
  await call(() => cb.onFailure?.(failure));
341
342
  throw failure;
342
343
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oya-ai/browser",
3
- "version": "1.0.77",
3
+ "version": "1.0.79",
4
4
  "description": "Rotate thousands of browsers behind one API — personas, proxies, stealth, CAPTCHA and MFA.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://browser.getoya.ai",