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/README.md +70 -5
- package/dist/agent.d.ts +3 -0
- package/dist/agent.js +161 -18
- package/dist/agent.js.map +1 -1
- package/dist/bsk/tools.d.ts +8 -0
- package/dist/bsk/tools.js +174 -10
- 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 +24 -6
- 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 +2 -0
- package/dist/report.js +60 -9
- package/dist/report.js.map +1 -1
- 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,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
|
-
|
|
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([
|
|
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
|
-
|
|
39
|
-
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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
|
|
298
|
+
const evidence = hit
|
|
299
|
+
? `页面中包含「${p.expectation}」`
|
|
300
|
+
: `页面中未找到「${p.expectation}」`;
|
|
137
301
|
return ok(`断言「${p.expectation}」:${verdict}。${evidence}`);
|
|
138
302
|
},
|
|
139
303
|
};
|
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":"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 = {
|
|
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
|
|
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
|
-
-
|
|
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") &&
|
|
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":";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
|
+
}
|
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
|