pageqa 0.1.0 → 0.3.0
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 +153 -14
- package/dist/agent.d.ts +3 -0
- package/dist/agent.js +217 -19
- package/dist/agent.js.map +1 -1
- package/dist/bsk/tools.d.ts +8 -0
- package/dist/bsk/tools.js +219 -11
- package/dist/bsk/tools.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +30 -8
- package/dist/index.js.map +1 -1
- package/dist/jev.d.ts +71 -0
- package/dist/jev.js +103 -0
- package/dist/jev.js.map +1 -0
- package/dist/llm.js +6 -6
- package/dist/llm.js.map +1 -1
- package/dist/report.d.ts +11 -0
- package/dist/report.js +66 -10
- package/dist/report.js.map +1 -1
- package/dist/vars.d.ts +20 -0
- package/dist/vars.js +70 -0
- package/dist/vars.js.map +1 -0
- package/examples/element-plus-upload.md +13 -0
- package/examples/github-star.md +19 -0
- package/examples/smoke.md +0 -3
- package/package.json +7 -2
package/dist/bsk/tools.js
CHANGED
|
@@ -1,12 +1,113 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
2
3
|
/**
|
|
3
4
|
* browserskill(`bsk`)工具层:把 bsk CLI 命令包装成 pi-agent-core 的 AgentTool。
|
|
4
5
|
*
|
|
5
6
|
* bsk 连接一个已运行的真实浏览器,每个命令都需要 --session <id>。
|
|
6
7
|
* 所有命令以 --quiet 抑制进度输出,仅返回结构化/可读结果。
|
|
7
8
|
*/
|
|
9
|
+
const BSK_TIMEOUT_MS = 60_000;
|
|
8
10
|
function bsk(args) {
|
|
9
|
-
|
|
11
|
+
try {
|
|
12
|
+
return execFileSync("bsk", args, {
|
|
13
|
+
encoding: "utf-8",
|
|
14
|
+
timeout: BSK_TIMEOUT_MS,
|
|
15
|
+
windowsHide: true,
|
|
16
|
+
}).toString();
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
const e = err;
|
|
20
|
+
if (e.code === "ENOENT") {
|
|
21
|
+
throw new Error("未找到 bsk 命令:请先安装 browserskill 并确认 bsk 在 PATH 中");
|
|
22
|
+
}
|
|
23
|
+
if (e.code === "ETIMEDOUT" || e.signal === "SIGTERM") {
|
|
24
|
+
throw new Error(`bsk 命令执行超时(${BSK_TIMEOUT_MS / 1000}s):可能 bsk daemon 未启动或未连接浏览器。` +
|
|
25
|
+
`请先运行 \`bsk session start\` 并确认浏览器已连接,再重试。命令:bsk ${args.join(" ")}`);
|
|
26
|
+
}
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** 运行 `bsk status --json`,成功返回解析后的对象;daemon 未运行/其他错误返回 null。
|
|
31
|
+
* 注意:bsk 未安装(ENOENT)是致命错误,会向上抛出。 */
|
|
32
|
+
function bskStatusJson() {
|
|
33
|
+
try {
|
|
34
|
+
const out = bsk(["status", "--json"]);
|
|
35
|
+
return JSON.parse(out);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const e = err;
|
|
39
|
+
if (e.code === "ENOENT")
|
|
40
|
+
throw err;
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** 当前是否已连接至少一个浏览器(从 status 解析)。 */
|
|
45
|
+
function connectedBrowserCount() {
|
|
46
|
+
const status = bskStatusJson();
|
|
47
|
+
if (!status || !Array.isArray(status.browsers))
|
|
48
|
+
return 0;
|
|
49
|
+
return status.browsers.length;
|
|
50
|
+
}
|
|
51
|
+
/** 后台启动 bsk daemon(bsk daemon start 是前台阻塞的,必须 detached 启动后轮询等待就绪)。 */
|
|
52
|
+
function startDaemon() {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const child = spawn("bsk", ["daemon", "start"], {
|
|
55
|
+
detached: true,
|
|
56
|
+
stdio: "ignore",
|
|
57
|
+
});
|
|
58
|
+
child.unref();
|
|
59
|
+
const deadline = Date.now() + 30_000;
|
|
60
|
+
const poll = () => {
|
|
61
|
+
try {
|
|
62
|
+
if (child.exitCode !== null && child.exitCode !== 0) {
|
|
63
|
+
reject(new Error(`bsk daemon 启动失败,退出码 ${child.exitCode}`));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// 子进程状态读取失败,继续轮询
|
|
69
|
+
}
|
|
70
|
+
if (bskStatusJson() !== null) {
|
|
71
|
+
resolve();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (Date.now() > deadline) {
|
|
75
|
+
reject(new Error("bsk daemon 启动超时(30s),请检查 bsk 安装或手动运行 `bsk daemon start`"));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
setTimeout(poll, 500);
|
|
79
|
+
};
|
|
80
|
+
setTimeout(poll, 500);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
let readyPromise = null;
|
|
84
|
+
/**
|
|
85
|
+
* 自动确保 bsk 就绪:启动 daemon(若未运行)+ 校验浏览器连接(若未连则报错)。
|
|
86
|
+
* 整个进程只真正执行一次(readyPromise 缓存)。
|
|
87
|
+
*/
|
|
88
|
+
export function ensureBskReady(debug = false) {
|
|
89
|
+
if (readyPromise)
|
|
90
|
+
return readyPromise;
|
|
91
|
+
const log = debug
|
|
92
|
+
? (m) => process.stderr.write("[bsk] " + m + "\n")
|
|
93
|
+
: () => { };
|
|
94
|
+
readyPromise = (async () => {
|
|
95
|
+
if (bskStatusJson() === null) {
|
|
96
|
+
log("daemon 未运行,尝试启动...");
|
|
97
|
+
await startDaemon();
|
|
98
|
+
log("daemon 已启动");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
log("daemon 已在运行");
|
|
102
|
+
}
|
|
103
|
+
const n = connectedBrowserCount();
|
|
104
|
+
if (n === 0) {
|
|
105
|
+
throw new Error("bsk 未连接任何浏览器:pageqa 无法自动连接物理浏览器。\n" +
|
|
106
|
+
"请在浏览器中安装 bsk 扩展并完成连接(或运行 `bsk session start` 按其提示连接),再重试。");
|
|
107
|
+
}
|
|
108
|
+
log(`已连接浏览器 ${n} 个`);
|
|
109
|
+
})();
|
|
110
|
+
return readyPromise;
|
|
10
111
|
}
|
|
11
112
|
/** 构造 AgentTool 标准的成功返回(含必填 details 字段)。 */
|
|
12
113
|
function ok(text) {
|
|
@@ -15,11 +116,13 @@ function ok(text) {
|
|
|
15
116
|
/** 构造一组浏览器操作工具,供 page-test agent 调用。 */
|
|
16
117
|
export function createBskTools(opts) {
|
|
17
118
|
const s = opts.session;
|
|
119
|
+
const jevClient = opts.jevClient;
|
|
18
120
|
const quiet = ["--session", s, "--quiet"];
|
|
19
121
|
const navigate = {
|
|
20
122
|
name: "navigate",
|
|
21
123
|
label: "Navigate",
|
|
22
124
|
description: "在浏览器标签页打开一个 URL(支持 http/https/about: 等)。导航完成后页面 DOM 就绪。",
|
|
125
|
+
// SAFETY: AgentTool["parameters"] 在此上下文中与 {type, properties, required} 结构兼容
|
|
23
126
|
parameters: {
|
|
24
127
|
type: "object",
|
|
25
128
|
properties: { url: { type: "string", description: "目标 URL" } },
|
|
@@ -27,7 +130,13 @@ export function createBskTools(opts) {
|
|
|
27
130
|
},
|
|
28
131
|
execute: async (_id, params) => {
|
|
29
132
|
const p = params;
|
|
30
|
-
const out = bsk([
|
|
133
|
+
const out = bsk([
|
|
134
|
+
"navigate",
|
|
135
|
+
p.url,
|
|
136
|
+
...quiet,
|
|
137
|
+
"--wait-until",
|
|
138
|
+
"domcontentloaded",
|
|
139
|
+
]);
|
|
31
140
|
return ok(`已导航到 ${p.url}\n${out}`);
|
|
32
141
|
},
|
|
33
142
|
};
|
|
@@ -35,16 +144,29 @@ export function createBskTools(opts) {
|
|
|
35
144
|
name: "snapshot",
|
|
36
145
|
label: "Snapshot",
|
|
37
146
|
description: "读取当前页面的 aria 语义树与可见文本(标题、段落、链接、按钮等)。用于读取内容、标题、文本并定位元素。",
|
|
38
|
-
|
|
39
|
-
|
|
147
|
+
// SAFETY: 空对象在此上下文中与 AgentTool["parameters"] 兼容
|
|
148
|
+
parameters: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {},
|
|
151
|
+
},
|
|
152
|
+
execute: async () => {
|
|
153
|
+
const out = bsk(["snapshot", ...quiet]);
|
|
154
|
+
// 快照体积直接决定上下文压力(长流程易因上下文超限被中断)
|
|
155
|
+
if (opts.debug)
|
|
156
|
+
process.stderr.write("[bsk] snapshot 字符数=" + out.length + "\n");
|
|
157
|
+
return ok(out);
|
|
158
|
+
},
|
|
40
159
|
};
|
|
41
160
|
const click = {
|
|
42
161
|
name: "click",
|
|
43
162
|
label: "Click",
|
|
44
163
|
description: "点击一个元素。可用快照里的 @eN 引用或 CSS 选择器。",
|
|
164
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
45
165
|
parameters: {
|
|
46
166
|
type: "object",
|
|
47
|
-
properties: {
|
|
167
|
+
properties: {
|
|
168
|
+
target: { type: "string", description: "@eN 引用或 CSS 选择器" },
|
|
169
|
+
},
|
|
48
170
|
required: ["target"],
|
|
49
171
|
},
|
|
50
172
|
execute: async (_id, params) => {
|
|
@@ -57,6 +179,7 @@ export function createBskTools(opts) {
|
|
|
57
179
|
name: "fill",
|
|
58
180
|
label: "Fill",
|
|
59
181
|
description: "在输入框/文本域中填入文本(会先清空原有内容)。",
|
|
182
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
60
183
|
parameters: {
|
|
61
184
|
type: "object",
|
|
62
185
|
properties: {
|
|
@@ -71,13 +194,49 @@ export function createBskTools(opts) {
|
|
|
71
194
|
return ok(`已在 ${p.target} 填入文本\n${out}`);
|
|
72
195
|
},
|
|
73
196
|
};
|
|
197
|
+
const upload = {
|
|
198
|
+
name: "upload",
|
|
199
|
+
label: "Upload",
|
|
200
|
+
description: "上传本地文件到页面的文件输入框或上传区域(如 el-upload 的「Click to upload」按钮)。" +
|
|
201
|
+
"target 传触发文件选择器的元素(@eN 或 CSS 选择器),也可直接传隐藏的 <input type=\"file\">;" +
|
|
202
|
+
"不传 target 时 bsk 自动在页面中查找文件输入框。" +
|
|
203
|
+
"注意:原生文件选择框无法被自动化点击,因此不要先 click 触发按钮再调用本工具," +
|
|
204
|
+
"直接调用 upload 并指定该按钮为 target 即可。",
|
|
205
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
206
|
+
parameters: {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {
|
|
209
|
+
target: {
|
|
210
|
+
type: "string",
|
|
211
|
+
description: "触发文件选择器的元素(@eN 引用或 CSS 选择器),或 file input 本身",
|
|
212
|
+
},
|
|
213
|
+
file: { type: "string", description: "待上传的本地文件绝对路径" },
|
|
214
|
+
},
|
|
215
|
+
required: ["file"],
|
|
216
|
+
},
|
|
217
|
+
execute: async (_id, params) => {
|
|
218
|
+
const p = params;
|
|
219
|
+
if (!existsSync(p.file)) {
|
|
220
|
+
throw new Error(`待上传文件不存在:${p.file}`);
|
|
221
|
+
}
|
|
222
|
+
const args = ["upload"];
|
|
223
|
+
if (p.target)
|
|
224
|
+
args.push(p.target);
|
|
225
|
+
args.push("--file", p.file, ...quiet);
|
|
226
|
+
const out = bsk(args);
|
|
227
|
+
return ok(`已上传文件 ${p.file}\n${out}`);
|
|
228
|
+
},
|
|
229
|
+
};
|
|
74
230
|
const hover = {
|
|
75
231
|
name: "hover",
|
|
76
232
|
label: "Hover",
|
|
77
233
|
description: "悬停在一个元素上,用于触发悬停菜单/提示。",
|
|
234
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
78
235
|
parameters: {
|
|
79
236
|
type: "object",
|
|
80
|
-
properties: {
|
|
237
|
+
properties: {
|
|
238
|
+
target: { type: "string", description: "@eN 引用或 CSS 选择器" },
|
|
239
|
+
},
|
|
81
240
|
required: ["target"],
|
|
82
241
|
},
|
|
83
242
|
execute: async (_id, params) => {
|
|
@@ -90,9 +249,12 @@ export function createBskTools(opts) {
|
|
|
90
249
|
name: "scroll",
|
|
91
250
|
label: "Scroll",
|
|
92
251
|
description: "滚动到指定元素使其进入视口。",
|
|
252
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
93
253
|
parameters: {
|
|
94
254
|
type: "object",
|
|
95
|
-
properties: {
|
|
255
|
+
properties: {
|
|
256
|
+
target: { type: "string", description: "@eN 引用或 CSS 选择器" },
|
|
257
|
+
},
|
|
96
258
|
required: ["target"],
|
|
97
259
|
},
|
|
98
260
|
execute: async (_id, params) => {
|
|
@@ -106,6 +268,7 @@ export function createBskTools(opts) {
|
|
|
106
268
|
name: "wait",
|
|
107
269
|
label: "Wait",
|
|
108
270
|
description: "等待一段时间(毫秒)或等待页面导航完成。",
|
|
271
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
109
272
|
parameters: {
|
|
110
273
|
type: "object",
|
|
111
274
|
properties: { ms: { type: "number", description: "等待毫秒数" } },
|
|
@@ -123,21 +286,66 @@ export function createBskTools(opts) {
|
|
|
123
286
|
name: "assert_text",
|
|
124
287
|
label: "Assert Text",
|
|
125
288
|
description: "断言当前页面是否包含指定文本。返回「成立」或「不成立」并附上证据(命中片段)。用于校验测试结果。",
|
|
289
|
+
// SAFETY: 结构匹配 AgentTool["parameters"]
|
|
126
290
|
parameters: {
|
|
127
291
|
type: "object",
|
|
128
|
-
properties: {
|
|
292
|
+
properties: {
|
|
293
|
+
expectation: { type: "string", description: "期望在页面中出现的文本" },
|
|
294
|
+
},
|
|
129
295
|
required: ["expectation"],
|
|
130
296
|
},
|
|
131
297
|
execute: async (_id, params) => {
|
|
132
298
|
const p = params;
|
|
133
299
|
const snap = bsk(["snapshot", ...quiet]);
|
|
300
|
+
// 防御:快照为空或明显不是已加载页面 → 断言不成立。
|
|
301
|
+
// 浏览器页面还没打开时,bsk 返回的是空串/about:blank/错误信息,
|
|
302
|
+
// 此时不应信任 Jev 或直接判定「成立」(空页面不可能包含断言文本)。
|
|
303
|
+
const snapLen = snap.trim().length;
|
|
304
|
+
const SNAP_MIN_LEN = 30;
|
|
305
|
+
if (snapLen < SNAP_MIN_LEN) {
|
|
306
|
+
return ok(`断言「${p.expectation}」:不成立。证据:页面快照为空或过短(${snapLen} 字符),页面可能尚未打开或未导航`);
|
|
307
|
+
}
|
|
308
|
+
// 当 Jev 客户端可用时,使用语义判断替代字符串包含匹配
|
|
309
|
+
if (jevClient?.enabled) {
|
|
310
|
+
try {
|
|
311
|
+
const prob = await jevClient.assertText(snap, p.expectation);
|
|
312
|
+
const pass = prob >= jevClient.threshold;
|
|
313
|
+
const verdict = pass ? "成立" : "不成立";
|
|
314
|
+
const evidence = pass
|
|
315
|
+
? `语义匹配度 ${(prob * 100).toFixed(1)}%,超过阈值 ${(jevClient.threshold * 100).toFixed(0)}%`
|
|
316
|
+
: `语义匹配度 ${(prob * 100).toFixed(1)}%,未达到阈值 ${(jevClient.threshold * 100).toFixed(0)}%`;
|
|
317
|
+
return ok(`断言「${p.expectation}」:${verdict}。${evidence}`);
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
// Jev 调用失败:回退到原有的字符串包含逻辑
|
|
321
|
+
const hit = snap.includes(p.expectation);
|
|
322
|
+
const verdict = hit ? "成立" : "不成立";
|
|
323
|
+
const evidence = hit
|
|
324
|
+
? `页面中包含「${p.expectation}」`
|
|
325
|
+
: `页面中未找到「${p.expectation}」`;
|
|
326
|
+
return ok(`断言「${p.expectation}」:${verdict}。${evidence}(Jev 不可用,已回退)`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// 默认:字符串包含匹配
|
|
134
330
|
const hit = snap.includes(p.expectation);
|
|
135
331
|
const verdict = hit ? "成立" : "不成立";
|
|
136
|
-
const evidence = hit
|
|
332
|
+
const evidence = hit
|
|
333
|
+
? `页面中包含「${p.expectation}」`
|
|
334
|
+
: `页面中未找到「${p.expectation}」`;
|
|
137
335
|
return ok(`断言「${p.expectation}」:${verdict}。${evidence}`);
|
|
138
336
|
},
|
|
139
337
|
};
|
|
140
|
-
return [
|
|
338
|
+
return [
|
|
339
|
+
navigate,
|
|
340
|
+
snapshot,
|
|
341
|
+
click,
|
|
342
|
+
fill,
|
|
343
|
+
upload,
|
|
344
|
+
hover,
|
|
345
|
+
scroll,
|
|
346
|
+
wait,
|
|
347
|
+
assertText,
|
|
348
|
+
];
|
|
141
349
|
}
|
|
142
350
|
/** 创建一个 bsk session;若已提供且仍在活跃列表中则复用,否则新建。 */
|
|
143
351
|
export function ensureSession(existing) {
|
package/dist/bsk/tools.js.map
CHANGED
|
@@ -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 {
|
package/dist/config.js.map
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { runAgent, runSuite } from "./agent.js";
|
|
4
4
|
import { ensureConfigDir, CONFIG_PATH, loadConfig } from "./config.js";
|
|
5
|
+
import { expandVars, VAR_HELP } from "./vars.js";
|
|
5
6
|
function parseArgs(argv) {
|
|
6
|
-
const args = {
|
|
7
|
+
const args = {
|
|
8
|
+
json: false,
|
|
9
|
+
suite: false,
|
|
10
|
+
initConfig: false,
|
|
11
|
+
help: false,
|
|
12
|
+
debug: false,
|
|
13
|
+
};
|
|
7
14
|
for (let i = 0; i < argv.length; i++) {
|
|
8
15
|
const a = argv[i];
|
|
9
16
|
switch (a) {
|
|
@@ -26,6 +33,9 @@ function parseArgs(argv) {
|
|
|
26
33
|
case "--out":
|
|
27
34
|
args.out = argv[++i];
|
|
28
35
|
break;
|
|
36
|
+
case "--debug":
|
|
37
|
+
args.debug = true;
|
|
38
|
+
break;
|
|
29
39
|
default:
|
|
30
40
|
if (!a.startsWith("-"))
|
|
31
41
|
args.input = a;
|
|
@@ -47,34 +57,46 @@ const HELP = `pageqa - 自然语言驱动的页面测试工具(pi-agent-core +
|
|
|
47
57
|
--suite 强制按多场景套件运行(即使只有一个场景)
|
|
48
58
|
--init-config 在用户目录创建/重置配置文件
|
|
49
59
|
--out <file> 将报告写入文件
|
|
60
|
+
--debug 显示调试日志(LLM 思考、工具调用耗时、Jev 请求详情)
|
|
50
61
|
-h, --help 显示帮助
|
|
51
62
|
|
|
63
|
+
脚本占位符:
|
|
64
|
+
${VAR_HELP}
|
|
65
|
+
|
|
52
66
|
配置:
|
|
53
67
|
- 首次运行会在用户目录自动创建配置文件:~/.pageqa/config.json
|
|
54
|
-
(Windows: %USERPROFILE
|
|
68
|
+
(Windows: %USERPROFILE%\\.pageqa\\config.json)
|
|
55
69
|
- 可编辑该文件设置 baseUrl / apiKey / model
|
|
56
70
|
- 也可用环境变量覆盖(优先级高于配置文件):
|
|
57
71
|
PAGEQA_LLM_BASE_URL / PAGEQA_LLM_API_KEY / PAGEQA_LLM_MODEL
|
|
72
|
+
- Jev 语义判断(可选,用于增强断言精度):
|
|
73
|
+
PAGEQA_JEV_ENABLED=true 启用 Jev 辅助断言
|
|
74
|
+
PAGEQA_JEV_API_KEY=<key> TypeSafe API 密钥
|
|
75
|
+
PAGEQA_JEV_MODEL=<model> Jev 模型(默认 jev-latest)
|
|
76
|
+
PAGEQA_JEV_THRESHOLD=<n> 判定阈值 0-1(默认 0.5)
|
|
58
77
|
- 运行 pageqa --init-config 可显式创建/重置配置文件
|
|
59
78
|
|
|
60
79
|
前置:
|
|
61
80
|
- 已安装并启动 bsk daemon,且连接了一个浏览器(bsk session start)
|
|
62
|
-
-
|
|
81
|
+
- 有一个可用的 OpenAI 兼容 LLM 端点(默认 http://127.0.0.1:3000/v1,模型 hunyuan-2.0-instruct,
|
|
82
|
+
可通过 ~/.pageqa/config.json 或 PAGEQA_LLM_* 环境变量覆盖)
|
|
63
83
|
|
|
64
84
|
示例:
|
|
65
85
|
pageqa --session ulao "打开 https://example.com 并断言标题包含 Example"
|
|
66
86
|
pageqa examples/smoke.md --json
|
|
87
|
+
pageqa examples/smoke.md --debug
|
|
67
88
|
`;
|
|
68
89
|
function readInput(input) {
|
|
69
|
-
if (!input.includes("\n") &&
|
|
90
|
+
if (!input.includes("\n") &&
|
|
91
|
+
(input.endsWith(".md") || input.endsWith(".txt"))) {
|
|
70
92
|
try {
|
|
71
|
-
return readFileSync(input, "utf8");
|
|
93
|
+
return expandVars(readFileSync(input, "utf8"));
|
|
72
94
|
}
|
|
73
95
|
catch {
|
|
74
96
|
// 不是文件:视为内联文本
|
|
75
97
|
}
|
|
76
98
|
}
|
|
77
|
-
return input;
|
|
99
|
+
return expandVars(input);
|
|
78
100
|
}
|
|
79
101
|
async function main() {
|
|
80
102
|
const args = parseArgs(process.argv.slice(2));
|
|
@@ -97,8 +119,8 @@ async function main() {
|
|
|
97
119
|
try {
|
|
98
120
|
const hasScenarios = /^##\s+/m.test(input);
|
|
99
121
|
const result = hasScenarios || args.suite
|
|
100
|
-
? await runSuite(input, { session: args.session })
|
|
101
|
-
: await runAgent(input, { session: args.session });
|
|
122
|
+
? await runSuite(input, { session: args.session, debug: args.debug })
|
|
123
|
+
: await runAgent(input, { session: args.session, debug: args.debug });
|
|
102
124
|
const out = args.json ? result.json : result.text;
|
|
103
125
|
if (args.out) {
|
|
104
126
|
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":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,WAAW,
|
|
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
|
+
}
|