import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { createConsultationPlan } from "../src/lib/consultation-plan.ts"; import { toAgentConsultationContext, toModelOutput } from "../src/mastra/consultation-workflow.ts"; test("passes transparent public-case references into the agent context", () => { const workflowSource = readFileSync(new URL("../src/mastra/consultation-workflow.ts", import.meta.url), "utf8"); const agentSource = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8"); assert.match(workflowSource, /reference_transparency:\s*record\(data\.reference_transparency\)/); assert.match(workflowSource, /vedastro_gateway:\s*record\(data\.vedastro_gateway\)/); assert.match(workflowSource, /ashtakavarga:\s*chart\.ashtakavarga/); assert.match(agentSource, /high_similarity_public_references_available/); assert.match(agentSource, /requested_uncovered_domains/); assert.match(agentSource, /public_context_only/); assert.match(agentSource, /timing_state/); assert.match(agentSource, /partial_match/); assert.match(agentSource, /narayana_status/); assert.match(agentSource, /transit_status/); assert.match(agentSource, /Jupiter and Saturn relative houses/); assert.match(agentSource, /exact_triggers as technical trigger points/); assert.match(agentSource, /production_tuning_allowed=false/); assert.match(agentSource, /no_majority_vote/); assert.match(agentSource, /method_variant_not_majority_vote/); assert.match(agentSource, /Shadbala\/Ashtakavarga component differences/); assert.match(agentSource, /D2, D11/); assert.match(agentSource, /gender-specific spouse significators are supplements/); assert.match(agentSource, /male.*Venus/); assert.match(agentSource, /female.*Jupiter\/Mars/); }); test("keeps strength, Ashtakavarga, and timing evidence available to the answer model", () => { const workflowSource = readFileSync(new URL("../src/mastra/consultation-workflow.ts", import.meta.url), "utf8"); const agentSource = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8"); assert.match(workflowSource, /shadbala: chart\.shadbala/); assert.match(workflowSource, /shadbala_boundary:/); assert.match(workflowSource, /ashtakavarga: modules\.ashtakavarga/); assert.match(workflowSource, /dasha_boundaries: modules\.dasha_boundaries/); assert.match(workflowSource, /narayana_dasha: modules\.narayana_dasha/); assert.match(workflowSource, /evidence_contract:/); assert.match(workflowSource, /missing_route_layers: consumerContext\.missing_route_layers/); assert.match(workflowSource, /answer_policy: consumerContext\.answer_policy/); assert.match(agentSource, /evidence_contract\.answer_policy/); assert.match(agentSource, /can_answer_precise_timing/); assert.match(workflowSource, /boundary: "not_auto_rectified"/); assert.match(agentSource, /rectification\.boundary=not_auto_rectified/); assert.match(workflowSource, /external_engine_evidence:/); assert.match(workflowSource, /runtime_truth: record\(data\.runtime_truth\)/); assert.match(workflowSource, /numerical_parity: record\(data\.external_parity_gate\)/); assert.match(workflowSource, /real_case_calibration: record\(data\.real_case_calibration\)/); }); test("projects only bounded server-selected evidence to the model", () => { const context = toAgentConsultationContext({ success: true, question: "事业如何", chart: { birth: { date: "1990-01-02", time: "03:04", latitude: 25.03, longitude: 121.56 }, ascendant: { sign: "Leo", degree: 12.5, reported_time: "private-reported-time" }, planets: [{ name: "Sun", sign: "Capricorn", degree: 4.2, lng: "private-lng" }], houses: { first: { sign: "Leo" } }, dasha: { current: "Mars", next: "Rahu", utc_offset: "private-utc-offset" }, shadbala: { planets: { Sun: { total_rupa: 7.1 } } }, ashtakavarga: { house_scores: { "10": 31 } }, modules: { shadbala: { total: 412 }, ashtakavarga: { total: 28 }, dasha_boundaries: { next: "2027-03", utc_offset: "private-module-utc-offset" }, narayana_dasha: { current: "Aries" }, }, }, routing: { primary_theme: "career" }, thematic_report: { themes: { career: { theme: "career", summary: "保留这条服务端证据摘要", narrative: "事业证据叙事", strength: "strong", account_balance: "private-account-balance", recommendations: ["保持稳健推进"], evidence: [{ technique: "D10-Dashamsha-local", chart: "D10", conclusion: "D10 事业分盘已进入证据链", sentiment: "positive", strength: "strong", details: { source: "chart", derived: true, entitlements: "private-entitlements", access_scopes: "private-access-scopes", }, }], }, }, }, consumer_context: { route: "career", core_status: "ready", available_layers: ["natal", "timing"], missing_route_layers: [], hard_blockers: [], technique_truth: { status: "verified", access_scopes: "private-validation-scopes" }, answer_policy: { can_answer_direction: true, can_answer_precise_timing: false, entitlements: "private-policy-entitlements", }, user_facing_limitation: "精确月份暂不可用", }, reference_transparency: { similar_public_cases: { status: "public_context_only" } }, rectification: { summary: "none" }, }); const output = toModelOutput(context); const careerPlan = createConsultationPlan({ userIntent: "事业如何", theme: "career" }); const careerOutput = toModelOutput(context, careerPlan); const serialized = JSON.stringify(output); assert.equal(output.packet_version, "consultation-evidence-packet-v2"); assert.equal("birth" in output, false); assert.equal(serialized.includes("1990-01-02"), false); assert.equal(serialized.includes("03:04"), false); assert.equal(serialized.includes("25.03"), false); assert.equal(serialized.includes("121.56"), false); for (const privateValue of [ "private-reported-time", "private-lng", "private-utc-offset", "private-module-utc-offset", "private-account-balance", "private-entitlements", "private-access-scopes", "private-validation-scopes", "private-policy-entitlements", ]) { assert.equal(serialized.includes(privateValue), false); } for (const privateKey of [ "reported_time", "lng", "utc_offset", "account_balance", "entitlements", "access_scopes", ]) { assert.equal(serialized.includes(`"${privateKey}"`), false); } assert.equal(serialized.includes("保留这条服务端证据摘要"), true); assert.equal(serialized.includes("D10-Dashamsha-local"), true); assert.equal(serialized.includes("total_rupa"), true); assert.equal(serialized.includes("house_scores"), true); assert.equal(serialized.includes('"dasha"'), true); assert.equal(serialized.includes("narayana_dasha"), true); assert.equal(serialized.includes('"status":"verified"'), true); const answerPolicy = output.evidence_contract.answer_policy as Record; assert.equal(answerPolicy.can_answer_precise_timing, false); assert.deepEqual(output.claim_cards.map((card) => card.category), ["natal_foundation", "domain", "timing", "validation"]); assert.deepEqual(careerOutput.claim_cards.map((card) => card.category), ["natal_foundation", "domain"]); assert.equal(JSON.stringify(careerOutput).includes('"dasha"'), false); assert.equal(serialized.includes("consultation-evidence-packet-v2"), true); });