fix(consult): 每一轮回答前都必须调用排盘工具
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
AGENT_TIMEOUT_MS,
|
||||
CONSULTATION_MAX_OUTPUT_TOKENS,
|
||||
CONSULTATION_NATAL_CALC_TOOL_ID,
|
||||
CONSULTATION_WINDOW_CALC_TOOL_ID,
|
||||
mergeConsultationAnswerPolicies,
|
||||
CONSULTATION_DOMAIN_WALL_CLOCK_MS,
|
||||
MAX_CONSULTATION_DOMAINS,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
canonicalDomainPlan,
|
||||
consultationGenerationSettings,
|
||||
consultationNatalPrepareStep,
|
||||
consultationWindowPrepareStep,
|
||||
consultationSliceGenerationSettings,
|
||||
consultationModelStepTelemetry,
|
||||
consultationStepBudgetReceipt,
|
||||
@@ -654,15 +656,28 @@ test("guided-topic entrypoint ignores a model domain rewrite instead of executin
|
||||
|
||||
test("natal first step exposes only the chart calculation tool", () => {
|
||||
assert.equal(CONSULTATION_NATAL_CALC_TOOL_ID, "run-jyotish-consultation");
|
||||
// 原值: toolChoice "auto" / 新值: 第 0 步 "required"、第 1 步仍 "auto"
|
||||
// 原因: BUG-923 每轮必须先调排盘工具,提示词例外已删
|
||||
assert.deepEqual(consultationNatalPrepareStep({ stepNumber: 0 }), {
|
||||
activeTools: ["run-jyotish-consultation"],
|
||||
toolChoice: "auto",
|
||||
toolChoice: "required",
|
||||
});
|
||||
assert.deepEqual(consultationNatalPrepareStep({ stepNumber: 1 }), {
|
||||
toolChoice: "auto",
|
||||
});
|
||||
});
|
||||
|
||||
test("window first step requires the window consultation tool", () => {
|
||||
assert.equal(CONSULTATION_WINDOW_CALC_TOOL_ID, "run-jyotish-window-consultation");
|
||||
assert.deepEqual(consultationWindowPrepareStep({ stepNumber: 0 }), {
|
||||
activeTools: ["run-jyotish-window-consultation"],
|
||||
toolChoice: "required",
|
||||
});
|
||||
assert.deepEqual(consultationWindowPrepareStep({ stepNumber: 1 }), {
|
||||
toolChoice: "auto",
|
||||
});
|
||||
});
|
||||
|
||||
test("matching the pinned theme does not record a plan override", async () => {
|
||||
const state = createConsultationRuntimeState();
|
||||
await createConsultationTools({
|
||||
|
||||
@@ -171,3 +171,10 @@ test("window agent instructions forbid probe clocks as a birth minute", () => {
|
||||
assert.match(windowFactory, /Never invent 00:00, a period midpoint, noon, or any probe clock as the birth time/);
|
||||
assert.doesNotMatch(windowFactory, /id: `jyotish-guide-/);
|
||||
});
|
||||
|
||||
test("natal and window agents must call the chart tool every turn (BUG-922)", () => {
|
||||
const mastra = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8");
|
||||
assert.doesNotMatch(mastra, /follow-ups may use the existing/);
|
||||
assert.match(mastra, /Call run-jyotish-consultation before answering every turn/);
|
||||
assert.match(mastra, /Call run-jyotish-window-consultation before answering every turn/);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import {
|
||||
consultationNatalPrepareStep,
|
||||
consultationWindowPrepareStep,
|
||||
} from "../src/mastra/consultation-tools.ts";
|
||||
|
||||
const route = readFileSync(new URL("../src/app/api/consult/route.ts", import.meta.url), "utf8");
|
||||
const reportsRoute = readFileSync(new URL("../src/app/api/reports/route.ts", import.meta.url), "utf8");
|
||||
@@ -15,6 +19,29 @@ const stagingCompose = readFileSync(new URL("../../deploy/docker-compose.staging
|
||||
|
||||
|
||||
|
||||
test("natal and window instructions require a chart tool every turn (BUG-922)", () => {
|
||||
assert.doesNotMatch(mastra, /follow-ups may use the existing/);
|
||||
assert.match(mastra, /Call run-jyotish-consultation before answering every turn/);
|
||||
assert.match(mastra, /Call run-jyotish-window-consultation before answering every turn/);
|
||||
});
|
||||
|
||||
test("natal and window first steps require the chart tool (BUG-923)", () => {
|
||||
assert.deepEqual(consultationNatalPrepareStep({ stepNumber: 0 }), {
|
||||
activeTools: ["run-jyotish-consultation"],
|
||||
toolChoice: "required",
|
||||
});
|
||||
assert.deepEqual(consultationNatalPrepareStep({ stepNumber: 1 }), {
|
||||
toolChoice: "auto",
|
||||
});
|
||||
assert.deepEqual(consultationWindowPrepareStep({ stepNumber: 0 }), {
|
||||
activeTools: ["run-jyotish-window-consultation"],
|
||||
toolChoice: "required",
|
||||
});
|
||||
assert.deepEqual(consultationWindowPrepareStep({ stepNumber: 1 }), {
|
||||
toolChoice: "auto",
|
||||
});
|
||||
});
|
||||
|
||||
test("consultation plans are server-owned and bounded", () => {
|
||||
assert.match(plan, /consultationPlanSchema/);
|
||||
assert.match(plan, /requestedDomains/);
|
||||
@@ -93,14 +120,22 @@ test("consult streams reserve an answer budget and keep provider thinking on a s
|
||||
assert.match(route, /entrypoint: consultEntrypoint/);
|
||||
assert.match(route, /entrypoint: parsed\.data\.entrypoint/);
|
||||
assert.match(tools, /export function consultationNatalPrepareStep/);
|
||||
assert.match(tools, /export function consultationWindowPrepareStep/);
|
||||
assert.match(tools, /activeTools: \[CONSULTATION_NATAL_CALC_TOOL_ID\]/);
|
||||
assert.match(tools, /activeTools: \[CONSULTATION_WINDOW_CALC_TOOL_ID\]/);
|
||||
const sharedStreamOptions = route.slice(
|
||||
route.indexOf("const streamOptions = {"),
|
||||
route.indexOf("const natalStreamOptions = {"),
|
||||
);
|
||||
assert.doesNotMatch(sharedStreamOptions, /prepareStep/);
|
||||
assert.match(route, /prepareStep: consultationNatalPrepareStep/);
|
||||
assert.match(route, /prepareStep: consultationWindowPrepareStep/);
|
||||
assert.match(route, /streamWithOverflowRetry\(agent, natalStreamOptions\)/);
|
||||
assert.match(route, /streamWithOverflowRetry\(agent, windowStreamOptions\)/);
|
||||
assert.match(
|
||||
route,
|
||||
/请调用 run-jyotish-window-consultation 完成计算[\s\S]*?windowStreamOptions\)/,
|
||||
);
|
||||
assert.doesNotMatch(route, /先加载 Jyotish Skill/);
|
||||
assert.match(route, /pinsConsultationDomains\(consultEntrypoint\)/);
|
||||
assert.match(route, /调用时不要填写 domains,沿用服务器已选定的主题/);
|
||||
|
||||
Reference in New Issue
Block a user