Files
Jyotisha/frontend/tests/agent-activity-progress.test.ts
T
Jesse_Chen 6a44c778c3 fix(web): show live agent work progress and fail truncated rectification answers
Rectification dropped tool.activity started events and treated length finishes as completed. Share generation settings with consultation, keep the activity line through streaming, and name multi-domain chart calculation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 12:39:09 +08:00

92 lines
3.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 {
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,
rectificationCompletedTrail,
rectificationToolActivityPhase,
} from "../src/lib/rectification-activity-labels.ts";
test("generation settings reserve visible tokens and disable thinking", () => {
const settings = agentGenerationSettings({ providerId: "deepseek" });
assert.equal(AGENT_MAX_OUTPUT_TOKENS, 8192);
assert.equal(settings.modelSettings.maxOutputTokens, 8192);
assert.deepEqual(settings.providerOptions.openai, { thinking: { type: "disabled" } });
assert.deepEqual(settings.providerOptions.deepseek, { thinking: { type: "disabled" } });
});
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);
});
test("live rectification labels name the actual public tool", () => {
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"]),
"已完成:读取校正记录 · 整理事件证据",
);
});
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/);
});