@hasna/browser 0.2.5 → 0.2.6
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/cli/index.js +80 -10
- package/dist/lib/login-scripts.d.ts +5 -1
- package/dist/lib/login-scripts.d.ts.map +1 -1
- package/dist/mcp/index.js +80 -10
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -12953,6 +12953,9 @@ async function runScript(script, page, overrides = {}, jobId) {
|
|
|
12953
12953
|
case "extract":
|
|
12954
12954
|
runExtractStep(step, vars);
|
|
12955
12955
|
break;
|
|
12956
|
+
case "ai":
|
|
12957
|
+
await runAIStep(step, vars);
|
|
12958
|
+
break;
|
|
12956
12959
|
case "wait":
|
|
12957
12960
|
await new Promise((r) => setTimeout(r, (step.seconds ?? 3) * 1000));
|
|
12958
12961
|
break;
|
|
@@ -13079,7 +13082,7 @@ async function runConnectorStep(step, vars) {
|
|
|
13079
13082
|
if (!connectorName)
|
|
13080
13083
|
throw new Error("Connector step missing connector name");
|
|
13081
13084
|
const args = (step.args ?? []).map((a) => interpolate(a, vars));
|
|
13082
|
-
let
|
|
13085
|
+
let stdout = "";
|
|
13083
13086
|
try {
|
|
13084
13087
|
const bin = `connect-${connectorName}`;
|
|
13085
13088
|
const proc = Bun.spawn([bin, ...args], {
|
|
@@ -13087,18 +13090,20 @@ async function runConnectorStep(step, vars) {
|
|
|
13087
13090
|
stderr: "pipe",
|
|
13088
13091
|
env: { ...process.env, HOME: process.env.HOME ?? "" }
|
|
13089
13092
|
});
|
|
13090
|
-
|
|
13093
|
+
stdout = await new Response(proc.stdout).text();
|
|
13091
13094
|
const stderr = await new Response(proc.stderr).text();
|
|
13092
13095
|
const exitCode = await proc.exited;
|
|
13093
|
-
|
|
13096
|
+
vars["last_success"] = String(exitCode === 0);
|
|
13097
|
+
vars["last_exit_code"] = String(exitCode);
|
|
13098
|
+
if (exitCode !== 0 && stderr)
|
|
13099
|
+
stdout = stderr;
|
|
13094
13100
|
} catch (e) {
|
|
13095
|
-
|
|
13101
|
+
vars["last_success"] = "false";
|
|
13102
|
+
throw new Error(`Connector ${connectorName} failed: ${e.message ?? String(e)}`);
|
|
13096
13103
|
}
|
|
13097
|
-
vars["last_output"] =
|
|
13098
|
-
vars["last_success"] = String(result.success);
|
|
13099
|
-
vars["last_exit_code"] = String(result.exitCode);
|
|
13104
|
+
vars["last_output"] = stdout;
|
|
13100
13105
|
try {
|
|
13101
|
-
const parsed = JSON.parse(
|
|
13106
|
+
const parsed = JSON.parse(stdout);
|
|
13102
13107
|
if (typeof parsed === "object" && parsed !== null) {
|
|
13103
13108
|
for (const [k, v] of Object.entries(parsed)) {
|
|
13104
13109
|
if (typeof v === "string" || typeof v === "number") {
|
|
@@ -13108,7 +13113,64 @@ async function runConnectorStep(step, vars) {
|
|
|
13108
13113
|
}
|
|
13109
13114
|
} catch {}
|
|
13110
13115
|
if (step.save_as) {
|
|
13111
|
-
vars[step.save_as] =
|
|
13116
|
+
vars[step.save_as] = stdout;
|
|
13117
|
+
}
|
|
13118
|
+
}
|
|
13119
|
+
function getAIProvider(provider) {
|
|
13120
|
+
if (provider === "anthropic") {
|
|
13121
|
+
const apiKey2 = process.env["ANTHROPIC_API_KEY"];
|
|
13122
|
+
if (!apiKey2)
|
|
13123
|
+
throw new Error("ANTHROPIC_API_KEY not set");
|
|
13124
|
+
return {
|
|
13125
|
+
url: "https://api.anthropic.com/v1/messages",
|
|
13126
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey2, "anthropic-version": "2023-06-01" },
|
|
13127
|
+
body: (model, prompt) => ({ model, max_tokens: 1024, messages: [{ role: "user", content: prompt }] }),
|
|
13128
|
+
extract: (data) => data.content?.[0]?.text ?? ""
|
|
13129
|
+
};
|
|
13130
|
+
}
|
|
13131
|
+
const apiKey = process.env["CEREBRAS_API_KEY"];
|
|
13132
|
+
if (!apiKey)
|
|
13133
|
+
throw new Error("CEREBRAS_API_KEY not set \u2014 required for AI steps (set CEREBRAS_API_KEY or use provider: 'anthropic')");
|
|
13134
|
+
return {
|
|
13135
|
+
url: "https://api.cerebras.ai/v1/chat/completions",
|
|
13136
|
+
headers: { "content-type": "application/json", Authorization: `Bearer ${apiKey}` },
|
|
13137
|
+
body: (model, prompt) => ({ model, max_tokens: 1024, messages: [{ role: "user", content: prompt }] }),
|
|
13138
|
+
extract: (data) => data.choices?.[0]?.message?.content ?? ""
|
|
13139
|
+
};
|
|
13140
|
+
}
|
|
13141
|
+
async function runAIStep(step, vars) {
|
|
13142
|
+
const prompt = interpolate(step.prompt ?? "", vars);
|
|
13143
|
+
if (!prompt)
|
|
13144
|
+
throw new Error("AI step missing prompt");
|
|
13145
|
+
const modelAlias = step.model ?? "fast";
|
|
13146
|
+
const resolved = MODEL_MAP[modelAlias] ?? { provider: "cerebras", model: modelAlias };
|
|
13147
|
+
const saveTo = step.save_as ?? "ai_response";
|
|
13148
|
+
const provider = getAIProvider(resolved.provider);
|
|
13149
|
+
const response = await fetch(provider.url, {
|
|
13150
|
+
method: "POST",
|
|
13151
|
+
headers: provider.headers,
|
|
13152
|
+
body: JSON.stringify(provider.body(resolved.model, prompt))
|
|
13153
|
+
});
|
|
13154
|
+
if (!response.ok) {
|
|
13155
|
+
const errBody = await response.text();
|
|
13156
|
+
throw new Error(`AI API error (${response.status}): ${errBody.slice(0, 200)}`);
|
|
13157
|
+
}
|
|
13158
|
+
const data = await response.json();
|
|
13159
|
+
const text = provider.extract(data);
|
|
13160
|
+
vars[saveTo] = text;
|
|
13161
|
+
vars["last_output"] = text;
|
|
13162
|
+
if (step.response_format === "json") {
|
|
13163
|
+
try {
|
|
13164
|
+
const jsonStr = text.replace(/```json?\n?/g, "").replace(/```/g, "").trim();
|
|
13165
|
+
const parsed = JSON.parse(jsonStr);
|
|
13166
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
13167
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
13168
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
13169
|
+
vars[`${saveTo}.${k}`] = String(v);
|
|
13170
|
+
}
|
|
13171
|
+
}
|
|
13172
|
+
}
|
|
13173
|
+
} catch {}
|
|
13112
13174
|
}
|
|
13113
13175
|
}
|
|
13114
13176
|
function decodeHtmlEntities(str) {
|
|
@@ -13160,10 +13222,18 @@ function createScriptFromFile(filePath) {
|
|
|
13160
13222
|
throw new Error(`File not found: ${filePath}`);
|
|
13161
13223
|
return createScriptFromJSON(readFileSync3(filePath, "utf8"));
|
|
13162
13224
|
}
|
|
13163
|
-
var activeJobs;
|
|
13225
|
+
var activeJobs, MODEL_MAP;
|
|
13164
13226
|
var init_login_scripts = __esm(() => {
|
|
13165
13227
|
init_schema();
|
|
13166
13228
|
activeJobs = new Map;
|
|
13229
|
+
MODEL_MAP = {
|
|
13230
|
+
fast: { provider: "cerebras", model: "llama-4-scout-17b-16e-instruct" },
|
|
13231
|
+
scout: { provider: "cerebras", model: "llama-4-scout-17b-16e-instruct" },
|
|
13232
|
+
maverick: { provider: "cerebras", model: "llama-4-maverick-17b-128e-instruct" },
|
|
13233
|
+
haiku: { provider: "anthropic", model: "claude-haiku-4-5-20251001" },
|
|
13234
|
+
sonnet: { provider: "anthropic", model: "claude-sonnet-4-5-20250929" },
|
|
13235
|
+
opus: { provider: "anthropic", model: "claude-opus-4-6" }
|
|
13236
|
+
};
|
|
13167
13237
|
});
|
|
13168
13238
|
|
|
13169
13239
|
// src/lib/daemon-client.ts
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Usage: save a script once, replay with `browser login-script <name>`
|
|
6
6
|
*/
|
|
7
7
|
import type { Page } from "playwright";
|
|
8
|
-
export type StepType = "browser" | "connector" | "extract" | "wait" | "condition" | "save_state";
|
|
8
|
+
export type StepType = "browser" | "connector" | "extract" | "wait" | "condition" | "save_state" | "ai";
|
|
9
9
|
export interface ScriptStep {
|
|
10
10
|
type: StepType;
|
|
11
11
|
description?: string;
|
|
@@ -16,11 +16,15 @@ export interface ScriptStep {
|
|
|
16
16
|
value?: string;
|
|
17
17
|
timeout?: number;
|
|
18
18
|
connector?: string;
|
|
19
|
+
operation?: string;
|
|
19
20
|
args?: string[];
|
|
20
21
|
format?: string;
|
|
21
22
|
pattern?: string;
|
|
22
23
|
json_path?: string;
|
|
23
24
|
save_as?: string;
|
|
25
|
+
prompt?: string;
|
|
26
|
+
model?: string;
|
|
27
|
+
response_format?: "text" | "json";
|
|
24
28
|
seconds?: number;
|
|
25
29
|
check?: string;
|
|
26
30
|
equals?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-scripts.d.ts","sourceRoot":"","sources":["../../src/lib/login-scripts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIvC,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"login-scripts.d.ts","sourceRoot":"","sources":["../../src/lib/login-scripts.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -10710,6 +10710,9 @@ async function runScript(script, page, overrides = {}, jobId) {
|
|
|
10710
10710
|
case "extract":
|
|
10711
10711
|
runExtractStep(step, vars);
|
|
10712
10712
|
break;
|
|
10713
|
+
case "ai":
|
|
10714
|
+
await runAIStep(step, vars);
|
|
10715
|
+
break;
|
|
10713
10716
|
case "wait":
|
|
10714
10717
|
await new Promise((r) => setTimeout(r, (step.seconds ?? 3) * 1000));
|
|
10715
10718
|
break;
|
|
@@ -10836,7 +10839,7 @@ async function runConnectorStep(step, vars) {
|
|
|
10836
10839
|
if (!connectorName)
|
|
10837
10840
|
throw new Error("Connector step missing connector name");
|
|
10838
10841
|
const args = (step.args ?? []).map((a) => interpolate(a, vars));
|
|
10839
|
-
let
|
|
10842
|
+
let stdout = "";
|
|
10840
10843
|
try {
|
|
10841
10844
|
const bin = `connect-${connectorName}`;
|
|
10842
10845
|
const proc = Bun.spawn([bin, ...args], {
|
|
@@ -10844,18 +10847,20 @@ async function runConnectorStep(step, vars) {
|
|
|
10844
10847
|
stderr: "pipe",
|
|
10845
10848
|
env: { ...process.env, HOME: process.env.HOME ?? "" }
|
|
10846
10849
|
});
|
|
10847
|
-
|
|
10850
|
+
stdout = await new Response(proc.stdout).text();
|
|
10848
10851
|
const stderr = await new Response(proc.stderr).text();
|
|
10849
10852
|
const exitCode = await proc.exited;
|
|
10850
|
-
|
|
10853
|
+
vars["last_success"] = String(exitCode === 0);
|
|
10854
|
+
vars["last_exit_code"] = String(exitCode);
|
|
10855
|
+
if (exitCode !== 0 && stderr)
|
|
10856
|
+
stdout = stderr;
|
|
10851
10857
|
} catch (e) {
|
|
10852
|
-
|
|
10858
|
+
vars["last_success"] = "false";
|
|
10859
|
+
throw new Error(`Connector ${connectorName} failed: ${e.message ?? String(e)}`);
|
|
10853
10860
|
}
|
|
10854
|
-
vars["last_output"] =
|
|
10855
|
-
vars["last_success"] = String(result.success);
|
|
10856
|
-
vars["last_exit_code"] = String(result.exitCode);
|
|
10861
|
+
vars["last_output"] = stdout;
|
|
10857
10862
|
try {
|
|
10858
|
-
const parsed = JSON.parse(
|
|
10863
|
+
const parsed = JSON.parse(stdout);
|
|
10859
10864
|
if (typeof parsed === "object" && parsed !== null) {
|
|
10860
10865
|
for (const [k, v] of Object.entries(parsed)) {
|
|
10861
10866
|
if (typeof v === "string" || typeof v === "number") {
|
|
@@ -10865,7 +10870,64 @@ async function runConnectorStep(step, vars) {
|
|
|
10865
10870
|
}
|
|
10866
10871
|
} catch {}
|
|
10867
10872
|
if (step.save_as) {
|
|
10868
|
-
vars[step.save_as] =
|
|
10873
|
+
vars[step.save_as] = stdout;
|
|
10874
|
+
}
|
|
10875
|
+
}
|
|
10876
|
+
function getAIProvider(provider) {
|
|
10877
|
+
if (provider === "anthropic") {
|
|
10878
|
+
const apiKey2 = process.env["ANTHROPIC_API_KEY"];
|
|
10879
|
+
if (!apiKey2)
|
|
10880
|
+
throw new Error("ANTHROPIC_API_KEY not set");
|
|
10881
|
+
return {
|
|
10882
|
+
url: "https://api.anthropic.com/v1/messages",
|
|
10883
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey2, "anthropic-version": "2023-06-01" },
|
|
10884
|
+
body: (model, prompt) => ({ model, max_tokens: 1024, messages: [{ role: "user", content: prompt }] }),
|
|
10885
|
+
extract: (data) => data.content?.[0]?.text ?? ""
|
|
10886
|
+
};
|
|
10887
|
+
}
|
|
10888
|
+
const apiKey = process.env["CEREBRAS_API_KEY"];
|
|
10889
|
+
if (!apiKey)
|
|
10890
|
+
throw new Error("CEREBRAS_API_KEY not set \u2014 required for AI steps (set CEREBRAS_API_KEY or use provider: 'anthropic')");
|
|
10891
|
+
return {
|
|
10892
|
+
url: "https://api.cerebras.ai/v1/chat/completions",
|
|
10893
|
+
headers: { "content-type": "application/json", Authorization: `Bearer ${apiKey}` },
|
|
10894
|
+
body: (model, prompt) => ({ model, max_tokens: 1024, messages: [{ role: "user", content: prompt }] }),
|
|
10895
|
+
extract: (data) => data.choices?.[0]?.message?.content ?? ""
|
|
10896
|
+
};
|
|
10897
|
+
}
|
|
10898
|
+
async function runAIStep(step, vars) {
|
|
10899
|
+
const prompt = interpolate(step.prompt ?? "", vars);
|
|
10900
|
+
if (!prompt)
|
|
10901
|
+
throw new Error("AI step missing prompt");
|
|
10902
|
+
const modelAlias = step.model ?? "fast";
|
|
10903
|
+
const resolved = MODEL_MAP[modelAlias] ?? { provider: "cerebras", model: modelAlias };
|
|
10904
|
+
const saveTo = step.save_as ?? "ai_response";
|
|
10905
|
+
const provider = getAIProvider(resolved.provider);
|
|
10906
|
+
const response = await fetch(provider.url, {
|
|
10907
|
+
method: "POST",
|
|
10908
|
+
headers: provider.headers,
|
|
10909
|
+
body: JSON.stringify(provider.body(resolved.model, prompt))
|
|
10910
|
+
});
|
|
10911
|
+
if (!response.ok) {
|
|
10912
|
+
const errBody = await response.text();
|
|
10913
|
+
throw new Error(`AI API error (${response.status}): ${errBody.slice(0, 200)}`);
|
|
10914
|
+
}
|
|
10915
|
+
const data = await response.json();
|
|
10916
|
+
const text = provider.extract(data);
|
|
10917
|
+
vars[saveTo] = text;
|
|
10918
|
+
vars["last_output"] = text;
|
|
10919
|
+
if (step.response_format === "json") {
|
|
10920
|
+
try {
|
|
10921
|
+
const jsonStr = text.replace(/```json?\n?/g, "").replace(/```/g, "").trim();
|
|
10922
|
+
const parsed = JSON.parse(jsonStr);
|
|
10923
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
10924
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
10925
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
10926
|
+
vars[`${saveTo}.${k}`] = String(v);
|
|
10927
|
+
}
|
|
10928
|
+
}
|
|
10929
|
+
}
|
|
10930
|
+
} catch {}
|
|
10869
10931
|
}
|
|
10870
10932
|
}
|
|
10871
10933
|
function decodeHtmlEntities(str) {
|
|
@@ -10917,10 +10979,18 @@ function createScriptFromFile(filePath) {
|
|
|
10917
10979
|
throw new Error(`File not found: ${filePath}`);
|
|
10918
10980
|
return createScriptFromJSON(readFileSync3(filePath, "utf8"));
|
|
10919
10981
|
}
|
|
10920
|
-
var activeJobs;
|
|
10982
|
+
var activeJobs, MODEL_MAP;
|
|
10921
10983
|
var init_login_scripts = __esm(() => {
|
|
10922
10984
|
init_schema();
|
|
10923
10985
|
activeJobs = new Map;
|
|
10986
|
+
MODEL_MAP = {
|
|
10987
|
+
fast: { provider: "cerebras", model: "llama-4-scout-17b-16e-instruct" },
|
|
10988
|
+
scout: { provider: "cerebras", model: "llama-4-scout-17b-16e-instruct" },
|
|
10989
|
+
maverick: { provider: "cerebras", model: "llama-4-maverick-17b-128e-instruct" },
|
|
10990
|
+
haiku: { provider: "anthropic", model: "claude-haiku-4-5-20251001" },
|
|
10991
|
+
sonnet: { provider: "anthropic", model: "claude-sonnet-4-5-20250929" },
|
|
10992
|
+
opus: { provider: "anthropic", model: "claude-opus-4-6" }
|
|
10993
|
+
};
|
|
10924
10994
|
});
|
|
10925
10995
|
|
|
10926
10996
|
// src/lib/api-detector.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/browser",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "General-purpose browser agent toolkit — Playwright, Chrome DevTools Protocol, Lightpanda with auto engine selection. CLI + MCP + REST + SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|