/** * Read-only projection of a consultation workflow payload into the text the * answer model sees. Does not modify frontend runtime files. * * The single-domain wrap matches consultation-tools.ts toModelDomainPlanContext * when consultations.length === 1 and omittedDomains.length === 0: * return { ...consultations[0], ...plan, consultations }; */ import { readFileSync, writeFileSync } from "node:fs"; import { createConsultationPlan } from "../../frontend/src/lib/consultation-plan.ts"; import { consultationMethodologyForDomains } from "../../frontend/src/lib/consultation-methodology.ts"; import type { ConsultationDomain } from "../../frontend/src/lib/consultation-domain-registry.ts"; import { consultationWorkflowResponseSchema, toAgentConsultationContext, toModelOutput, } from "../../frontend/src/mastra/consultation-workflow.ts"; type JsonRecord = Record; function readJson(path: string): JsonRecord { return JSON.parse(readFileSync(path, "utf8")) as JsonRecord; } function planFields(domain: ConsultationDomain, question: string) { const plan = createConsultationPlan({ userIntent: question, theme: domain, consultationMode: "verified_chart", }); return { plan_version: plan.plan_version, depth: plan.depth, requested_domains: plan.requestedDomains, timing_horizon: plan.timingHorizon, precision_boundary: plan.precisionBoundary, required_evidence_categories: plan.requiredEvidenceCategories, birthTimeMode: plan.birthTimeMode, }; } function projectOne(workflow: JsonRecord, domain: ConsultationDomain, question: string) { const parsed = consultationWorkflowResponseSchema.safeParse(workflow); const agentContext = toAgentConsultationContext(parsed.success ? parsed.data : workflow); const consultationPlan = createConsultationPlan({ userIntent: question, theme: domain, consultationMode: "verified_chart", }); const modelOutput = toModelOutput(agentContext, consultationPlan); const consultation = { domain, ...modelOutput }; const methodology = consultationMethodologyForDomains([domain]); const plan = { success: agentContext.success === true, domains: [domain], omitted_domains: [] as ConsultationDomain[], ...(methodology ? { methodology } : {}), }; const modelContext = { ...consultation, ...plan, consultations: [consultation] }; return { schema_ok: parsed.success, schema_error: parsed.success ? null : parsed.error.issues.slice(0, 8).map((issue) => ({ path: issue.path.join("."), code: issue.code, })), methodology_sections: methodology?.sections.length ?? 0, methodology_chars: methodology ? JSON.stringify(methodology).length : 0, model_context: modelContext, }; } const [mode, ...rest] = process.argv.slice(2); if (mode === "plans") { const spec = readJson(rest[0]); const questions = spec.questions as Array<{ id: string; domain: ConsultationDomain; question: string }>; const plans: JsonRecord = {}; for (const item of questions) { plans[item.id] = planFields(item.domain, item.question); } writeFileSync(rest[1], JSON.stringify(plans)); } else if (mode === "project") { const jobs = readJson(rest[0]) as { items: Array<{ id: string; domain: ConsultationDomain; question: string; workflow_path: string; out_path: string }>; }; const summary: JsonRecord[] = []; for (const item of jobs.items) { const workflow = readJson(item.workflow_path); const projected = projectOne(workflow, item.domain, item.question); const text = JSON.stringify(projected.model_context); writeFileSync(item.out_path, text); summary.push({ id: item.id, schema_ok: projected.schema_ok, schema_error: projected.schema_error, methodology_sections: projected.methodology_sections, methodology_chars: projected.methodology_chars, model_chars: text.length, }); } writeFileSync(rest[1], JSON.stringify(summary)); } else { process.stderr.write("usage: plans | project \n"); process.exit(2); }