/** * MI Data Queries — dispatches content queries to module-specific readers. * * Used by the agentic loop to fetch module data server-side and feed * results back into the LLM context. */ import { getUpcomingEventsForMI } from "../modules/rcal/mod"; import { getRecentNotesForMI } from "../modules/rnotes/mod"; import { getRecentTasksForMI } from "../modules/rtasks/mod"; export interface MiQueryResult { ok: boolean; module: string; queryType: string; data: any; summary: string; } /** * Query module content by type. Returns structured data + a text summary * the LLM can consume. */ export function queryModuleContent( space: string, module: string, queryType: "recent" | "summary" | "count", limit = 5, ): MiQueryResult { switch (module) { case "rnotes": { const notes = getRecentNotesForMI(space, limit); if (queryType === "count") { return { ok: true, module, queryType, data: { count: notes.length }, summary: `${notes.length} recent notes found.` }; } const lines = notes.map((n) => `- "${n.title}" (${n.type}, updated ${new Date(n.updatedAt).toLocaleDateString()})${n.tags.length ? ` [${n.tags.join(", ")}]` : ""}: ${n.contentPlain.slice(0, 100)}...`); return { ok: true, module, queryType, data: notes, summary: lines.length ? `Recent notes:\n${lines.join("\n")}` : "No notes found." }; } case "rtasks": { const tasks = getRecentTasksForMI(space, limit); if (queryType === "count") { return { ok: true, module, queryType, data: { count: tasks.length }, summary: `${tasks.length} open tasks found.` }; } const lines = tasks.map((t) => `- "${t.title}" [${t.status}]${t.priority ? ` (${t.priority})` : ""}${t.description ? `: ${t.description.slice(0, 80)}` : ""}`); return { ok: true, module, queryType, data: tasks, summary: lines.length ? `Open tasks:\n${lines.join("\n")}` : "No open tasks." }; } case "rcal": { const events = getUpcomingEventsForMI(space, 14, limit); if (queryType === "count") { return { ok: true, module, queryType, data: { count: events.length }, summary: `${events.length} upcoming events.` }; } const lines = events.map((e) => { const date = e.allDay ? e.start.split("T")[0] : e.start; let line = `- ${date}: ${e.title}`; if (e.location) line += ` (${e.location})`; return line; }); return { ok: true, module, queryType, data: events, summary: lines.length ? `Upcoming events:\n${lines.join("\n")}` : "No upcoming events." }; } default: return { ok: false, module, queryType, data: null, summary: `Module "${module}" does not support content queries.` }; } }