/** * MI Module Routes — maps module content types to API endpoints. * * Used by the action executor to route `create-content` / `update-content` / * `delete-content` actions to the correct module API path. Stable abstraction * layer between LLM output and actual HTTP calls. */ export interface ModuleRouteEntry { method: string; /** Path template — `:space` is replaced at execution time. */ path: string; } /** Content-type → route mapping per module. */ export const MODULE_ROUTES: Record> = { rcal: { event: { method: "POST", path: "/:space/rcal/api/events" }, }, rtasks: { task: { method: "POST", path: "/:space/rtasks/api/tasks" }, }, rnotes: { notebook: { method: "POST", path: "/:space/rnotes/api/notebooks" }, note: { method: "POST", path: "/:space/rnotes/api/notes" }, }, rforum: { thread: { method: "POST", path: "/:space/rforum/api/threads" }, post: { method: "POST", path: "/:space/rforum/api/posts" }, }, rflows: { flow: { method: "POST", path: "/:space/rflows/api/flows" }, }, rvote: { proposal: { method: "POST", path: "/:space/rvote/api/proposals" }, }, rchoices: { choice: { method: "POST", path: "/:space/rchoices/api/choices" }, }, rfiles: { file: { method: "POST", path: "/:space/rfiles/api/files" }, }, rphotos: { album: { method: "POST", path: "/:space/rphotos/api/albums" }, }, rdata: { dataset: { method: "POST", path: "/:space/rdata/api/datasets" }, }, }; /** * Resolve a module + contentType to the actual API endpoint path. * Returns null if the route is not known. */ export function resolveModuleRoute( module: string, contentType: string, space: string, ): { method: string; url: string } | null { const routes = MODULE_ROUTES[module]; if (!routes) return null; const entry = routes[contentType]; if (!entry) return null; return { method: entry.method, url: entry.path.replace(":space", encodeURIComponent(space)), }; } /** * Build a human-readable capabilities summary for a set of enabled modules. * Used in the MI system prompt so the LLM knows what it can create. */ export function buildModuleCapabilities(enabledModuleIds: string[]): string { const lines: string[] = []; for (const modId of enabledModuleIds) { const routes = MODULE_ROUTES[modId]; if (!routes) continue; const types = Object.keys(routes).join(", "); lines.push(`- ${modId}: create ${types}`); } return lines.length ? lines.join("\n") : "No module APIs available."; }