ed9497e76a
Natal answers were opening on parameter tables, and rectification turns were one-sentence legal copy. Centralize user-facing strings, keep representative-minute and question-slot red lines, and stop duplicating the opening collect prompt as a second assistant message. Co-authored-by: Cursor <cursoragent@cursor.com>
73 lines
4.4 KiB
TypeScript
73 lines
4.4 KiB
TypeScript
import assert from "node:assert/strict";
|
||
import { readFileSync } from "node:fs";
|
||
import test from "node:test";
|
||
|
||
const voice = readFileSync(new URL("../src/mastra/product-voice.ts", import.meta.url), "utf8");
|
||
const mastra = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8");
|
||
const route = readFileSync(new URL("../src/app/api/consult/route.ts", import.meta.url), "utf8");
|
||
const binding = readFileSync(new URL("../src/mastra/skill-binding.ts", import.meta.url), "utf8");
|
||
const workflow = readFileSync(new URL("../src/mastra/consultation-workflow.ts", import.meta.url), "utf8");
|
||
|
||
test("product voice uses a spoken opener then the skill Level 2 report skeleton", () => {
|
||
assert.match(voice, /VISIBLE VOICE/);
|
||
assert.match(voice, /natalSpokenReportContract/);
|
||
assert.match(voice, /governs METHOD, TECHNIQUE INVOCATION, TRUTH BOUNDARIES/);
|
||
assert.match(voice, /Raman six-step house judgment/);
|
||
assert.match(voice, /Yoga table/);
|
||
assert.match(voice, /Technique Audit Table at the end of the answer body/);
|
||
assert.match(voice, /已执行 \/ 阻塞 \/ 不适用/);
|
||
assert.match(voice, /governed_support_only_candidate_ready/);
|
||
assert.match(voice, /Skip an executed layer the question needs/);
|
||
assert.match(voice, /你更适合把已经积累的专业能力做成长期事业/);
|
||
assert.match(voice, /3–6 heading-free sentences/);
|
||
assert.match(voice, /骨架不可省略,但必须以直接回应开场/);
|
||
|
||
assert.match(mastra, /productConversationVoice/);
|
||
assert.match(mastra, /natalSpokenReportContract/);
|
||
assert.match(mastra, /skill Level 2 report skeleton/);
|
||
assert.match(mastra, /Paste that Technique Audit Table at the end of the answer body/);
|
||
assert.match(binding, /Follow this method and its truth boundaries/);
|
||
assert.match(binding, /present its Level 2 report template in the chat body after a 3-6 sentence spoken reply/);
|
||
assert.match(mastra, /The bound skill method is this product's answering contract/);
|
||
assert.match(mastra, /Do not use a restricted technique/);
|
||
assert.match(mastra, /must_use_layers is the executed shortlist/);
|
||
assert.match(mastra, /do not invent it from model knowledge/);
|
||
assert.match(mastra, /search_period is the searched observation window/);
|
||
assert.match(voice, /## 统一参数与原始结构/);
|
||
assert.match(mastra, /consultationSpokenHeadingRule\("natal"\)/);
|
||
assert.match(workflow, /template: "skill_level_2"/);
|
||
assert.match(workflow, /raman_six_step/);
|
||
assert.doesNotMatch(mastra, /Name the domains you did cover, say plainly that the remaining ones were not calculated/);
|
||
assert.doesNotMatch(mastra, /2-5 short paragraphs/);
|
||
assert.doesNotMatch(voice, /Do not paste the Technique Audit Table/);
|
||
});
|
||
|
||
test("general and onboarding get voice without the natal Level 2 skeleton", () => {
|
||
const generalStart = mastra.indexOf("const generalJyotishInstructions");
|
||
const onboardingStart = mastra.indexOf("const onboardingInstructions");
|
||
const windowStart = mastra.indexOf("const windowJyotishInstructions");
|
||
const natalStart = mastra.indexOf("const jyotishInstructions");
|
||
const general = mastra.slice(generalStart, onboardingStart);
|
||
const onboarding = mastra.slice(onboardingStart, mastra.indexOf("const onboardingAgents"));
|
||
const window = mastra.slice(windowStart, mastra.indexOf("export function getWindowJyotishAgent"));
|
||
const natal = mastra.slice(natalStart, mastra.indexOf("export function getJyotishAgent"));
|
||
assert.match(natal, /natalSpokenReportContract/);
|
||
assert.match(general, /productConversationVoice/);
|
||
assert.doesNotMatch(general, /natalSpokenReportContract/);
|
||
assert.match(window, /productConversationVoice/);
|
||
assert.doesNotMatch(window, /natalSpokenReportContract/);
|
||
assert.doesNotMatch(onboarding, /natalSpokenReportContract/);
|
||
assert.doesNotMatch(onboarding, /## 统一参数与原始结构/);
|
||
assert.match(onboarding, /knowledgeable, reliable astrologer friend/);
|
||
});
|
||
|
||
test("consult user turn no longer dumps tool JSON that the model would parrot", () => {
|
||
const chartBranch = route.slice(route.indexOf("const toolInput = consultationInputSchema.parse"));
|
||
|
||
assert.match(chartBranch, /先用 3–6 句口语直接回答下面的问题[\s\S]*?resolvedQuestion\.modelQuestion/);
|
||
assert.doesNotMatch(chartBranch, /JSON\.stringify\(toolInput\)/);
|
||
assert.doesNotMatch(chartBranch, /经过服务端校验的工具参数/);
|
||
assert.match(route, /文末技法审计表/);
|
||
assert.match(chartBranch, /await runConsultationWorkflow\(toolInput/);
|
||
});
|