u1s1-cli 1.11.0 → 1.11.1
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/bench.js +19 -24
- package/package.json +1 -1
- package/scripts/patch-pi.js +20 -12
package/dist/bench.js
CHANGED
|
@@ -82,6 +82,24 @@ function listSuites() {
|
|
|
82
82
|
return suites;
|
|
83
83
|
}
|
|
84
84
|
// ─── 模型调用 ───
|
|
85
|
+
function asRecord(value) {
|
|
86
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
87
|
+
}
|
|
88
|
+
function tokenCount(value) {
|
|
89
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
90
|
+
}
|
|
91
|
+
/** 只认 OpenAI 兼容形状:choices[0].message.content 与 usage.prompt/completion_tokens,缺哪项哪项归零。 */
|
|
92
|
+
function parseChatCompletion(value) {
|
|
93
|
+
const data = asRecord(value);
|
|
94
|
+
const choices = Array.isArray(data?.choices) ? data.choices : [];
|
|
95
|
+
const message = asRecord(asRecord(choices[0])?.message);
|
|
96
|
+
const usage = asRecord(data?.usage);
|
|
97
|
+
return {
|
|
98
|
+
response: typeof message?.content === "string" ? message.content : "",
|
|
99
|
+
tokensIn: tokenCount(usage?.prompt_tokens),
|
|
100
|
+
tokensOut: tokenCount(usage?.completion_tokens),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
85
103
|
async function callModel(input) {
|
|
86
104
|
const { baseUrl, apiKey, modelId, prompt, officialCfg } = input;
|
|
87
105
|
const start = performance.now();
|
|
@@ -111,30 +129,7 @@ async function callModel(input) {
|
|
|
111
129
|
const errBody = await readResponseTextCapped(res, 64 * 1024).catch(() => "未知错误");
|
|
112
130
|
return { response: "", latencyMs, tokensIn: 0, tokensOut: 0, error: `HTTP ${res.status}: ${errBody.slice(0, 200)}` };
|
|
113
131
|
}
|
|
114
|
-
|
|
115
|
-
const data = value && typeof value === "object" && !Array.isArray(value)
|
|
116
|
-
? value
|
|
117
|
-
: null;
|
|
118
|
-
const choices = Array.isArray(data?.choices) ? data.choices : [];
|
|
119
|
-
const firstChoice = choices[0] && typeof choices[0] === "object" && !Array.isArray(choices[0])
|
|
120
|
-
? choices[0]
|
|
121
|
-
: null;
|
|
122
|
-
const message = firstChoice?.message && typeof firstChoice.message === "object" && !Array.isArray(firstChoice.message)
|
|
123
|
-
? firstChoice.message
|
|
124
|
-
: null;
|
|
125
|
-
const usage = data?.usage && typeof data.usage === "object" && !Array.isArray(data.usage)
|
|
126
|
-
? data.usage
|
|
127
|
-
: null;
|
|
128
|
-
return {
|
|
129
|
-
response: typeof message?.content === "string" ? message.content : "",
|
|
130
|
-
latencyMs,
|
|
131
|
-
tokensIn: typeof usage?.prompt_tokens === "number" && Number.isFinite(usage.prompt_tokens)
|
|
132
|
-
? Math.max(0, usage.prompt_tokens)
|
|
133
|
-
: 0,
|
|
134
|
-
tokensOut: typeof usage?.completion_tokens === "number" && Number.isFinite(usage.completion_tokens)
|
|
135
|
-
? Math.max(0, usage.completion_tokens)
|
|
136
|
-
: 0,
|
|
137
|
-
};
|
|
132
|
+
return { ...parseChatCompletion(await readJsonResponseCapped(res)), latencyMs };
|
|
138
133
|
}
|
|
139
134
|
catch (e) {
|
|
140
135
|
const latencyMs = Math.round(performance.now() - start);
|
package/package.json
CHANGED
package/scripts/patch-pi.js
CHANGED
|
@@ -391,23 +391,31 @@ const TUI_TEXT_TARGETS = [
|
|
|
391
391
|
[["modes", "interactive", "components", "settings-selector.js"], SETTINGS_REPLACEMENTS, "设置菜单"],
|
|
392
392
|
];
|
|
393
393
|
|
|
394
|
+
/**
|
|
395
|
+
* 逐条套文案替换规则:已替换过的算应用成功(幂等),出现次数与预期不符的跳过
|
|
396
|
+
* (pi 升级后上下文变了,宁可不改也不误改)。
|
|
397
|
+
*/
|
|
398
|
+
function applyTextRules(text, rules) {
|
|
399
|
+
let applied = 0;
|
|
400
|
+
for (const rule of rules) {
|
|
401
|
+
const { from, to, expected } = Array.isArray(rule) ? { from: rule[0], to: rule[1], expected: 1 } : rule;
|
|
402
|
+
if (text.includes(to)) {
|
|
403
|
+
applied++;
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
if (text.split(from).length !== expected + 1) continue;
|
|
407
|
+
text = text.split(from).join(to);
|
|
408
|
+
applied++;
|
|
409
|
+
}
|
|
410
|
+
return { text, applied };
|
|
411
|
+
}
|
|
412
|
+
|
|
394
413
|
function patchTuiText() {
|
|
395
414
|
for (const piDir of findPackageDirs("@earendil-works/pi-coding-agent")) {
|
|
396
415
|
for (const [parts, rules, label] of TUI_TEXT_TARGETS) {
|
|
397
416
|
const target = join(piDir, "dist", ...parts);
|
|
398
417
|
try {
|
|
399
|
-
|
|
400
|
-
let applied = 0;
|
|
401
|
-
for (const rule of rules) {
|
|
402
|
-
const { from, to, expected } = Array.isArray(rule) ? { from: rule[0], to: rule[1], expected: 1 } : rule;
|
|
403
|
-
if (text.includes(to)) {
|
|
404
|
-
applied++;
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
if (text.split(from).length !== expected + 1) continue;
|
|
408
|
-
text = text.split(from).join(to);
|
|
409
|
-
applied++;
|
|
410
|
-
}
|
|
418
|
+
const { text, applied } = applyTextRules(readFileSync(target, "utf8"), rules);
|
|
411
419
|
if (applied < rules.length) {
|
|
412
420
|
console.log(
|
|
413
421
|
`[u1s1] 提示: pi 版本可能已更新,${label}汉化补丁只应用了 ${applied}/${rules.length} 处(不影响使用)`,
|