@rigstate/mcp 0.4.6 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -676,7 +676,7 @@ var QueryBrainInputSchema = z4.object({
676
676
  projectId: z4.string().uuid("Invalid project ID"),
677
677
  query: z4.string().min(1, "Query is required"),
678
678
  limit: z4.number().min(1).max(20).optional().default(8),
679
- threshold: z4.number().min(0).max(1).optional().default(0.5)
679
+ threshold: z4.number().min(0).max(1).optional().default(0.1)
680
680
  });
681
681
  var GetProjectContextInputSchema = z4.object({
682
682
  projectId: z4.string().uuid("Invalid project ID")
@@ -973,35 +973,42 @@ architecture rules, decisions, and constraints.`,
973
973
  return { content: [{ type: "text", text: result.formatted }] };
974
974
  }
975
975
  });
976
+ async function generateQueryEmbedding(query) {
977
+ const apiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY;
978
+ if (!apiKey) {
979
+ console.warn("GOOGLE_GENERATIVE_AI_API_KEY not found, skipping vector search.");
980
+ return null;
981
+ }
982
+ try {
983
+ const { google } = await import("@ai-sdk/google");
984
+ const { embed } = await import("ai");
985
+ const { embedding } = await embed({
986
+ model: google.embedding("text-embedding-004"),
987
+ value: query.replace(/\n/g, " ")
988
+ });
989
+ return embedding;
990
+ } catch (error) {
991
+ console.error("Failed to generate embedding for search:", error);
992
+ return null;
993
+ }
994
+ }
976
995
  async function queryBrain(supabase, userId, projectId, query, limit = 8, threshold = 0.5) {
977
996
  const { data: project, error: projectError } = await supabase.from("projects").select("id").eq("id", projectId).eq("owner_id", userId).single();
978
997
  if (projectError || !project) {
979
998
  throw new Error("Project not found or access denied");
980
999
  }
1000
+ const embedding = await generateQueryEmbedding(query);
981
1001
  let memories = [];
982
- const searchTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
983
- if (searchTerms.length > 0) {
984
- const orConditions = searchTerms.map((term) => `content.ilike.%${term}%`).join(",");
985
- const { data: keywordMatches, error: searchError } = await supabase.from("project_memories").select("id, content, category, tags, importance, created_at").eq("project_id", projectId).eq("is_active", true).or(orConditions).order("importance", { ascending: false, nullsFirst: false }).limit(limit);
986
- if (searchError) {
987
- console.error("Search error:", searchError);
988
- }
989
- if (keywordMatches) {
990
- memories = keywordMatches.map((m) => ({
991
- id: m.id,
992
- content: m.content,
993
- category: m.category || "general",
994
- tags: m.tags || [],
995
- netVotes: m.importance || 0,
996
- createdAt: m.created_at
997
- }));
998
- }
999
- }
1000
- if (memories.length === 0) {
1001
- const { data: recentMemories, error: recentError } = await supabase.from("project_memories").select("id, content, category, tags, importance, created_at").eq("project_id", projectId).eq("is_active", true).order("created_at", { ascending: false }).limit(limit);
1002
- if (recentError) {
1003
- console.error("Recent error:", recentError);
1004
- }
1002
+ const { data: searchResults, error: searchError } = await supabase.rpc("hybrid_search_memories", {
1003
+ p_project_id: projectId,
1004
+ p_query: query,
1005
+ p_embedding: embedding,
1006
+ p_limit: limit,
1007
+ p_similarity_threshold: threshold || 0.2
1008
+ });
1009
+ if (searchError) {
1010
+ console.error("Hybrid search error:", searchError);
1011
+ const { data: recentMemories } = await supabase.from("project_memories").select("id, content, category, tags, importance, created_at").eq("project_id", projectId).eq("is_active", true).order("created_at", { ascending: false }).limit(limit);
1005
1012
  if (recentMemories) {
1006
1013
  memories = recentMemories.map((m) => ({
1007
1014
  id: m.id,
@@ -1012,13 +1019,25 @@ async function queryBrain(supabase, userId, projectId, query, limit = 8, thresho
1012
1019
  createdAt: m.created_at
1013
1020
  }));
1014
1021
  }
1022
+ } else if (searchResults) {
1023
+ memories = searchResults.map((m) => ({
1024
+ id: m.id,
1025
+ content: m.content,
1026
+ category: m.category,
1027
+ tags: m.tags,
1028
+ netVotes: m.importance,
1029
+ createdAt: m.created_at
1030
+ }));
1015
1031
  }
1016
1032
  const contextLines = memories.map((m) => {
1017
1033
  const voteIndicator = m.netVotes && m.netVotes < 0 ? ` [\u26A0\uFE0F POORLY RATED: ${m.netVotes}]` : "";
1018
- const tagStr = m.tags.length > 0 ? ` [${m.tags.join(", ")}]` : "";
1019
- return `- [${m.category.toUpperCase()}]${tagStr}${voteIndicator}: ${m.content}`;
1034
+ const tagStr = m.tags && m.tags.length > 0 ? ` [${m.tags.join(", ")}]` : "";
1035
+ const category = m.category ? m.category.toUpperCase() : "GENERAL";
1036
+ return `- [${category}]${tagStr}${voteIndicator}: ${m.content}`;
1020
1037
  });
1038
+ const searchType = embedding ? "TRIPLE-HYBRID (Vector + FTS + Fuzzy)" : "HYBRID (FTS + Fuzzy)";
1021
1039
  const formatted = memories.length > 0 ? `=== PROJECT BRAIN: RELEVANT MEMORIES ===
1040
+ Search Mode: ${searchType}
1022
1041
  Query: "${query}"
1023
1042
  Found ${memories.length} relevant memories:
1024
1043