Files
Jyotisha/scripts/research/project_consult_model_context.ts
T
jesse-ux d8d03b5a69
Independent Staging Quality Gate / validate (push) Failing after 6m40s
Independent Staging Quality Gate / publish (push) Skipped
research: consultation evidence-card inventory and draft
Measure the model-visible consultation payload on three public charts, draft per-domain cards, and record the Narayana/pratyantar projection gap as BUG-1054. No runtime behavior change.
2026-09-27 01:27:57 +08:00

108 lines
4.0 KiB
TypeScript

/**
* 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<string, unknown>;
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 <spec.json> <out.json> | project <jobs.json> <summary.json>\n");
process.exit(2);
}