{"_id":"@ejiogbevoices/sovereign-rag","_rev":"2-575bc177783c29eabd3da7e348703df0","name":"@ejiogbevoices/sovereign-rag","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@ejiogbevoices/sovereign-rag","version":"0.1.0","keywords":["rag","vector-search","multi-vector","pipeline","supabase","pgvector","cultural-heritage","ancestral-intelligence","ejiogbe"],"author":{"name":"Fenix Creation Studio LLC"},"license":"Apache-2.0","_id":"@ejiogbevoices/sovereign-rag@0.1.0","maintainers":[{"name":"monroerodriguez","email":"monroe@ejiogbevoices.com"}],"homepage":"https://github.com/ejiogbevoices/sovereign-rag#readme","bugs":{"url":"https://github.com/ejiogbevoices/sovereign-rag/issues"},"dist":{"shasum":"6bd551fc22db40354defc90f7e1786b1318fdbf0","tarball":"https://registry.npmjs.org/@ejiogbevoices/sovereign-rag/-/sovereign-rag-0.1.0.tgz","fileCount":20,"integrity":"sha512-xFcvK7ilod81tAAiUKa8igPvC1LZvkT7px9ddAkmPef1R9N3yqgcfjrEznEwmdH+3ivoZaOh8M4CwJjD/CPc5g==","signatures":[{"sig":"MEQCIHx8Ls/rPD0XSO8QV3xpxey2w/nKmFJE6R6dWsFoIFEMAiAl+OwZc28u3NgwHf4nk0WKTaDFtUXGiLoUp+p9CHy7Ow==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105056},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./store":{"types":"./dist/store/index.d.ts","import":"./dist/store/index.js"},"./vector":{"types":"./dist/vector/index.d.ts","import":"./dist/vector/index.js"},"./pipeline":{"types":"./dist/pipeline/index.d.ts","import":"./dist/pipeline/index.js"}},"gitHead":"7f36d76985e4b9736cd4c1af10d6183d8131d4ea","scripts":{"dev":"tsc --watch","lint":"eslint src/","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"monroerodriguez","email":"monroe@ejiogbevoices.com"},"repository":{"url":"git+https://github.com/ejiogbevoices/sovereign-rag.git","type":"git"},"_npmVersion":"11.6.2","description":"Multi-vector RAG pipeline engine for Ejiogbe Voices. Declarative YAML pipeline orchestration with multi-vector fusion search. TypeScript-native, Supabase-backed.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@supabase/supabase-js":"^2.49.0"},"peerDependencies":{"@supabase/supabase-js":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sovereign-rag_0.1.0_1771500692050_0.5121849201934461","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ejiogbevoices/sovereign-rag","version":"0.1.1","description":"Multi-vector RAG pipeline engine for Ejiogbe Voices. Declarative YAML pipeline orchestration with multi-vector fusion search. TypeScript-native, Supabase-backed.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./pipeline":{"import":"./dist/pipeline/index.js","types":"./dist/pipeline/index.d.ts"},"./vector":{"import":"./dist/vector/index.js","types":"./dist/vector/index.d.ts"},"./store":{"import":"./dist/store/index.js","types":"./dist/store/index.d.ts"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest run","test:watch":"vitest","lint":"eslint src/","typecheck":"tsc --noEmit"},"peerDependencies":{"@supabase/supabase-js":"^2.0.0"},"devDependencies":{"@supabase/supabase-js":"^2.49.0","typescript":"^5.7.0","vitest":"^3.0.0","@types/node":"^22.0.0"},"dependencies":{"yaml":"^2.7.0"},"keywords":["rag","vector-search","multi-vector","pipeline","supabase","pgvector","cultural-heritage","ancestral-intelligence","ejiogbe"],"license":"Apache-2.0","author":{"name":"Fenix Creation Studio LLC"},"repository":{"type":"git","url":"git+https://github.com/ejiogbevoices/sovereign-rag.git"},"gitHead":"7f36d76985e4b9736cd4c1af10d6183d8131d4ea","_id":"@ejiogbevoices/sovereign-rag@0.1.1","bugs":{"url":"https://github.com/ejiogbevoices/sovereign-rag/issues"},"homepage":"https://github.com/ejiogbevoices/sovereign-rag#readme","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-YHlJ1IrHxiplHI5fjlHL0+XIz6SoalIc26VYYR7GlSMKirSW8qChIW/HNbKoBM5jzuctMhtzGOCv/f3xQoAyXA==","shasum":"0ca71cd6304076583671a79eb942c3f41aec0dc1","tarball":"https://registry.npmjs.org/@ejiogbevoices/sovereign-rag/-/sovereign-rag-0.1.1.tgz","fileCount":20,"unpackedSize":105062,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD9+hRTbH2cVNMHrOTnJeZFD/BnH7ve+L8aglvf+NoS/wIhAJ7Q4g1PjLf0KFdrrFmpnstnNcvayoJ7FN7cGghJarMp"}]},"_npmUser":{"name":"monroerodriguez","email":"monroe@ejiogbevoices.com"},"directories":{},"maintainers":[{"name":"monroerodriguez","email":"monroe@ejiogbevoices.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sovereign-rag_0.1.1_1771501031352_0.11902085500800208"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-19T11:31:31.901Z","modified":"2026-02-19T11:37:11.632Z","0.1.0":"2026-02-19T11:31:32.231Z","0.1.1":"2026-02-19T11:37:11.495Z"},"bugs":{"url":"https://github.com/ejiogbevoices/sovereign-rag/issues"},"author":{"name":"Fenix Creation Studio LLC"},"license":"Apache-2.0","homepage":"https://github.com/ejiogbevoices/sovereign-rag#readme","keywords":["rag","vector-search","multi-vector","pipeline","supabase","pgvector","cultural-heritage","ancestral-intelligence","ejiogbe"],"repository":{"type":"git","url":"git+https://github.com/ejiogbevoices/sovereign-rag.git"},"description":"Multi-vector RAG pipeline engine for Ejiogbe Voices. Declarative YAML pipeline orchestration with multi-vector fusion search. TypeScript-native, Supabase-backed.","maintainers":[{"name":"monroerodriguez","email":"monroe@ejiogbevoices.com"}],"readme":"# Sovereign RAG\n\n**Multi-vector RAG pipeline engine for cultural heritage audio.**\n\nDeclarative pipeline orchestration with multi-vector fusion search, built in TypeScript for React, React Native, and Swift environments.\n\nBuilt for [Ejiogbe Voices](https://ejiogbevoices.com) — the Sovereign AI (Ancestral Intelligence) Platform.\n\n## What It Does\n\nTwo problems solved in one library:\n\n**Pipeline orchestration**: Define RAG pipelines as declarative step sequences with loops, branches, and streaming. Tools are plain async functions running in-process.\n\n**Multi-vector fusion search**: Search across multiple embedding spaces simultaneously (text + audio, text + image, any combination) and fuse results via Reciprocal Rank Fusion or weighted scoring. Backed by Supabase pgvector.\n\n## Install\n\n```bash\nnpm install @ejiogbevoices/sovereign-rag @supabase/supabase-js\n```\n\n## Quick Start\n\n```typescript\nimport { createSovereignRAG, RrfReranker } from '@ejiogbevoices/sovereign-rag';\nimport { createClient } from '@supabase/supabase-js';\n\nconst rag = createSovereignRAG({\n  supabase: createClient(SUPABASE_URL, SUPABASE_KEY),\n  schemas: [{\n    name: 'audio_segments',\n    vectors: [\n      { name: 'text_embedding', dimension: 3072 },\n      { name: 'audio_embedding', dimension: 512 },\n    ],\n    fields: [\n      { name: 'transcript', dataType: 'STRING' },\n      { name: 'language', dataType: 'STRING' },\n      { name: 'tradition', dataType: 'STRING' },\n    ],\n  }],\n  generate: async (prompt) => {\n    const res = await fetch('https://api.anthropic.com/v1/messages', { ... });\n    return res.json().content[0].text;\n  },\n  textEmbed: async (text) => {\n    const res = await fetch('https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent', { ... });\n    return res.json().embedding.values;\n  },\n  reranker: new RrfReranker({ topn: 10, rankConstant: 60 }),\n});\n\n// Run a pipeline\nconst ctx = await rag.engine.run({\n  pipeline: [\n    'embed.text',\n    'retriever.search',\n    'generator.generate',\n  ],\n}, { text: 'Yoruba chanting patterns similar to Gregorian chant' });\n\nconsole.log(ctx.vars.answer);\n```\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────┐\n│                   PipelineEngine                     │\n│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │\n│  │  Steps   │→ │  Loops   │→ │    Branches      │  │\n│  └──────────┘  └──────────┘  └──────────────────┘  │\n│                      │                               │\n│              ┌───────▼───────┐                       │\n│              │ ToolRegistry  │                       │\n│              └───────┬───────┘                       │\n│  ┌───────────────────┼───────────────────┐          │\n│  │           │       │       │           │          │\n│  ▼           ▼       ▼       ▼           ▼          │\n│ embed    retriever  gen   prompt   utils/custom      │\n└──┬───────────┬───────────────────────────────────────┘\n   │           │\n   ▼           ▼\n┌──────┐  ┌──────────────────────────┐\n│Gemini│  │       Collection          │\n│CLAP  │  │  ┌─────────┐ ┌────────┐ │\n│GLAP  │  │  │ text_emb │ │audio_emb│ │\n│      │  │  └────┬─────┘ └───┬────┘ │\n└──────┘  │       │  Reranker  │      │\n          │       └─────┬──────┘      │\n          │             ▼             │\n          │     ┌──────────────┐      │\n          │     │  RRF/Weighted│      │\n          │     └──────┬───────┘      │\n          └────────────┼──────────────┘\n                       ▼\n              ┌─────────────────┐\n              │ Supabase pgvec  │\n              │ (or MemoryStore)│\n              └─────────────────┘\n```\n\n## Multi-Vector Search\n\nSearch multiple embedding spaces in parallel and fuse the results.\n\n```typescript\nimport { Collection, MemoryVectorStore, RrfReranker } from '@ejiogbevoices/sovereign-rag';\n\nconst store = new MemoryVectorStore();\nconst collection = new Collection({\n  store,\n  schema: {\n    name: 'audio_segments',\n    vectors: [\n      { name: 'text_embedding', dimension: 3072 },\n      { name: 'audio_embedding', dimension: 512 },\n    ],\n  },\n});\n\n// Insert a document with both text and audio embeddings\nawait collection.insert({\n  id: 'seg_042',\n  fields: { transcript: 'Sacred drumming pattern', language: 'yo' },\n  vectors: {\n    text_embedding: textVec,   // from Gemini text-embedding-004\n    audio_embedding: audioVec, // from CLAP or GLAP\n  },\n});\n\n// Fusion search: text meaning + acoustic similarity\nconst results = await collection.query({\n  vectors: [\n    { fieldName: 'text_embedding', vector: queryTextVec },\n    { fieldName: 'audio_embedding', vector: queryAudioVec },\n  ],\n  topk: 10,\n  reranker: new RrfReranker({ topn: 10, rankConstant: 60 }),\n});\n```\n\n### Rerankers\n\n**RrfReranker** (recommended default): Fuses by rank position across lists. Works well when mixing embeddings of different dimensions and scales (text 3072-dim + audio 512-dim). No score normalization needed.\n\n**WeightedReranker**: Normalizes scores per field, multiplies by weights, sums. Use when you want explicit control: \"70% text relevance, 30% acoustic similarity.\"\n\n**CustomReranker**: Pass your own fusion function for domain-specific strategies (e.g., boost results matching the user's language preference).\n\n## Pipeline Engine\n\nDeclarative pipeline definitions with loops and branches.\n\n### Simple Pipeline\n\n```typescript\nconst ctx = await engine.run({\n  pipeline: [\n    'embed.text',          // embed the query\n    'retriever.search',    // search the collection\n    'prompt.build',        // build the prompt from retrieved passages\n    'generator.generate',  // generate the answer\n  ],\n}, { text: 'user query here' });\n```\n\n### Loop (Iterative Refinement)\n\n```typescript\nconst ctx = await engine.run({\n  pipeline: [\n    'embed.text',\n    'retriever.search',\n    {\n      loop: {\n        times: 3,\n        steps: [\n          'prompt.generate_subqueries',\n          'generator.generate',\n          'retriever.search',\n          'utils.merge_passages',\n        ],\n      },\n    },\n    'prompt.final_answer',\n    'generator.generate',\n  ],\n});\n```\n\n### Branch (Conditional Routing)\n\n```typescript\nconst ctx = await engine.run({\n  pipeline: [\n    'embed.text',\n    'retriever.search',\n    {\n      branch: {\n        router: ['router.check_quality'],\n        branches: {\n          sufficient: ['generator.generate'],\n          insufficient: [\n            'prompt.generate_subqueries',\n            'retriever.search',\n            'generator.generate',\n          ],\n        },\n      },\n    },\n  ],\n});\n```\n\n### Custom Tools\n\n```typescript\nconst registry = new ToolRegistry();\n\nregistry.tool('custom', 'filter_by_tradition', {\n  handler: async (input, ctx) => {\n    const passages = ctx.vars.passages as Doc[];\n    const tradition = ctx.vars.tradition as string;\n    const filtered = passages.filter(p => p.fields?.tradition === tradition);\n    return { passages: filtered };\n  },\n});\n\nengine.run({\n  pipeline: ['retriever.search', 'custom.filter_by_tradition', 'generator.generate'],\n}, { tradition: 'Yoruba' });\n```\n\n### Stream Events\n\n```typescript\nconst engine = new PipelineEngine({\n  registry,\n  onStream: (event) => {\n    switch (event.type) {\n      case 'step_start': console.log(`Starting: ${event.step}`); break;\n      case 'token':      process.stdout.write(event.content); break;\n      case 'loop_iter':  console.log(`Iteration ${event.iteration}`); break;\n      case 'branch':     console.log(`Took branch: ${event.branch}`); break;\n    }\n  },\n});\n```\n\n## Supabase Setup\n\nFor each vector field you want to search, create an RPC function in Supabase:\n\n```sql\ncreate table audio_segments (\n  id text primary key,\n  transcript text,\n  language text,\n  tradition text,\n  text_embedding vector(3072),\n  audio_embedding vector(512)\n);\n\ncreate index on audio_segments\n  using hnsw (text_embedding vector_cosine_ops)\n  with (m = 16, ef_construction = 64);\n\ncreate index on audio_segments\n  using hnsw (audio_embedding vector_cosine_ops)\n  with (m = 16, ef_construction = 64);\n\ncreate or replace function match_audio_segments_text_embedding(\n  query_embedding vector(3072),\n  match_count int default 10,\n  filter_expr text default null\n)\nreturns table (id text, similarity float, transcript text, language text, tradition text)\nlanguage plpgsql as $$\nbegin\n  return query\n    select\n      a.id,\n      1 - (a.text_embedding <=> query_embedding) as similarity,\n      a.transcript, a.language, a.tradition\n    from audio_segments a\n    order by a.text_embedding <=> query_embedding\n    limit match_count;\nend;\n$$;\n\ncreate or replace function match_audio_segments_audio_embedding(\n  query_embedding vector(512),\n  match_count int default 10,\n  filter_expr text default null\n)\nreturns table (id text, similarity float, transcript text, language text, tradition text)\nlanguage plpgsql as $$\nbegin\n  return query\n    select\n      a.id,\n      1 - (a.audio_embedding <=> query_embedding) as similarity,\n      a.transcript, a.language, a.tradition\n    from audio_segments a\n    order by a.audio_embedding <=> query_embedding\n    limit match_count;\nend;\n$$;\n```\n\nThe naming convention for RPC functions is `match_{table}_{column}`. Override per collection:\n\n```typescript\nconst store = new SupabaseVectorStore({\n  client: supabase,\n  collections: {\n    audio_segments: {\n      rpcMap: {\n        text_embedding: 'search_text',\n        audio_embedding: 'search_audio',\n      },\n    },\n  },\n});\n```\n\n## Ejiogbe Voices Integration\n\nCross-tradition sonic discovery pipeline:\n\n```typescript\nconst rag = createSovereignRAG({\n  supabase,\n  schemas: [{\n    name: 'audio_segments',\n    vectors: [\n      { name: 'text_embedding', dimension: 3072 },\n      { name: 'audio_embedding', dimension: 512 },\n    ],\n  }],\n  textEmbed: geminiEmbed,\n  audioEmbed: clapEmbed,\n  generate: claudeGenerate,\n  reranker: new RrfReranker({ topn: 10 }),\n});\n\n// \"Find recordings that sound like this Yoruba chant but from other traditions\"\nconst ctx = await rag.engine.run({\n  pipeline: [\n    'embed.audio',\n    'embed.text',\n    'retriever.multi_search',\n    'prompt.build',\n    'generator.generate',\n  ],\n}, {\n  audio_data: referenceClipBuffer,\n  text: 'rhythmic call-and-response chanting patterns',\n  query_embeddings: {\n    text_embedding: textVec,\n    audio_embedding: audioVec,\n  },\n});\n```\n\n## Design Decisions\n\n**In-process tools.** Tools are plain async functions grouped by namespace. No subprocess spawning, no protocol overhead. Works on React Native and client-side environments.\n\n**Supabase pgvector as the vector backend.** ANN search runs in PostgreSQL via HNSW indexes. The multi-vector fusion and reranking logic runs in TypeScript on the client.\n\n**Type-safe pipeline definitions.** Pipeline steps, tools, and I/O mappings are fully typed. Your IDE catches wiring errors before runtime.\n\n**Portable across platforms.** Works in Node.js, React Native, Deno, and (via API) Swift. No Python, no CUDA, no Docker required at the application layer.\n\n## License\n\nApache 2.0\n","readmeFilename":"README.md"}