// Analyze pass: write definitions for taxonomy terms grounded in the prose. import "server-only"; import { defaultGateway, chatJSON, type Message } from "../gateway"; import { loadPrompt } from "../prompts"; const glossaryJsonSchema = { type: "object", additionalProperties: false, required: ["definitions"], properties: { definitions: { type: "array", items: { type: "object", additionalProperties: false, required: ["label", "definition"], properties: { label: { type: "string", minLength: 1 }, definition: { type: "string" }, }, }, }, }, } as const; export interface GlossaryResult { defs: Array<{ label: string; definition: string }>; inputTokens: number; outputTokens: number; provider: string; model: string; } export async function analyzeGlossary( documentText: string, terms: Array<{ label: string; parentLabel?: string | null; synonyms?: string[] }> ): Promise { if (terms.length === 0) { return { defs: [], inputTokens: 0, outputTokens: 0, provider: "n/a", model: "n/a" }; } const prompt = loadPrompt("socrates/analyze-glossary.md"); const gateway = defaultGateway(); const userPayload = `Document:\n\n${documentText}\n\n---\n\n` + `Terms:\n\`\`\`json\n${JSON.stringify(terms, null, 2)}\n\`\`\``; const messages: Message[] = [ { role: "system", content: prompt }, { role: "user", content: userPayload }, ]; const { value, result } = await chatJSON<{ definitions?: Array<{ label?: string; definition?: string }> }>( gateway, messages, { temperature: 0.2, maxTokens: 1800, jsonSchema: { name: "glossary", schema: glossaryJsonSchema as Record }, jsonObjectMode: true, maxRepairs: 2, } ); const defs: Array<{ label: string; definition: string }> = []; for (const d of value?.definitions ?? []) { const label = (d.label ?? "").trim(); const def = (d.definition ?? "").trim(); if (!label || !def) continue; defs.push({ label, definition: def }); } return { defs, inputTokens: result.inputTokens, outputTokens: result.outputTokens, provider: gateway.provider, model: gateway.model, }; }