refactor(rectification): split runV9AgentTurn into prepare / attempt / retry / finish
Move-only (TASK-rectification-code-split-20260926 T3/T4). No behavior, receipt, billing, Skill or scoring change. - agent-run.ts: 1400 -> 135 lines; runV9AgentTurn 1046 -> 25 lines, no nested functions. It keeps the public types, the budget constants and the phase order: agent-run-prepare.ts (reliability, session, year re-ask, Skill identity, delivered guard, reserve, turn row / replay), agent-run-retry.ts (attempt loop), agent-run-attempt.ts (the old nested streamAttempt), agent-run-finish.ts (billing settle, receipts, interview, finalize), agent-run-support.ts (outcome types, retry classification, turn receipt writers), agent-run-messages.ts (buildAgentMessages / buildOpeningBrief, re-exported). - One token changed with the move: the attempt passes its own `previousErrorCode` argument to buildAgentMessages instead of reading the enclosing `lastAttemptError`; the loop passes that same value (clears the old unused-parameter warning). - Tests: whole-source contracts read tests/rectification-agent-run-surface.ts; behavioral runV9AgentTurn tests unchanged. agent-run growth caps added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
eb773f1299
commit
a00c40d4b8
@@ -30,6 +30,7 @@ import { attachQuestionsToTurns } from "../src/lib/rectification-agentic/v9/turn
|
||||
import { CASE_ID, FOCUS_ID, TURN_ID } from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
/** Task 0 frozen “before” snapshot: accident case f83d9b42, origin/staging @ 8617eb56. */
|
||||
export const ACCIDENT_CASE_BEFORE_COPY = {
|
||||
@@ -253,7 +254,8 @@ test("settled assistant body with a focus has no question-mark sentences", () =>
|
||||
assert.doesNotMatch(withRescoreSkippedNotice("记下了:2016 年 3 月入学。范围在收窄。"), /收窄/);
|
||||
assert.doesNotMatch(RECTIFICATION_USER_COPY.evidenceNotRecorded, /系统|模型/);
|
||||
assert.doesNotMatch(RECTIFICATION_USER_COPY.collectHandoff, /请回答下面的问题/);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.match(agentRun, /stripQuestionSentences/);
|
||||
assert.match(agentRun, /withRangeChangedAfterEvidence/);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
/**
|
||||
* The V10 rectification turn runner as source text: agent-run.ts (public
|
||||
* types and the order of the phases) plus the phase modules it was split into
|
||||
* (TASK-rectification-code-split-20260926), in the order the code ran inside
|
||||
* the old runV9AgentTurn: preparation, the retry loop, the finish, one
|
||||
* attempt, then the shared pieces and the model messages. A whole-source
|
||||
* contract that held on agent-run.ts before the split holds on this
|
||||
* concatenation after it. Slices that no longer sit in one file are
|
||||
* rewritten per test.
|
||||
*/
|
||||
export const rectificationAgentRunFiles = [
|
||||
"../src/lib/rectification-agentic/v9/agent-run.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-prepare.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-retry.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-finish.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-attempt.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-support.ts",
|
||||
"../src/lib/rectification-agentic/v9/agent-run-messages.ts",
|
||||
] as const;
|
||||
|
||||
export function readRectificationAgentRunFile(relativePath: (typeof rectificationAgentRunFiles)[number]): string {
|
||||
return readFileSync(new URL(relativePath, import.meta.url), "utf8");
|
||||
}
|
||||
|
||||
export const rectificationAgentRunSurface = rectificationAgentRunFiles
|
||||
.map((relativePath) => readRectificationAgentRunFile(relativePath))
|
||||
.join("\n");
|
||||
@@ -17,6 +17,7 @@ import { deriveRectificationChatView } from "../src/lib/rectification-chat-view.
|
||||
import { completedReceiptFromPersisted } from "../src/lib/rectification-chat-messages.ts";
|
||||
import { RectificationQuestionGapNotices } from "../src/components/rectification-question-gap-notices.tsx";
|
||||
import { rectificationAgentRouteSurface } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const component = readFileSync(
|
||||
new URL("../src/components/conversational-birth-time-rectification.tsx", import.meta.url),
|
||||
@@ -288,10 +289,8 @@ test("candidate acceptance is non-billable, mutually exclusive, and continues th
|
||||
});
|
||||
|
||||
test("usage completes or releases without hiding settlement failures", () => {
|
||||
const run = readFileSync(
|
||||
new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const run = rectificationAgentRunSurface;
|
||||
assert.match(run, /billing\.complete\(/);
|
||||
assert.match(run, /billing\.release\(/);
|
||||
assert.match(run, /usage_settlement_failed/);
|
||||
|
||||
@@ -55,6 +55,7 @@ import {
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface, readRectificationAgentRouteFile } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const ACTION_ID = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa";
|
||||
const QUESTION_ID = "question-1";
|
||||
@@ -1508,7 +1509,8 @@ test("the public agent route treats structured choice as a non-model command", (
|
||||
});
|
||||
|
||||
test("rectification attempt timeout stays under the agent route budget", () => {
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const budget = readFileSync(new URL("../src/lib/rectification-run-budget.ts", import.meta.url), "utf8");
|
||||
const regenerate = readFileSync(
|
||||
new URL("../src/app/api/rectification/cases/[caseId]/turns/[turnId]/regenerate/route.ts", import.meta.url),
|
||||
|
||||
@@ -6,6 +6,7 @@ import { composeCollectSpokenAssistantText, detachCollectSpokenAssistantText, st
|
||||
import { attachQuestionsToTurns } from "../src/lib/rectification-agentic/v9/turn-question.ts";
|
||||
import { GENERIC_COLLECT_QUESTION, RECTIFICATION_USER_COPY, USER_COLLECT_QUESTION } from "../src/lib/rectification-agentic/user-copy.ts";
|
||||
import { CASE_ID, FOCUS_ID, TURN_ID } from "./rectification-v9-test-support.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
test("composeCollectSpokenAssistantText joins by exact prompt identity", () => {
|
||||
const greeting = "你好,我是生时校正助手。";
|
||||
@@ -89,7 +90,8 @@ test("composeCollectSpokenAssistantText drops a near-duplicate restatement of th
|
||||
});
|
||||
|
||||
test("runtime no longer composes the stem into assistant_message", () => {
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const attach = readFileSync(new URL("../src/lib/rectification-agentic/v9/turn-question.ts", import.meta.url), "utf8");
|
||||
assert.doesNotMatch(agentRun, /composeCollectSpokenAssistantText/);
|
||||
assert.match(attach, /stripQuestionSentences/);
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
import { RectificationVerificationReport } from "../src/components/rectification-verification-report.tsx";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
test("delivery body is three sentences and omits the eight-method report", () => {
|
||||
const text = deliveryTurnNarration({
|
||||
@@ -74,7 +75,8 @@ test("already_delivered blocks a second no-message run for the same result withi
|
||||
});
|
||||
|
||||
test("agent-run returns already_delivered before billing and the route skips a second turn", () => {
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
// 原值: 读 app/api/rectification/agent/route.ts 单文件。新值: rectificationAgentRouteSurface(route.ts + 拆出的 agent-route-*.ts,见 rectification-agent-route-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const route = rectificationAgentRouteSurface;
|
||||
const exit = readFileSync(new URL("../src/lib/rectification-agentic/v9/turn-exit.ts", import.meta.url), "utf8");
|
||||
@@ -94,7 +96,8 @@ test("agent-run returns already_delivered before billing and the route skips a s
|
||||
});
|
||||
|
||||
test("agent-run trims evidence after persistNextInterviewIfIdle so delivery can keep three sentences", () => {
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const persistIdx = agentRun.lastIndexOf("persistNextInterviewIfIdle({");
|
||||
const trimIdx = agentRun.lastIndexOf("trimSpokenTurnForInterview(");
|
||||
const replaceIdx = agentRun.lastIndexOf('type: "answer.delta", text: spokenAnswer, replace: true');
|
||||
|
||||
@@ -122,3 +122,41 @@ test("rectification agent POST stays an assembly of branch handlers", () => {
|
||||
assert.match(post, new RegExp(`\\b${handler}\\(`), `POST must delegate to ${handler}`);
|
||||
}
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// T3 · lib/rectification-agentic/v9/agent-run.ts
|
||||
// Measured 2026-09-26 after the runner split. Before (origin/staging 12cbe6f8):
|
||||
// file 1400 lines, runV9AgentTurn 1046 lines with four nested functions
|
||||
// (streamAttempt, failedAttempt, persistCommittedPhase, finalizeTurn). After:
|
||||
// file 135, runV9AgentTurn 25 lines, no nested functions; the phases live in
|
||||
// agent-run-{prepare,retry,attempt,finish,support,messages}.ts.
|
||||
const RUN_PATH = "../src/lib/rectification-agentic/v9/agent-run.ts";
|
||||
const RUN_LINE_BASELINE = 135;
|
||||
const RUN_LINE_CAP = RUN_LINE_BASELINE + 150;
|
||||
/** D2 of the task: runV9AgentTurn stays at or under 300 lines. */
|
||||
const RUN_FUNCTION_LINE_CAP = 300;
|
||||
const RUN_FUNCTION_MARKER = "export async function runV9AgentTurn(";
|
||||
|
||||
function functionBody(source: string, marker: string): string {
|
||||
const start = source.indexOf(marker);
|
||||
assert.notEqual(start, -1, `missing marker: ${marker}`);
|
||||
const end = source.indexOf("\n}\n", start);
|
||||
assert.notEqual(end, -1, `unterminated function: ${marker}`);
|
||||
return source.slice(start, end + 2);
|
||||
}
|
||||
|
||||
test("agent-run.ts line count stays within the coarse guardrail", () => {
|
||||
const n = lineCount(read(RUN_PATH));
|
||||
assert.ok(n <= RUN_LINE_CAP, `agent-run.ts has ${n} lines; cap is ${RUN_LINE_CAP} (${RUN_LINE_BASELINE} baseline + 150).`);
|
||||
});
|
||||
|
||||
test("runV9AgentTurn stays the order of its phases", () => {
|
||||
const body = functionBody(read(RUN_PATH), RUN_FUNCTION_MARKER);
|
||||
const n = lineCount(body);
|
||||
assert.ok(n <= RUN_FUNCTION_LINE_CAP, `runV9AgentTurn has ${n} lines; cap is ${RUN_FUNCTION_LINE_CAP}. Phase logic belongs in agent-run-*.ts.`);
|
||||
assert.doesNotMatch(body, /^\s+(?:async )?function\s/m, "runV9AgentTurn must not grow nested functions again.");
|
||||
const prepare = body.indexOf("prepareV9AgentTurn(");
|
||||
const attempts = body.indexOf("runV9AttemptsWithRetry(");
|
||||
const finish = body.indexOf("finishV9AgentTurn(");
|
||||
assert.ok(prepare >= 0 && attempts > prepare && finish > attempts, "prepare → attempts → finish");
|
||||
});
|
||||
|
||||
@@ -60,6 +60,7 @@ import { finalizeSuccessfulTurnExit } from "../src/lib/rectification-agentic/v9/
|
||||
import { RECTIFICATION_TURN_PROGRESS_LABELS } from "../src/lib/rectification-activity-labels.ts";
|
||||
import { rectificationInitialLiveLabel } from "../src/lib/rectification-surface-state.ts";
|
||||
import { rectificationAgentRouteSurface } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const dummyModel = { id: "test-model" } as ResolvedLanguageModel;
|
||||
const PROGRESS_LINES = Object.values(RECTIFICATION_TURN_PROGRESS_LABELS);
|
||||
@@ -527,7 +528,8 @@ test("D5: the exit gate skips its idle re-read only when told the run settled th
|
||||
});
|
||||
|
||||
test("D5 contract: the Agent run reports interviewSettled only from the focus-active exit; the route forwards it", () => {
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
// 原值: 读 app/api/rectification/agent/route.ts 单文件。新值: rectificationAgentRouteSurface(route.ts + 拆出的 agent-route-*.ts,见 rectification-agent-route-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const route = rectificationAgentRouteSurface;
|
||||
assert.match(agentRun, /interviewSettled = interviewIdle\.focusActive === true;/);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
|
||||
import { OPEN_ENGINE_CAPABILITY_CEILING } from "./rectification-v9-test-support.ts";
|
||||
@@ -34,6 +33,7 @@ import {
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface, rectificationTypedMessageFastPath } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const STYLE_OPTIONS = [
|
||||
{ label: "明确发生且时间吻合", answer_class: "yes" as const },
|
||||
@@ -828,7 +828,8 @@ test("idle persist on the covered-domain accident delivers adopt and writes no f
|
||||
});
|
||||
|
||||
test("agent-run still writes the exhaustion gate when idle persist returns terminalNote", () => {
|
||||
const agent = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agent = rectificationAgentRunSurface;
|
||||
// 原值: 读 rectification-agentic-chat.tsx 单文件。新值: rectificationChatSurface(容器 + 拆出的 hook / 参数函数 / 块,见 rectification-chat-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改为调用函数。
|
||||
const chat = rectificationChatSurface;
|
||||
assert.match(agent, /interviewIdle\.terminalNote && interviewIdle\.hostNarration/);
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
receiptHandlers,
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
type ExecutableTool<T = unknown> = {
|
||||
execute(input: unknown): Promise<T>;
|
||||
@@ -325,7 +326,8 @@ test("orphan collect:other focus is skipped so idle persist can deliver", async
|
||||
});
|
||||
|
||||
test("agent-run writes the exhaustion gate when idle persist returns terminalNote", () => {
|
||||
const agent = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agent = rectificationAgentRunSurface;
|
||||
// 原值: 读 rectification-agentic-chat.tsx 单文件。新值: rectificationChatSurface(容器 + 拆出的 hook / 参数函数 / 块,见 rectification-chat-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改为调用函数。
|
||||
const chat = rectificationChatSurface;
|
||||
assert.match(agent, /interviewIdle\.terminalNote && interviewIdle\.hostNarration/);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
@@ -23,6 +22,7 @@ import {
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { deriveRectificationChatView } from "../src/lib/rectification-chat-view.ts";
|
||||
import { chatViewInput, offerableCandidateResult, settledAssistant } from "./rectification-chat-run-fixtures.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const S1_TIMES = [
|
||||
"04:50", "04:51", "04:52", "04:53", "04:54", "04:55", "04:56", "04:57", "05:13",
|
||||
@@ -286,10 +286,8 @@ test("BUG-588 evidence narration names a widened range after compare", () => {
|
||||
);
|
||||
assert.equal(rangeChangedAfterEvidence(["04:50", "04:57"], ["04:50", "04:57"]), null);
|
||||
|
||||
const agentRun = readFileSync(
|
||||
new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const askedFocusAt = agentRun.indexOf("const askedFocus = latestDossier.conversationSummary.activeFocus");
|
||||
const settlement = askedFocusAt >= 0 ? agentRun.slice(askedFocusAt) : "";
|
||||
const stripAt = settlement.indexOf("stripQuestionSentences");
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
type MethodFollowupEvidence,
|
||||
} from "../src/lib/rectification-agentic/v9/method-followup.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const SEVEN_WITHOUT_HEALTH: MethodFollowupEvidence[] = [
|
||||
{ id: "e-edu", status: "confirmed", domain: "education", datePrecision: "month", occurredFrom: "2016-09-01", occurredTo: null, eventKind: "education_start" },
|
||||
@@ -149,7 +150,8 @@ test("unavailable gap button posts repair-exit and says 接着问", () => {
|
||||
new URL("../src/app/api/rectification/cases/[caseId]/repair-exit/route.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.equal(RECTIFICATION_QUESTION_RELOAD_LABEL, "接着问");
|
||||
assert.match(surface, /RECTIFICATION_QUESTION_RELOAD_LABEL = "接着问"/);
|
||||
assert.match(surface, /暂时接不上,请新建一次校正/);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
// 原值: 读 rectification-agentic-chat.tsx 单文件。新值: rectificationChatSurface(容器 + 拆出的 hook / 参数函数 / 块,见 rectification-chat-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改为调用函数。
|
||||
const chat = rectificationChatSurface;
|
||||
const agentRun = readFileSync(
|
||||
new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
|
||||
test("live and persisted assistant text stay verbatim after spoken-answer removal", () => {
|
||||
assert.match(chat, /const raw = failed \? "" : turn\.text \?\? ""/);
|
||||
|
||||
@@ -39,6 +39,7 @@ import type { DiscriminatingEventProbe } from "../src/lib/rectification-agentic/
|
||||
import { collectFocusCloseStatus } from "../src/lib/rectification-agentic/v9/turn-intent-classifier.ts";
|
||||
import { rectificationChatSurface, readRectificationChatFile } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface, rectificationTypedMessageFastPath } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const RELATIONSHIP_PROMPT = USER_COLLECT_QUESTION.relationship;
|
||||
|
||||
@@ -162,7 +163,8 @@ test("collect_spoken stem lives on turn.question inside the same assistant artic
|
||||
const chat = rectificationChatSurface;
|
||||
const row = readFileSync(new URL("../src/components/chat-message-row.tsx", import.meta.url), "utf8");
|
||||
const styles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.match(chat, /currentQuestion\?\.kind === "collect_spoken"/);
|
||||
assert.match(chat, /const collectSpokenPrompt =/);
|
||||
assert.match(chat, /parseTurnQuestion\(turn\.question\)/);
|
||||
@@ -482,7 +484,8 @@ test("agent route keeps question ownership in the server Case projection", () =>
|
||||
);
|
||||
assert.match(successExit, /await finalizeSuccessfulTurnExit/);
|
||||
assert.doesNotMatch(successExit, /send\(\{\s*type:\s*"error"/);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.doesNotMatch(agentRun, /collectSpokenPromptForNewFocus/);
|
||||
assert.doesNotMatch(agentRun, /composeCollectSpokenAssistantText/);
|
||||
assert.match(agentRun, /askedTurnId: turnId/);
|
||||
@@ -578,7 +581,8 @@ test("after one or two dated events the next collect is an invite, not a domain
|
||||
assert.match(tools, /recordV10EvidenceBatch/);
|
||||
assert.match(tools, /result\.acceptedCount > 0[\s\S]*autoRescoreAfterEvidenceChange/);
|
||||
const agent = readFileSync(new URL("../src/mastra/agentic-rectification.ts", import.meta.url), "utf8");
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.doesNotMatch(agent, /还能想起别的吗/);
|
||||
assert.doesNotMatch(agentRun, /还能想起别的吗/);
|
||||
});
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
fakeAccounting,
|
||||
receiptHandlers,
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const ACTION_ID = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa";
|
||||
const QUESTION_ID = "question-1";
|
||||
@@ -219,7 +220,8 @@ test("compare failure copy and receipt detail stay user-visible without PII", ()
|
||||
});
|
||||
assert.equal(detail?.safe_error_code, "engine_request_failed");
|
||||
assert.match(String(detail?.engine_message), /asked_probe_keys/);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.match(agentRun, /withCompareFailedRetryNotice/);
|
||||
assert.match(agentRun, /rectification-compare-candidates/);
|
||||
const tools = readFileSync(new URL("../src/mastra/rectification-v9-tools.ts", import.meta.url), "utf8");
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRouteSurface, readRectificationAgentRouteFile } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const REJECTION = {
|
||||
error: true,
|
||||
@@ -164,10 +165,8 @@ test("retry bootstrap uses the unwritten-evidence constraint only for that error
|
||||
test("route passes classifier expectedWrite into the agent runner", () => {
|
||||
// 原值: 读 app/api/rectification/agent/route.ts 单文件。新值: rectificationAgentRouteSurface(route.ts + 拆出的 agent-route-*.ts,见 rectification-agent-route-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const route = rectificationAgentRouteSurface;
|
||||
const agentRun = readFileSync(
|
||||
new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
assert.match(route, /classifyTurnIntentWithRetry/);
|
||||
// 原值: route 含 `expectedWrite,`(runV9AgentTurn 参数)与 `let expectedWrite: "evidence" | "none" | "unknown" = "none"`。
|
||||
// 新值: 分类结果放在 turnState 上:类型 `expectedWrite: "evidence" | "none" | "unknown"`,route.ts 初值 `expectedWrite: "none"`,
|
||||
|
||||
@@ -31,6 +31,7 @@ import { RECTIFICATION_SKILL_NAME } from "../src/lib/rectification-agentic/v9/ca
|
||||
import { messageContentHash } from "../src/lib/rectification-agentic/v9/message-origin.ts";
|
||||
import { safeToolErrorCode } from "../src/lib/rectification-agentic/v9/tool-service.ts";
|
||||
import { rectificationAgentRouteSurface } from "./rectification-agent-route-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
type StreamChunk = {
|
||||
type: string;
|
||||
@@ -1868,7 +1869,8 @@ test("whole-run budget is less than both route maxDuration values", () => {
|
||||
assert.ok(RECTIFICATION_AGENT_ATTEMPT_TIMEOUT_MS <= RECTIFICATION_RUN_BUDGET_MS);
|
||||
assert.ok(RECTIFICATION_MIN_RETRY_ATTEMPT_MS > 0);
|
||||
const budget = readFileSync(new URL("../src/lib/rectification-run-budget.ts", import.meta.url), "utf8");
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const labels = readFileSync(new URL("../src/lib/rectification-activity-labels.ts", import.meta.url), "utf8");
|
||||
assert.match(budget, /export const RECTIFICATION_AGENT_ATTEMPT_TIMEOUT_MS = 210_000/);
|
||||
assert.doesNotMatch(agentRun, /210_000/);
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
fakeAccounting,
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
import { rectificationChatSurface } from "./rectification-chat-surface.ts";
|
||||
import { rectificationAgentRunSurface } from "./rectification-agent-run-surface.ts";
|
||||
|
||||
const YEAR_Q = "collect:targeted:health_pressure:year";
|
||||
const SERVER_PROMPT = TARGETED_YEAR_PROMPT;
|
||||
@@ -135,7 +136,8 @@ test("yearless short replies are held by the host pre-step (BUG-910)", () => {
|
||||
};
|
||||
assert.equal(shouldHostReaskYearEntry(focus, "是"), SERVER_PROMPT);
|
||||
assert.equal(shouldHostReaskYearEntry(focus, "2019年3月做过手术"), null);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
// 原值: 读 lib/rectification-agentic/v9/agent-run.ts 单文件。新值: rectificationAgentRunSurface(agent-run.ts + 拆出的 agent-run-*.ts,见 rectification-agent-run-surface.ts)。原因: TASK-rectification-code-split-20260926 只搬不改,整文件断言跟着代码走;切片断言另行改写。
|
||||
const agentRun = rectificationAgentRunSurface;
|
||||
const reliability = agentRun.indexOf("classifyDateReliabilityUtterance");
|
||||
const yearHost = agentRun.indexOf("shouldHostReaskYearEntry");
|
||||
const reserve = agentRun.indexOf("billing.reserve");
|
||||
|
||||
Reference in New Issue
Block a user