- BUG-1049 (recurrence of BUG-504): the opening stem carries six examples and an example answer again and is server-owned on the zero-evidence opening; the body is two plain sentences (no 大运/盘面/代表分钟/精确到秒, no year, no question). Stem de-dup compares whole sentences / near-equality instead of a 12-char prefix, which had deleted the body's examples sentence sinceaa7ccb30(BUG-604) +dd8f35f7(BUG-648). - BUG-1050: plain step labels; a finished step label shows once and 「已完成 N 步」counts shown rows; failed rows read 「…未完成」 from the in-progress wording. - Skill 10.0.30 -> 10.0.31 (OpeningPolicy); 10.0.30 kept as deprecated. - VOICE / DESIGN / CHANGELOG / BUG_HISTORY / PROGRESS / real-device checklist and screenshots. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
130 lines
5.8 KiB
TypeScript
130 lines
5.8 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { agentGenerationSettings, AGENT_MAX_OUTPUT_TOKENS } from "../src/lib/agent-generation-settings.ts";
|
|
import {
|
|
activityCompletedSteps,
|
|
activityCompletedTrail,
|
|
activityElapsedLabel,
|
|
nextActivityView,
|
|
} from "../src/lib/chat-message-view.ts";
|
|
import {
|
|
chartCalculationProgressLabel,
|
|
CONSULTATION_CHART_CALCULATION_LABEL,
|
|
} from "../src/lib/consultation-activity-labels.ts";
|
|
import {
|
|
RECTIFICATION_TOOL_PROGRESS_LABELS,
|
|
activityTraceFromReceipt,
|
|
rectificationCompletedTrail,
|
|
rectificationToolActivityPhase,
|
|
} from "../src/lib/rectification-activity-labels.ts";
|
|
|
|
test("generation settings reserve spoken-answer tokens and disable thinking by default", () => {
|
|
const settings = agentGenerationSettings({ providerId: "deepseek" });
|
|
assert.equal(AGENT_MAX_OUTPUT_TOKENS, 16_384);
|
|
assert.equal(settings.modelSettings.maxOutputTokens, 16_384);
|
|
assert.deepEqual(settings.providerOptions.openai, { thinking: { type: "disabled" } });
|
|
assert.deepEqual(settings.providerOptions.deepseek, { thinking: { type: "disabled" } });
|
|
});
|
|
|
|
test("callers can enable a separate thinking channel without pinching the answer budget", () => {
|
|
const settings = agentGenerationSettings({ providerId: "deepseek" }, { thinking: "enabled" });
|
|
assert.equal(settings.modelSettings.maxOutputTokens, 16_384 + 8_192);
|
|
assert.deepEqual(settings.providerOptions.openai, { thinking: { type: "enabled" } });
|
|
assert.deepEqual(settings.providerOptions.deepseek, { thinking: { type: "enabled" } });
|
|
});
|
|
|
|
test("activity elapsed copy stays hidden until eight seconds", () => {
|
|
assert.equal(activityElapsedLabel(1_000, 8_999), null);
|
|
assert.equal(activityElapsedLabel(1_000, 9_000), "已用时 8 秒");
|
|
assert.equal(activityElapsedLabel(1_000, 25_000), "已用时 24 秒");
|
|
});
|
|
|
|
test("the same activity label keeps its start time", () => {
|
|
const first = nextActivityView(undefined, {
|
|
phase: "chart-calculation",
|
|
label: "正在比较候选时间…",
|
|
}, 10);
|
|
const same = nextActivityView(first, {
|
|
phase: "chart-calculation",
|
|
label: "正在比较候选时间…",
|
|
}, 40);
|
|
const next = nextActivityView(same, {
|
|
phase: "answer-composition",
|
|
label: "正在组织回答…",
|
|
}, 50);
|
|
assert.equal(first.startedAt, 10);
|
|
assert.equal(same.startedAt, 10);
|
|
assert.equal(next.startedAt, 50);
|
|
});
|
|
|
|
test("completed-step trail stays short and drops while composing", () => {
|
|
assert.equal(activityCompletedTrail([]), undefined);
|
|
assert.equal(
|
|
activityCompletedTrail(["读取校正记录", "整理事件证据"]),
|
|
"已完成:读取校正记录 · 整理事件证据",
|
|
);
|
|
assert.equal(
|
|
activityCompletedTrail(["一", "二", "三", "四"]),
|
|
"已完成:二 · 三 · 四",
|
|
);
|
|
const waiting = nextActivityView(undefined, {
|
|
phase: "chart-calculation",
|
|
label: "正在比较候选时间…",
|
|
completedTrail: activityCompletedTrail(["读取校正记录", "整理事件证据"]),
|
|
}, 10);
|
|
assert.equal(waiting.completedTrail, "已完成:读取校正记录 · 整理事件证据");
|
|
const composing = nextActivityView(waiting, {
|
|
phase: "answer-composition",
|
|
label: "正在组织回答…",
|
|
}, 20);
|
|
assert.equal(composing.completedTrail, undefined);
|
|
assert.deepEqual(
|
|
activityCompletedSteps("已完成:读取分析方法 · 计算本命盘"),
|
|
["读取分析方法", "计算本命盘"],
|
|
);
|
|
});
|
|
|
|
test("live rectification labels name the actual public tool", () => {
|
|
// 原值: "正在读取校正记录…" / "正在比较候选时间…"
|
|
// 新值: "正在看你的资料…" / "正在重新对照盘面…"
|
|
// 原因: BUG-1050 步骤名改大白话;对照盘面一句与 BUG-1047 已批准的阶段句同文
|
|
assert.equal(RECTIFICATION_TOOL_PROGRESS_LABELS["rectification-read-case"], "正在看你的资料…");
|
|
assert.equal(RECTIFICATION_TOOL_PROGRESS_LABELS["rectification-compare-candidates"], "正在重新对照盘面…");
|
|
assert.equal(rectificationToolActivityPhase("rectification-read-case"), "loading-method");
|
|
assert.equal(rectificationToolActivityPhase("rectification-compare-candidates"), "chart-calculation");
|
|
assert.equal(rectificationToolActivityPhase("rectification-propose-evidence"), "evidence-validation");
|
|
assert.equal(
|
|
rectificationCompletedTrail(["rectification-read-case", "rectification-propose-evidence"]),
|
|
// 原值: "已完成:读取校正记录 · 整理事件证据" / 新值: 大白话步骤名 / 原因: BUG-1050
|
|
"已完成:看了你的资料 · 记下你说的事",
|
|
);
|
|
// BUG-1050: two tools that share one plain label are named once in the trail.
|
|
assert.equal(
|
|
rectificationCompletedTrail([
|
|
"rectification-read-case",
|
|
"rectification-record-evidence-batch",
|
|
"rectification-propose-evidence",
|
|
]),
|
|
"已完成:看了你的资料 · 记下你说的事",
|
|
);
|
|
});
|
|
|
|
test("persisted receipts rebuild the public activity steps without thinking text", () => {
|
|
assert.deepEqual(
|
|
activityTraceFromReceipt({
|
|
steps: ["rectification-read-case", "rectification-record-evidence-batch"],
|
|
methods: ["d1-rashi", "d10-dashamsa"],
|
|
}).map((row) => `${row.kind}:${row.label}`),
|
|
// 原值: ["activity:读取校正记录", "activity:整理多条事件证据"] / 新值: 大白话步骤名 / 原因: BUG-1050
|
|
["activity:看了你的资料", "activity:记下你说的事"],
|
|
);
|
|
assert.deepEqual(activityTraceFromReceipt({ steps: [], methods: ["d1-rashi"] }), []);
|
|
});
|
|
|
|
test("multi-domain chart calculation names the current item without domain ids", () => {
|
|
assert.equal(chartCalculationProgressLabel(1, 1), CONSULTATION_CHART_CALCULATION_LABEL);
|
|
assert.equal(chartCalculationProgressLabel(2, 3), "正在计算本命盘(第 2/3 项)…");
|
|
assert.doesNotMatch(chartCalculationProgressLabel(2, 3), /career|wealth|timing|marriage/);
|
|
});
|