/** * MI Tool Schema β€” lightweight registry of canvas shape types with keyword * matching, so MI can suggest relevant tools as clickable chips. */ export interface ToolHint { tagName: string; label: string; icon: string; keywords: string[]; } const TOOL_HINTS: ToolHint[] = [ { tagName: "folk-markdown", label: "Note", icon: "πŸ“", keywords: ["note", "text", "markdown", "write", "document"] }, { tagName: "folk-wrapper", label: "Card", icon: "πŸ“‹", keywords: ["card", "wrapper", "container", "group"] }, { tagName: "folk-slide", label: "Slide", icon: "πŸ–ΌοΈ", keywords: ["slide", "presentation", "deck"] }, { tagName: "folk-chat", label: "Chat", icon: "πŸ’¬", keywords: ["chat", "message", "conversation", "talk"] }, { tagName: "folk-embed", label: "Embed", icon: "πŸ”—", keywords: ["embed", "iframe", "website", "url", "link"] }, { tagName: "folk-calendar", label: "Calendar", icon: "πŸ“…", keywords: ["calendar", "date", "schedule", "event"] }, { tagName: "folk-map", label: "Map", icon: "πŸ—ΊοΈ", keywords: ["map", "location", "place", "geo"] }, { tagName: "folk-image-gen", label: "AI Image", icon: "🎨", keywords: ["image", "picture", "photo", "generate", "art", "draw"] }, { tagName: "folk-video-gen", label: "AI Video", icon: "🎬", keywords: ["video", "clip", "animate", "movie", "film"] }, { tagName: "folk-prompt", label: "AI Chat", icon: "πŸ€–", keywords: ["ai", "prompt", "llm", "assistant", "gpt"] }, { tagName: "folk-transcription", label: "Transcribe", icon: "πŸŽ™οΈ", keywords: ["transcribe", "audio", "speech", "voice", "record"] }, { tagName: "folk-video-chat", label: "Video Call", icon: "πŸ“Ή", keywords: ["video call", "webcam", "meeting"] }, { tagName: "folk-obs-note", label: "Obsidian Note", icon: "πŸ““", keywords: ["obsidian", "note", "vault"] }, { tagName: "folk-workflow-block", label: "Workflow", icon: "βš™οΈ", keywords: ["workflow", "automation", "block", "process"] }, { tagName: "folk-social-post", label: "Social Post", icon: "πŸ“£", keywords: ["social", "post", "twitter", "instagram", "campaign"] }, { tagName: "folk-splat", label: "3D Gaussian", icon: "πŸ’Ž", keywords: ["3d", "splat", "gaussian", "point cloud"] }, { tagName: "folk-drawfast", label: "Drawing", icon: "✏️", keywords: ["draw", "sketch", "whiteboard", "pencil"] }, { tagName: "folk-rapp", label: "rApp Embed", icon: "πŸ“¦", keywords: ["rapp", "module", "embed", "app"] }, { tagName: "folk-feed", label: "Feed", icon: "πŸ“‘", keywords: ["feed", "data", "stream", "flow"] }, { tagName: "folk-piano", label: "Piano", icon: "🎹", keywords: ["piano", "music", "instrument", "midi"] }, { tagName: "folk-choice-vote", label: "Vote", icon: "πŸ—³οΈ", keywords: ["vote", "poll", "election", "choice"] }, { tagName: "folk-choice-rank", label: "Ranking", icon: "πŸ“Š", keywords: ["rank", "order", "priority", "sort"] }, { tagName: "folk-choice-spider", label: "Spider Chart", icon: "πŸ•ΈοΈ", keywords: ["spider", "radar", "criteria", "evaluate"] }, ]; /** * Given a user query, return matching tool hints (max 3). * Matches if any keyword appears in the query (case-insensitive). */ export function suggestTools(query: string): ToolHint[] { const q = query.toLowerCase(); const scored: { hint: ToolHint; score: number }[] = []; for (const hint of TOOL_HINTS) { let score = 0; for (const kw of hint.keywords) { if (q.includes(kw)) score += kw.length; // longer keyword match = higher relevance } if (score > 0) scored.push({ hint, score }); } return scored .sort((a, b) => b.score - a.score) .slice(0, 3) .map((s) => s.hint); }