pageqa 0.1.0 → 0.2.2

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/bsk/tools.js CHANGED
@@ -1,12 +1,112 @@
1
- import { execFileSync } from "node:child_process";
1
+ import { execFileSync, spawn } from "node:child_process";
2
2
  /**
3
3
  * browserskill(`bsk`)工具层:把 bsk CLI 命令包装成 pi-agent-core 的 AgentTool。
4
4
  *
5
5
  * bsk 连接一个已运行的真实浏览器,每个命令都需要 --session <id>。
6
6
  * 所有命令以 --quiet 抑制进度输出,仅返回结构化/可读结果。
7
7
  */
8
+ const BSK_TIMEOUT_MS = 60_000;
8
9
  function bsk(args) {
9
- return execFileSync("bsk", args, { encoding: "utf-8" }).toString();
10
+ try {
11
+ return execFileSync("bsk", args, {
12
+ encoding: "utf-8",
13
+ timeout: BSK_TIMEOUT_MS,
14
+ windowsHide: true,
15
+ }).toString();
16
+ }
17
+ catch (err) {
18
+ const e = err;
19
+ if (e.code === "ENOENT") {
20
+ throw new Error("未找到 bsk 命令:请先安装 browserskill 并确认 bsk 在 PATH 中");
21
+ }
22
+ if (e.code === "ETIMEDOUT" || e.signal === "SIGTERM") {
23
+ throw new Error(`bsk 命令执行超时(${BSK_TIMEOUT_MS / 1000}s):可能 bsk daemon 未启动或未连接浏览器。` +
24
+ `请先运行 \`bsk session start\` 并确认浏览器已连接,再重试。命令:bsk ${args.join(" ")}`);
25
+ }
26
+ throw err;
27
+ }
28
+ }
29
+ /** 运行 `bsk status --json`,成功返回解析后的对象;daemon 未运行/其他错误返回 null。
30
+ * 注意:bsk 未安装(ENOENT)是致命错误,会向上抛出。 */
31
+ function bskStatusJson() {
32
+ try {
33
+ const out = bsk(["status", "--json"]);
34
+ return JSON.parse(out);
35
+ }
36
+ catch (err) {
37
+ const e = err;
38
+ if (e.code === "ENOENT")
39
+ throw err;
40
+ return null;
41
+ }
42
+ }
43
+ /** 当前是否已连接至少一个浏览器(从 status 解析)。 */
44
+ function connectedBrowserCount() {
45
+ const status = bskStatusJson();
46
+ if (!status || !Array.isArray(status.browsers))
47
+ return 0;
48
+ return status.browsers.length;
49
+ }
50
+ /** 后台启动 bsk daemon(bsk daemon start 是前台阻塞的,必须 detached 启动后轮询等待就绪)。 */
51
+ function startDaemon() {
52
+ return new Promise((resolve, reject) => {
53
+ const child = spawn("bsk", ["daemon", "start"], {
54
+ detached: true,
55
+ stdio: "ignore",
56
+ });
57
+ child.unref();
58
+ const deadline = Date.now() + 30_000;
59
+ const poll = () => {
60
+ try {
61
+ if (child.exitCode !== null && child.exitCode !== 0) {
62
+ reject(new Error(`bsk daemon 启动失败,退出码 ${child.exitCode}`));
63
+ return;
64
+ }
65
+ }
66
+ catch {
67
+ // 子进程状态读取失败,继续轮询
68
+ }
69
+ if (bskStatusJson() !== null) {
70
+ resolve();
71
+ return;
72
+ }
73
+ if (Date.now() > deadline) {
74
+ reject(new Error("bsk daemon 启动超时(30s),请检查 bsk 安装或手动运行 `bsk daemon start`"));
75
+ return;
76
+ }
77
+ setTimeout(poll, 500);
78
+ };
79
+ setTimeout(poll, 500);
80
+ });
81
+ }
82
+ let readyPromise = null;
83
+ /**
84
+ * 自动确保 bsk 就绪:启动 daemon(若未运行)+ 校验浏览器连接(若未连则报错)。
85
+ * 整个进程只真正执行一次(readyPromise 缓存)。
86
+ */
87
+ export function ensureBskReady(debug = false) {
88
+ if (readyPromise)
89
+ return readyPromise;
90
+ const log = debug
91
+ ? (m) => process.stderr.write("[bsk] " + m + "\n")
92
+ : () => { };
93
+ readyPromise = (async () => {
94
+ if (bskStatusJson() === null) {
95
+ log("daemon 未运行,尝试启动...");
96
+ await startDaemon();
97
+ log("daemon 已启动");
98
+ }
99
+ else {
100
+ log("daemon 已在运行");
101
+ }
102
+ const n = connectedBrowserCount();
103
+ if (n === 0) {
104
+ throw new Error("bsk 未连接任何浏览器:pageqa 无法自动连接物理浏览器。\n" +
105
+ "请在浏览器中安装 bsk 扩展并完成连接(或运行 `bsk session start` 按其提示连接),再重试。");
106
+ }
107
+ log(`已连接浏览器 ${n} 个`);
108
+ })();
109
+ return readyPromise;
10
110
  }
11
111
  /** 构造 AgentTool 标准的成功返回(含必填 details 字段)。 */
12
112
  function ok(text) {
@@ -15,11 +115,13 @@ function ok(text) {
15
115
  /** 构造一组浏览器操作工具,供 page-test agent 调用。 */
16
116
  export function createBskTools(opts) {
17
117
  const s = opts.session;
118
+ const jevClient = opts.jevClient;
18
119
  const quiet = ["--session", s, "--quiet"];
19
120
  const navigate = {
20
121
  name: "navigate",
21
122
  label: "Navigate",
22
123
  description: "在浏览器标签页打开一个 URL(支持 http/https/about: 等)。导航完成后页面 DOM 就绪。",
124
+ // SAFETY: AgentTool["parameters"] 在此上下文中与 {type, properties, required} 结构兼容
23
125
  parameters: {
24
126
  type: "object",
25
127
  properties: { url: { type: "string", description: "目标 URL" } },
@@ -27,7 +129,13 @@ export function createBskTools(opts) {
27
129
  },
28
130
  execute: async (_id, params) => {
29
131
  const p = params;
30
- const out = bsk(["navigate", p.url, ...quiet, "--wait-until", "domcontentloaded"]);
132
+ const out = bsk([
133
+ "navigate",
134
+ p.url,
135
+ ...quiet,
136
+ "--wait-until",
137
+ "domcontentloaded",
138
+ ]);
31
139
  return ok(`已导航到 ${p.url}\n${out}`);
32
140
  },
33
141
  };
@@ -35,16 +143,29 @@ export function createBskTools(opts) {
35
143
  name: "snapshot",
36
144
  label: "Snapshot",
37
145
  description: "读取当前页面的 aria 语义树与可见文本(标题、段落、链接、按钮等)。用于读取内容、标题、文本并定位元素。",
38
- parameters: { type: "object", properties: {} },
39
- execute: async () => ok(bsk(["snapshot", ...quiet])),
146
+ // SAFETY: 空对象在此上下文中与 AgentTool["parameters"] 兼容
147
+ parameters: {
148
+ type: "object",
149
+ properties: {},
150
+ },
151
+ execute: async () => {
152
+ const out = bsk(["snapshot", ...quiet]);
153
+ // 快照体积直接决定上下文压力(长流程易因上下文超限被中断)
154
+ if (opts.debug)
155
+ process.stderr.write("[bsk] snapshot 字符数=" + out.length + "\n");
156
+ return ok(out);
157
+ },
40
158
  };
41
159
  const click = {
42
160
  name: "click",
43
161
  label: "Click",
44
162
  description: "点击一个元素。可用快照里的 @eN 引用或 CSS 选择器。",
163
+ // SAFETY: 结构匹配 AgentTool["parameters"]
45
164
  parameters: {
46
165
  type: "object",
47
- properties: { target: { type: "string", description: "@eN 引用或 CSS 选择器" } },
166
+ properties: {
167
+ target: { type: "string", description: "@eN 引用或 CSS 选择器" },
168
+ },
48
169
  required: ["target"],
49
170
  },
50
171
  execute: async (_id, params) => {
@@ -57,6 +178,7 @@ export function createBskTools(opts) {
57
178
  name: "fill",
58
179
  label: "Fill",
59
180
  description: "在输入框/文本域中填入文本(会先清空原有内容)。",
181
+ // SAFETY: 结构匹配 AgentTool["parameters"]
60
182
  parameters: {
61
183
  type: "object",
62
184
  properties: {
@@ -75,9 +197,12 @@ export function createBskTools(opts) {
75
197
  name: "hover",
76
198
  label: "Hover",
77
199
  description: "悬停在一个元素上,用于触发悬停菜单/提示。",
200
+ // SAFETY: 结构匹配 AgentTool["parameters"]
78
201
  parameters: {
79
202
  type: "object",
80
- properties: { target: { type: "string", description: "@eN 引用或 CSS 选择器" } },
203
+ properties: {
204
+ target: { type: "string", description: "@eN 引用或 CSS 选择器" },
205
+ },
81
206
  required: ["target"],
82
207
  },
83
208
  execute: async (_id, params) => {
@@ -90,9 +215,12 @@ export function createBskTools(opts) {
90
215
  name: "scroll",
91
216
  label: "Scroll",
92
217
  description: "滚动到指定元素使其进入视口。",
218
+ // SAFETY: 结构匹配 AgentTool["parameters"]
93
219
  parameters: {
94
220
  type: "object",
95
- properties: { target: { type: "string", description: "@eN 引用或 CSS 选择器" } },
221
+ properties: {
222
+ target: { type: "string", description: "@eN 引用或 CSS 选择器" },
223
+ },
96
224
  required: ["target"],
97
225
  },
98
226
  execute: async (_id, params) => {
@@ -106,6 +234,7 @@ export function createBskTools(opts) {
106
234
  name: "wait",
107
235
  label: "Wait",
108
236
  description: "等待一段时间(毫秒)或等待页面导航完成。",
237
+ // SAFETY: 结构匹配 AgentTool["parameters"]
109
238
  parameters: {
110
239
  type: "object",
111
240
  properties: { ms: { type: "number", description: "等待毫秒数" } },
@@ -123,17 +252,52 @@ export function createBskTools(opts) {
123
252
  name: "assert_text",
124
253
  label: "Assert Text",
125
254
  description: "断言当前页面是否包含指定文本。返回「成立」或「不成立」并附上证据(命中片段)。用于校验测试结果。",
255
+ // SAFETY: 结构匹配 AgentTool["parameters"]
126
256
  parameters: {
127
257
  type: "object",
128
- properties: { expectation: { type: "string", description: "期望在页面中出现的文本" } },
258
+ properties: {
259
+ expectation: { type: "string", description: "期望在页面中出现的文本" },
260
+ },
129
261
  required: ["expectation"],
130
262
  },
131
263
  execute: async (_id, params) => {
132
264
  const p = params;
133
265
  const snap = bsk(["snapshot", ...quiet]);
266
+ // 防御:快照为空或明显不是已加载页面 → 断言不成立。
267
+ // 浏览器页面还没打开时,bsk 返回的是空串/about:blank/错误信息,
268
+ // 此时不应信任 Jev 或直接判定「成立」(空页面不可能包含断言文本)。
269
+ const snapLen = snap.trim().length;
270
+ const SNAP_MIN_LEN = 30;
271
+ if (snapLen < SNAP_MIN_LEN) {
272
+ return ok(`断言「${p.expectation}」:不成立。证据:页面快照为空或过短(${snapLen} 字符),页面可能尚未打开或未导航`);
273
+ }
274
+ // 当 Jev 客户端可用时,使用语义判断替代字符串包含匹配
275
+ if (jevClient?.enabled) {
276
+ try {
277
+ const prob = await jevClient.assertText(snap, p.expectation);
278
+ const pass = prob >= jevClient.threshold;
279
+ const verdict = pass ? "成立" : "不成立";
280
+ const evidence = pass
281
+ ? `语义匹配度 ${(prob * 100).toFixed(1)}%,超过阈值 ${(jevClient.threshold * 100).toFixed(0)}%`
282
+ : `语义匹配度 ${(prob * 100).toFixed(1)}%,未达到阈值 ${(jevClient.threshold * 100).toFixed(0)}%`;
283
+ return ok(`断言「${p.expectation}」:${verdict}。${evidence}`);
284
+ }
285
+ catch {
286
+ // Jev 调用失败:回退到原有的字符串包含逻辑
287
+ const hit = snap.includes(p.expectation);
288
+ const verdict = hit ? "成立" : "不成立";
289
+ const evidence = hit
290
+ ? `页面中包含「${p.expectation}」`
291
+ : `页面中未找到「${p.expectation}」`;
292
+ return ok(`断言「${p.expectation}」:${verdict}。${evidence}(Jev 不可用,已回退)`);
293
+ }
294
+ }
295
+ // 默认:字符串包含匹配
134
296
  const hit = snap.includes(p.expectation);
135
297
  const verdict = hit ? "成立" : "不成立";
136
- const evidence = hit ? `页面中包含「${p.expectation}」` : `页面中未找到「${p.expectation}」`;
298
+ const evidence = hit
299
+ ? `页面中包含「${p.expectation}」`
300
+ : `页面中未找到「${p.expectation}」`;
137
301
  return ok(`断言「${p.expectation}」:${verdict}。${evidence}`);
138
302
  },
139
303
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/bsk/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/bsk/tools.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -12,10 +12,12 @@
12
12
  *
13
13
  * 首次运行(配置文件不存在)会自动创建带默认值的配置文件,便于用户日后修改。
14
14
  */
15
+ import type { JevConfig } from "./jev.js";
15
16
  export interface PageQaConfig {
16
17
  baseUrl: string;
17
18
  apiKey: string;
18
19
  model: string;
20
+ jev: JevConfig;
19
21
  }
20
22
  export declare const CONFIG_DIR: string;
21
23
  export declare const CONFIG_PATH: string;
package/dist/config.js CHANGED
@@ -5,16 +5,42 @@ const DEFAULTS = {
5
5
  baseUrl: "http://127.0.0.1:3000/v1",
6
6
  apiKey: "codebuddy-proxy-key",
7
7
  model: "hunyuan-2.0-instruct",
8
+ jev: {
9
+ enabled: false,
10
+ apiKey: "",
11
+ model: "jev-latest",
12
+ threshold: 0.5,
13
+ },
8
14
  };
9
15
  export const CONFIG_DIR = join(homedir(), ".pageqa");
10
16
  export const CONFIG_PATH = join(CONFIG_DIR, "config.json");
11
17
  /** 读取配置:合并 默认值 < 用户文件 < 环境变量。返回最终生效配置。 */
12
18
  export function loadConfig() {
13
19
  const fromFile = readConfigFile();
20
+ const fromJev = fromFile.jev ?? {};
14
21
  return {
15
22
  baseUrl: process.env.PAGEQA_LLM_BASE_URL ?? fromFile.baseUrl ?? DEFAULTS.baseUrl,
16
23
  apiKey: process.env.PAGEQA_LLM_API_KEY ?? fromFile.apiKey ?? DEFAULTS.apiKey,
17
24
  model: process.env.PAGEQA_LLM_MODEL ?? fromFile.model ?? DEFAULTS.model,
25
+ jev: {
26
+ enabled: (() => {
27
+ if (process.env.PAGEQA_JEV_ENABLED !== undefined) {
28
+ return process.env.PAGEQA_JEV_ENABLED.toLowerCase() === "true";
29
+ }
30
+ return fromJev.enabled ?? DEFAULTS.jev.enabled;
31
+ })(),
32
+ apiKey: process.env.PAGEQA_JEV_API_KEY ?? fromJev.apiKey ?? DEFAULTS.jev.apiKey,
33
+ model: process.env.PAGEQA_JEV_MODEL ?? fromJev.model ?? DEFAULTS.jev.model,
34
+ threshold: (() => {
35
+ const env = process.env.PAGEQA_JEV_THRESHOLD;
36
+ if (env != null) {
37
+ const n = Number(env);
38
+ if (!isNaN(n))
39
+ return n;
40
+ }
41
+ return fromJev.threshold ?? DEFAULTS.jev.threshold;
42
+ })(),
43
+ },
18
44
  };
19
45
  }
20
46
  /** 读取用户配置文件;不存在则创建默认文件并返回默认值。 */
@@ -31,6 +57,7 @@ function readConfigFile() {
31
57
  baseUrl: parsed.baseUrl ?? DEFAULTS.baseUrl,
32
58
  apiKey: parsed.apiKey ?? DEFAULTS.apiKey,
33
59
  model: parsed.model ?? DEFAULTS.model,
60
+ jev: parsed.jev ?? DEFAULTS.jev,
34
61
  };
35
62
  }
36
63
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAW,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAuB7E,MAAM,QAAQ,GAAiB;IAC7B,OAAO,EAAE,0BAA0B;IACnC,MAAM,EAAE,qBAAqB;IAC7B,KAAK,EAAE,sBAAsB;CAC9B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;QAChF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;QAC5E,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;KACxE,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,SAAS,cAAc;IACrB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,eAAe,EAAE,CAAC;QAClB,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACtE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;YAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;YACxC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;SACtC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC;IAC7E,OAAO,GAAG,UAAU,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0B7E,MAAM,QAAQ,GAAiB;IAC7B,OAAO,EAAE,0BAA0B;IACnC,MAAM,EAAE,qBAAqB;IAC7B,KAAK,EAAE,sBAAsB;IAC7B,GAAG,EAAE;QACH,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,GAAG;KACf;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,OAAO,GAAuB,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC;IACvD,OAAO;QACL,OAAO,EACL,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;QACzE,MAAM,EACJ,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;QACtE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;QACvE,GAAG,EAAE;YACH,OAAO,EAAE,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;oBACjD,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;gBACjE,CAAC;gBACD,OAAO,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;YACjD,CAAC,CAAC,EAAE;YACJ,MAAM,EACJ,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM;YACzE,KAAK,EACH,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK;YACrE,SAAS,EAAE,CAAC,GAAG,EAAE;gBACf,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;gBAC7C,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;oBAChB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;oBACtB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;wBAAE,OAAO,CAAC,CAAC;gBAC1B,CAAC;gBACD,OAAO,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;YACrD,CAAC,CAAC,EAAE;SACL;KACF,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,SAAS,cAAc;IACrB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,eAAe,EAAE,CAAC;QAClB,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACtE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;YAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;YACxC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;YACrC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG;SAChC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC;IAC7E,OAAO,GAAG,UAAU,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC;AAC7C,CAAC"}
package/dist/index.js CHANGED
@@ -3,7 +3,13 @@ import { readFileSync } from "node:fs";
3
3
  import { runAgent, runSuite } from "./agent.js";
4
4
  import { ensureConfigDir, CONFIG_PATH, loadConfig } from "./config.js";
5
5
  function parseArgs(argv) {
6
- const args = { json: false, suite: false, initConfig: false, help: false };
6
+ const args = {
7
+ json: false,
8
+ suite: false,
9
+ initConfig: false,
10
+ help: false,
11
+ debug: false,
12
+ };
7
13
  for (let i = 0; i < argv.length; i++) {
8
14
  const a = argv[i];
9
15
  switch (a) {
@@ -26,6 +32,9 @@ function parseArgs(argv) {
26
32
  case "--out":
27
33
  args.out = argv[++i];
28
34
  break;
35
+ case "--debug":
36
+ args.debug = true;
37
+ break;
29
38
  default:
30
39
  if (!a.startsWith("-"))
31
40
  args.input = a;
@@ -47,26 +56,35 @@ const HELP = `pageqa - 自然语言驱动的页面测试工具(pi-agent-core +
47
56
  --suite 强制按多场景套件运行(即使只有一个场景)
48
57
  --init-config 在用户目录创建/重置配置文件
49
58
  --out <file> 将报告写入文件
59
+ --debug 显示调试日志(LLM 思考、工具调用耗时、Jev 请求详情)
50
60
  -h, --help 显示帮助
51
61
 
52
62
  配置:
53
63
  - 首次运行会在用户目录自动创建配置文件:~/.pageqa/config.json
54
- (Windows: %USERPROFILE%\.pageqa\config.json)
64
+ (Windows: %USERPROFILE%\\.pageqa\\config.json)
55
65
  - 可编辑该文件设置 baseUrl / apiKey / model
56
66
  - 也可用环境变量覆盖(优先级高于配置文件):
57
67
  PAGEQA_LLM_BASE_URL / PAGEQA_LLM_API_KEY / PAGEQA_LLM_MODEL
68
+ - Jev 语义判断(可选,用于增强断言精度):
69
+ PAGEQA_JEV_ENABLED=true 启用 Jev 辅助断言
70
+ PAGEQA_JEV_API_KEY=<key> TypeSafe API 密钥
71
+ PAGEQA_JEV_MODEL=<model> Jev 模型(默认 jev-latest)
72
+ PAGEQA_JEV_THRESHOLD=<n> 判定阈值 0-1(默认 0.5)
58
73
  - 运行 pageqa --init-config 可显式创建/重置配置文件
59
74
 
60
75
  前置:
61
76
  - 已安装并启动 bsk daemon,且连接了一个浏览器(bsk session start)
62
- - CodeBuddy 本地反代可用(默认 http://127.0.0.1:3000/v1,模型 hunyuan-2.0-instruct
77
+ - 有一个可用的 OpenAI 兼容 LLM 端点(默认 http://127.0.0.1:3000/v1,模型 hunyuan-2.0-instruct
78
+ 可通过 ~/.pageqa/config.json 或 PAGEQA_LLM_* 环境变量覆盖)
63
79
 
64
80
  示例:
65
81
  pageqa --session ulao "打开 https://example.com 并断言标题包含 Example"
66
82
  pageqa examples/smoke.md --json
83
+ pageqa examples/smoke.md --debug
67
84
  `;
68
85
  function readInput(input) {
69
- if (!input.includes("\n") && (input.endsWith(".md") || input.endsWith(".txt"))) {
86
+ if (!input.includes("\n") &&
87
+ (input.endsWith(".md") || input.endsWith(".txt"))) {
70
88
  try {
71
89
  return readFileSync(input, "utf8");
72
90
  }
@@ -97,8 +115,8 @@ async function main() {
97
115
  try {
98
116
  const hasScenarios = /^##\s+/m.test(input);
99
117
  const result = hasScenarios || args.suite
100
- ? await runSuite(input, { session: args.session })
101
- : await runAgent(input, { session: args.session });
118
+ ? await runSuite(input, { session: args.session, debug: args.debug })
119
+ : await runAgent(input, { session: args.session, debug: args.debug });
102
120
  const out = args.json ? result.json : result.text;
103
121
  if (args.out) {
104
122
  const { writeFileSync } = await import("node:fs");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/jev.d.ts ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Jev(TypeSafe System One)API 客户端
3
+ *
4
+ * Jev 是一个结构化决策模型(System One),不做文本生成,只返回
5
+ * 校准后的概率分布。适合用来增强断言验证的语义判断能力。
6
+ *
7
+ * API 文档:https://docs.typesafe.ai
8
+ * Endpoint: POST https://api.typesafe.ai/v1/systemone
9
+ *
10
+ * 用法:
11
+ * const client = new JevClient(config);
12
+ * if (client.enabled) {
13
+ * const prob = await client.assertText(pageText, expectation);
14
+ * // prob ∈ [0, 1],超过阈值即判定成立
15
+ * }
16
+ */
17
+ export interface JevConfig {
18
+ enabled: boolean;
19
+ apiKey: string;
20
+ model: string;
21
+ threshold: number;
22
+ }
23
+ /** Noul 类型问题的答案 */
24
+ export interface NoulAnswer {
25
+ type: "noul";
26
+ noul: number;
27
+ }
28
+ /** Choice 类型问题的答案 */
29
+ export interface ChoiceAnswer {
30
+ type: "choice";
31
+ choice: string;
32
+ probabilities: Record<string, number>;
33
+ confidence: number;
34
+ }
35
+ /** Score 类型问题的答案 */
36
+ export interface ScoreAnswer {
37
+ type: "score";
38
+ score: number;
39
+ legend: Record<string, string>;
40
+ probabilities: Record<string, number>;
41
+ confidence: number;
42
+ }
43
+ export type Answer = NoulAnswer | ChoiceAnswer | ScoreAnswer;
44
+ export interface JevResponse {
45
+ model: string;
46
+ answers: Record<string, Answer>;
47
+ usage?: {
48
+ input_tokens: number;
49
+ output_tokens: number;
50
+ };
51
+ }
52
+ /** Jev 客户端 —— 封装对 TypeSafe API 的调用 */
53
+ export declare class JevClient {
54
+ private readonly cfg;
55
+ private readonly debug;
56
+ constructor(cfg: JevConfig, debug?: boolean);
57
+ /** 当 API 密钥不为空时视为可用 */
58
+ get enabled(): boolean;
59
+ get threshold(): number;
60
+ /**
61
+ * 向 Jev API 发送评估请求
62
+ * @param state 待评估的内容(字符串 / 对象 / 数组)
63
+ * @param questions 问题定义,key 为答案返回时的 id
64
+ */
65
+ evaluate(state: string, questions: Record<string, unknown>): Promise<JevResponse>;
66
+ /**
67
+ * 语义判断:页面文本是否匹配断言期望
68
+ * @returns 匹配概率 [0, 1]
69
+ */
70
+ assertText(pageText: string, expectation: string): Promise<number>;
71
+ }
package/dist/jev.js ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Jev(TypeSafe System One)API 客户端
3
+ *
4
+ * Jev 是一个结构化决策模型(System One),不做文本生成,只返回
5
+ * 校准后的概率分布。适合用来增强断言验证的语义判断能力。
6
+ *
7
+ * API 文档:https://docs.typesafe.ai
8
+ * Endpoint: POST https://api.typesafe.ai/v1/systemone
9
+ *
10
+ * 用法:
11
+ * const client = new JevClient(config);
12
+ * if (client.enabled) {
13
+ * const prob = await client.assertText(pageText, expectation);
14
+ * // prob ∈ [0, 1],超过阈值即判定成立
15
+ * }
16
+ */
17
+ const DEFAULT_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
18
+ const DEFAULT_TIMEOUT = 15_000; // 毫秒
19
+ /** Jev 客户端 —— 封装对 TypeSafe API 的调用 */
20
+ export class JevClient {
21
+ cfg;
22
+ debug;
23
+ constructor(cfg, debug = false) {
24
+ this.cfg = cfg;
25
+ this.debug = debug;
26
+ }
27
+ /** 当 API 密钥不为空时视为可用 */
28
+ get enabled() {
29
+ return this.cfg.enabled && Boolean(this.cfg.apiKey);
30
+ }
31
+ get threshold() {
32
+ return this.cfg.threshold;
33
+ }
34
+ /**
35
+ * 向 Jev API 发送评估请求
36
+ * @param state 待评估的内容(字符串 / 对象 / 数组)
37
+ * @param questions 问题定义,key 为答案返回时的 id
38
+ */
39
+ async evaluate(state, questions) {
40
+ const t0 = Date.now();
41
+ if (this.debug) {
42
+ process.stderr.write(`[jev] POST /v1/systemone model=${this.cfg.model} state_len=${state.length}\n`);
43
+ }
44
+ const controller = new AbortController();
45
+ const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
46
+ try {
47
+ const resp = await fetch(DEFAULT_ENDPOINT, {
48
+ method: "POST",
49
+ headers: {
50
+ "Content-Type": "application/json",
51
+ Authorization: `Bearer ${this.cfg.apiKey}`,
52
+ },
53
+ body: JSON.stringify({
54
+ model: this.cfg.model,
55
+ state,
56
+ questions,
57
+ }),
58
+ signal: controller.signal,
59
+ });
60
+ if (!resp.ok) {
61
+ const body = await resp.text();
62
+ throw new Error(`Jev API ${resp.status}: ${body}`);
63
+ }
64
+ const result = (await resp.json());
65
+ if (this.debug) {
66
+ const answer = result.answers?.["assertion_check"];
67
+ const noul = answer?.type === "noul" ? answer.noul : undefined;
68
+ process.stderr.write(`[jev] 响应 ${resp.status} 耗时=${Date.now() - t0}ms noul=${noul} usage=${JSON.stringify(result.usage)}\n`);
69
+ }
70
+ return result;
71
+ }
72
+ finally {
73
+ clearTimeout(timer);
74
+ }
75
+ }
76
+ /**
77
+ * 语义判断:页面文本是否匹配断言期望
78
+ * @returns 匹配概率 [0, 1]
79
+ */
80
+ async assertText(pageText, expectation) {
81
+ const t0 = Date.now();
82
+ if (this.debug) {
83
+ process.stderr.write(`[jev] assertText 期望="${expectation}" page_len=${pageText.length}\n`);
84
+ }
85
+ const resp = await this.evaluate(pageText, {
86
+ assertion_check: {
87
+ type: "noul",
88
+ instructions: `以下是一段浏览器页面的快照文本。请判断它是否包含或等效于给定的断言期望。考虑大小写变体、同义词、近义表达和格式差异。"${expectation}"`,
89
+ criteria: {
90
+ yes: "页面文本中包含或等效于期望的内容",
91
+ no: "页面文本中没有找到与期望相关的内容",
92
+ },
93
+ },
94
+ });
95
+ const answer = resp.answers?.["assertion_check"];
96
+ const noul = answer?.type === "noul" ? answer.noul : 0;
97
+ if (this.debug) {
98
+ process.stderr.write(`[jev] assertText 结果 noul=${noul} 阈值=${this.cfg.threshold} 耗时=${Date.now() - t0}ms\n`);
99
+ }
100
+ return noul;
101
+ }
102
+ }
103
+ //# sourceMappingURL=jev.js.map