rspace-online/lib/mi-module-routes.ts

86 lines
2.5 KiB
TypeScript

/**
* 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<string, Record<string, ModuleRouteEntry>> = {
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.";
}