From dd73588071b46e6afc6680de29946ee19fc64329 Mon Sep 17 00:00:00 2001 From: Adarsh Date: Tue, 17 Mar 2026 12:13:18 +0000 Subject: [PATCH] feat: Add CLI integration + VAJRA knowledge module - Add CLI commands: init, search, sync, stats - Export createKnowledgeEngine from index - Update to v1.1.0 - Add VAJRA integration example --- .gitignore | 1 + citations.d.ts | 20 ++++ citations.d.ts.map | 1 + citations.js | 56 ++++++++++++ citations.js.map | 1 + cli/index.js | 146 +++++++++++++++++++++++++++++ connectors/github.d.ts | 20 ++++ connectors/github.d.ts.map | 1 + connectors/github.js | 183 +++++++++++++++++++++++++++++++++++++ connectors/github.js.map | 1 + connectors/index.d.ts | 2 + connectors/index.d.ts.map | 1 + connectors/index.js | 3 + connectors/index.js.map | 1 + embeddings.d.ts | 15 +++ embeddings.d.ts.map | 1 + embeddings.js | 99 ++++++++++++++++++++ embeddings.js.map | 1 + engine.d.ts | 44 +++++++++ engine.d.ts.map | 1 + engine.js | 85 +++++++++++++++++ engine.js.map | 1 + index.d.ts | 8 ++ index.d.ts.map | 1 + index.js | 9 ++ index.js.map | 1 + package.json | 5 +- rag-query.d.ts | 23 +++++ rag-query.d.ts.map | 1 + rag-query.js | 114 +++++++++++++++++++++++ rag-query.js.map | 1 + src/index.ts | 4 +- types.d.ts | 53 +++++++++++ types.d.ts.map | 1 + types.js | 3 + types.js.map | 1 + vector-store.d.ts | 33 +++++++ vector-store.d.ts.map | 1 + vector-store.js | 102 +++++++++++++++++++++ vector-store.js.map | 1 + 40 files changed, 1043 insertions(+), 3 deletions(-) create mode 100644 citations.d.ts create mode 100644 citations.d.ts.map create mode 100644 citations.js create mode 100644 citations.js.map create mode 100644 cli/index.js create mode 100644 connectors/github.d.ts create mode 100644 connectors/github.d.ts.map create mode 100644 connectors/github.js create mode 100644 connectors/github.js.map create mode 100644 connectors/index.d.ts create mode 100644 connectors/index.d.ts.map create mode 100644 connectors/index.js create mode 100644 connectors/index.js.map create mode 100644 embeddings.d.ts create mode 100644 embeddings.d.ts.map create mode 100644 embeddings.js create mode 100644 embeddings.js.map create mode 100644 engine.d.ts create mode 100644 engine.d.ts.map create mode 100644 engine.js create mode 100644 engine.js.map create mode 100644 index.d.ts create mode 100644 index.d.ts.map create mode 100644 index.js create mode 100644 index.js.map create mode 100644 rag-query.d.ts create mode 100644 rag-query.d.ts.map create mode 100644 rag-query.js create mode 100644 rag-query.js.map create mode 100644 types.d.ts create mode 100644 types.d.ts.map create mode 100644 types.js create mode 100644 types.js.map create mode 100644 vector-store.d.ts create mode 100644 vector-store.d.ts.map create mode 100644 vector-store.js create mode 100644 vector-store.js.map diff --git a/.gitignore b/.gitignore index 7efc5d0..e367c9c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ dist/ .env .env.local .DS_Store +dist/ diff --git a/citations.d.ts b/citations.d.ts new file mode 100644 index 0000000..0a7b04b --- /dev/null +++ b/citations.d.ts @@ -0,0 +1,20 @@ +import { Citation } from './types.js'; +export declare class CitationTracker { + private citations; + private citationHistory; + addCitations(citations: Citation[]): void; + getCitations(): Citation[]; + getCitationsByQuery(queryHash: string): Citation[]; + formatCitations(): string; + formatCitationsInline(): string; + clear(): void; + exportHistory(): { + timestamp: string; + citations: Citation[]; + }[]; + getTopSources(limit?: number): { + source: string; + count: number; + }[]; +} +//# sourceMappingURL=citations.d.ts.map \ No newline at end of file diff --git a/citations.d.ts.map b/citations.d.ts.map new file mode 100644 index 0000000..97120d0 --- /dev/null +++ b/citations.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"citations.d.ts","sourceRoot":"","sources":["../src/citations.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,eAAe,CAAsC;IAE7D,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI;IAQzC,YAAY,IAAI,QAAQ,EAAE;IAI1B,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;IAIlD,eAAe,IAAI,MAAM;IAczB,qBAAqB,IAAI,MAAM;IAQ/B,KAAK,IAAI,IAAI;IAKb,aAAa,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;KAAE,EAAE;IAQ/D,aAAa,CAAC,KAAK,GAAE,MAAU,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE;CAYtE"} \ No newline at end of file diff --git a/citations.js b/citations.js new file mode 100644 index 0000000..333235a --- /dev/null +++ b/citations.js @@ -0,0 +1,56 @@ +// Citation Tracker +// Tracks sources and citations for RAG responses +export class CitationTracker { + citations = []; + citationHistory = new Map(); + addCitations(citations) { + this.citations = citations; + // Also store by query for history + const queryKey = Date.now().toString(); + this.citationHistory.set(queryKey, [...citations]); + } + getCitations() { + return this.citations; + } + getCitationsByQuery(queryHash) { + return this.citationHistory.get(queryHash) || []; + } + formatCitations() { + if (this.citations.length === 0) { + return ''; + } + const lines = ['\n\n**Sources:**']; + this.citations.forEach((cite, i) => { + lines.push(`[${i + 1}] ${cite.source}${cite.sourceUrl ? ` - ${cite.sourceUrl}` : ''}`); + }); + return lines.join('\n'); + } + formatCitationsInline() { + if (this.citations.length === 0) { + return ''; + } + return this.citations.map(c => `[${c.source}]`).join(', '); + } + clear() { + this.citations = []; + } + // Export all citation history + exportHistory() { + return Array.from(this.citationHistory.entries()).map(([timestamp, citations]) => ({ + timestamp, + citations + })); + } + // Get most cited sources + getTopSources(limit = 5) { + const counts = new Map(); + this.citations.forEach(cite => { + counts.set(cite.source, (counts.get(cite.source) || 0) + 1); + }); + return Array.from(counts.entries()) + .map(([source, count]) => ({ source, count })) + .sort((a, b) => b.count - a.count) + .slice(0, limit); + } +} +//# sourceMappingURL=citations.js.map \ No newline at end of file diff --git a/citations.js.map b/citations.js.map new file mode 100644 index 0000000..49575b0 --- /dev/null +++ b/citations.js.map @@ -0,0 +1 @@ +{"version":3,"file":"citations.js","sourceRoot":"","sources":["../src/citations.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,iDAAiD;AAIjD,MAAM,OAAO,eAAe;IAClB,SAAS,GAAe,EAAE,CAAC;IAC3B,eAAe,GAA4B,IAAI,GAAG,EAAE,CAAC;IAE7D,YAAY,CAAC,SAAqB;QAChC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,kCAAkC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,mBAAmB,CAAC,SAAiB;QACnC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACnD,CAAC;IAED,eAAe;QACb,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAEnC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,qBAAqB;QACnB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,8BAA8B;IAC9B,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;YACjF,SAAS;YACT,SAAS;SACV,CAAC,CAAC,CAAC;IACN,CAAC;IAED,yBAAyB;IACzB,aAAa,CAAC,QAAgB,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEzC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC5B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;aAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrB,CAAC;CACF"} \ No newline at end of file diff --git a/cli/index.js b/cli/index.js new file mode 100644 index 0000000..973ad78 --- /dev/null +++ b/cli/index.js @@ -0,0 +1,146 @@ +#!/usr/bin/env node + +/** + * Phantom Knowledge CLI + * Commands: init, search, sync, stats + */ + +import { createKnowledgeEngine, GitHubConnector } from '../dist/index.js'; + +const args = process.argv.slice(2); +const command = args[0]; + +async function main() { + switch (command) { + case 'init': + await cmdInit(); + break; + case 'search': + await cmdSearch(args[1]); + break; + case 'sync': + await cmdSync(args[1]); + break; + case 'stats': + await cmdStats(); + break; + default: + console.log(` +Phantom Knowledge Layer CLI + +Usage: phantom knowledge + +Commands: + init Initialize knowledge layer + search Search knowledge base + sync Sync from connector (github) + stats Show knowledge stats + +Examples: + phantom knowledge init + phantom knowledge search "what is VAJRA?" + phantom knowledge sync github + phantom knowledge stats +`); + } +} + +async function cmdInit() { + console.log('šŸ“š Initializing Phantom Knowledge Layer...'); + + const engine = await createKnowledgeEngine({ + embeddings: { + provider: process.env.EMBEDDING_PROVIDER || 'ollama', + model: process.env.EMBEDDING_MODEL || 'nomic-embed-text' + }, + vectorStore: { + type: process.env.VECTOR_STORE_TYPE || 'file', + path: process.env.VECTOR_STORE_PATH || './knowledge.json' + }, + llm: { + model: process.env.LLM_MODEL || 'gpt-4o-mini' + } + }); + + console.log('āœ… Knowledge engine initialized!'); + console.log('\nNext steps:'); + console.log(' 1. Set GITHUB_TOKEN for GitHub connector'); + console.log(' 2. Run: phantom knowledge sync github'); + console.log(' 3. Query: phantom knowledge search "your question"'); +} + +async function cmdSearch(query) { + if (!query) { + console.log('Error: Please provide a search query'); + console.log('Usage: phantom knowledge search ""'); + process.exit(1); + } + + console.log(`šŸ” Searching for: "${query}"`); + + const engine = await createKnowledgeEngine({ + embeddings: { provider: 'ollama' }, + vectorStore: { type: 'memory' } + }); + + const result = await engine.query(query); + + console.log('\nšŸ“ Answer:'); + console.log(result.answer); + + if (result.citations.length > 0) { + console.log('\nšŸ“š Sources:'); + result.citations.forEach((cite, i) => { + console.log(` [${i + 1}] ${cite.source}${cite.sourceUrl ? ` (${cite.sourceUrl})` : ''}`); + }); + } +} + +async function cmdSync(source) { + if (!source) { + console.log('Error: Please specify a source to sync'); + console.log('Usage: phantom knowledge sync '); + console.log('Available: github'); + process.exit(1); + } + + const token = process.env.GITHUB_TOKEN; + if (!token) { + console.log('Error: GITHUB_TOKEN not set'); + console.log('Set it with: export GITHUB_TOKEN=your_token'); + process.exit(1); + } + + console.log(`šŸ“„ Syncing from ${source}...`); + + const engine = await createKnowledgeEngine({ + embeddings: { provider: 'ollama' }, + vectorStore: { type: 'file', path: './knowledge.json' } + }); + + if (source === 'github') { + const [owner, repo] = (process.env.GITHUB_REPO || 'sir-ad/phantom-knowledge').split('/'); + const github = new GitHubConnector({ token, owner, repo }); + engine.registerConnector('github', github); + await engine.syncConnector('github'); + } + + const stats = engine.getStats(); + console.log(`\nāœ… Synced! Total documents: ${stats.documentCount}`); +} + +async function cmdStats() { + const engine = await createKnowledgeEngine({ + embeddings: { provider: 'ollama' }, + vectorStore: { type: 'file', path: './knowledge.json' } + }); + + const stats = engine.getStats(); + + console.log('šŸ“Š Knowledge Stats'); + console.log('─'.repeat(20)); + console.log(`Total Documents: ${stats.documentCount}`); + console.log(`Sources: ${stats.sources.join(', ')}`); +} + +main().catch(console.error); diff --git a/connectors/github.d.ts b/connectors/github.d.ts new file mode 100644 index 0000000..1e463ee --- /dev/null +++ b/connectors/github.d.ts @@ -0,0 +1,20 @@ +import { Document, Connector } from '../types.js'; +interface GitHubConfig { + token: string; + owner: string; + repo: string; +} +export declare class GitHubConnector implements Connector { + name: string; + private config; + private baseUrl; + constructor(config: GitHubConfig); + connect(): Promise; + fetch(): Promise; + sync(): Promise; + private fetchIssues; + private fetchPRs; + private fetchDiscussions; +} +export {}; +//# sourceMappingURL=github.d.ts.map \ No newline at end of file diff --git a/connectors/github.d.ts.map b/connectors/github.d.ts.map new file mode 100644 index 0000000..5e75918 --- /dev/null +++ b/connectors/github.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/connectors/github.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAuCD,qBAAa,eAAgB,YAAW,SAAS;IAC/C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAA4B;gBAE/B,MAAM,EAAE,YAAY;IAI1B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAcxB,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAU5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAMb,WAAW;YAmDX,QAAQ;YAkDR,gBAAgB;CAoE/B"} \ No newline at end of file diff --git a/connectors/github.js b/connectors/github.js new file mode 100644 index 0000000..1320d15 --- /dev/null +++ b/connectors/github.js @@ -0,0 +1,183 @@ +// GitHub Connector +// Fetches issues, PRs, discussions from GitHub repositories +export class GitHubConnector { + name = 'github'; + config; + baseUrl = 'https://api.github.com'; + constructor(config) { + this.config = config; + } + async connect() { + // Test connection + const response = await fetch(`${this.baseUrl}/repos/${this.config.owner}/${this.config.repo}`, { + headers: { + 'Authorization': `token ${this.config.token}`, + 'Accept': 'application/vnd.github.v3+json' + } + }); + if (!response.ok) { + throw new Error(`GitHub connection failed: ${response.statusText}`); + } + } + async fetch() { + const [issues, prs, discussions] = await Promise.all([ + this.fetchIssues(), + this.fetchPRs(), + this.fetchDiscussions() + ]); + return [...issues, ...prs, ...discussions]; + } + async sync() { + // For now, sync just fetches all + // Later, can implement incremental sync with last sync timestamp + await this.fetch(); + } + async fetchIssues() { + const documents = []; + let page = 1; + let hasMore = true; + while (hasMore && page <= 10) { + const response = await fetch(`${this.baseUrl}/repos/${this.config.owner}/${this.config.repo}/issues?state=all&page=${page}&per_page=100`, { + headers: { + 'Authorization': `token ${this.config.token}`, + 'Accept': 'application/vnd.github.v3+json' + } + }); + if (!response.ok) + break; + const issues = await response.json(); + if (issues.length === 0) { + hasMore = false; + } + else { + for (const issue of issues) { + // Skip PRs (they appear in issues API) + if ('pull_request' in issue) + continue; + const labels = issue.labels.map(l => l.name).join(', '); + documents.push({ + id: `issue-${issue.number}`, + content: `Issue #${issue.number}: ${issue.title}\n\n${issue.body || 'No description'}\n\nLabels: ${labels || 'None'}`, + source: `GitHub Issue #${issue.number}`, + sourceUrl: issue.html_url, + metadata: { + state: issue.state, + author: issue.user.login, + createdAt: issue.created_at, + updatedAt: issue.updated_at, + labels + }, + embeddedAt: 0 + }); + } + page++; + } + } + return documents; + } + async fetchPRs() { + const documents = []; + let page = 1; + let hasMore = true; + while (hasMore && page <= 10) { + const response = await fetch(`${this.baseUrl}/repos/${this.config.owner}/${this.config.repo}/pulls?state=all&page=${page}&per_page=100`, { + headers: { + 'Authorization': `token ${this.config.token}`, + 'Accept': 'application/vnd.github.v3+json' + } + }); + if (!response.ok) + break; + const prs = await response.json(); + if (prs.length === 0) { + hasMore = false; + } + else { + for (const pr of prs) { + const labels = pr.labels.map(l => l.name).join(', '); + documents.push({ + id: `pr-${pr.number}`, + content: `PR #${pr.number}: ${pr.title}\n\n${pr.body || 'No description'}\n\n+${pr.additions} -${pr.deletions} lines`, + source: `GitHub PR #${pr.number}`, + sourceUrl: pr.html_url, + metadata: { + state: pr.state, + author: pr.user.login, + createdAt: pr.created_at, + updatedAt: pr.updated_at, + labels, + additions: pr.additions, + deletions: pr.deletions + }, + embeddedAt: 0 + }); + } + page++; + } + } + return documents; + } + async fetchDiscussions() { + const documents = []; + // GraphQL is needed for discussions + const query = ` + query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + discussions(first: 100) { + nodes { + id + title + body + createdAt + updatedAt + url + category { + name + } + author { + login + } + } + } + } + } + `; + const response = await fetch(`${this.baseUrl}/graphql`, { + method: 'POST', + headers: { + 'Authorization': `token ${this.config.token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + query, + variables: { + owner: this.config.owner, + repo: this.config.repo + } + }) + }); + if (!response.ok) { + // Discussions might not be enabled + return documents; + } + const data = await response.json(); + const discussions = data.data?.repository?.discussions?.nodes || []; + for (const discussion of discussions) { + documents.push({ + id: `discussion-${discussion.id}`, + content: `Discussion: ${discussion.title}\n\n${discussion.body || 'No content'}\n\nCategory: ${discussion.category.name}`, + source: `GitHub Discussion`, + sourceUrl: discussion.url, + metadata: { + category: discussion.category.name, + author: discussion.author.login, + createdAt: discussion.created_at, + updatedAt: discussion.updated_at + }, + embeddedAt: 0 + }); + } + return documents; + } +} +//# sourceMappingURL=github.js.map \ No newline at end of file diff --git a/connectors/github.js.map b/connectors/github.js.map new file mode 100644 index 0000000..1476c75 --- /dev/null +++ b/connectors/github.js.map @@ -0,0 +1 @@ +{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/connectors/github.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/connectors/index.d.ts b/connectors/index.d.ts new file mode 100644 index 0000000..9fcdd79 --- /dev/null +++ b/connectors/index.d.ts @@ -0,0 +1,2 @@ +export { GitHubConnector } from './github.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/connectors/index.d.ts.map b/connectors/index.d.ts.map new file mode 100644 index 0000000..7c21dce --- /dev/null +++ b/connectors/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/connectors/index.js b/connectors/index.js new file mode 100644 index 0000000..207ab72 --- /dev/null +++ b/connectors/index.js @@ -0,0 +1,3 @@ +// Connector exports +export { GitHubConnector } from './github.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/connectors/index.js.map b/connectors/index.js.map new file mode 100644 index 0000000..b67c5ca --- /dev/null +++ b/connectors/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/embeddings.d.ts b/embeddings.d.ts new file mode 100644 index 0000000..259c265 --- /dev/null +++ b/embeddings.d.ts @@ -0,0 +1,15 @@ +import { EmbeddingOptions } from './types.js'; +export declare class Embeddings { + private provider; + private model; + private apiKey?; + private baseUrl?; + constructor(options: EmbeddingOptions); + embed(text: string): Promise; + embedBatch(texts: string[]): Promise; + private openAIEmbed; + private openAIEmbedBatch; + private ollamaEmbed; + cosineSimilarity(a: number[], b: number[]): number; +} +//# sourceMappingURL=embeddings.d.ts.map \ No newline at end of file diff --git a/embeddings.d.ts.map b/embeddings.d.ts.map new file mode 100644 index 0000000..a352067 --- /dev/null +++ b/embeddings.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../src/embeddings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAEhE,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;gBAEb,OAAO,EAAE,gBAAgB;IAO/B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQtC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAQxC,WAAW;YAqBX,gBAAgB;YAqBhB,WAAW;IAqBzB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;CAiBnD"} \ No newline at end of file diff --git a/embeddings.js b/embeddings.js new file mode 100644 index 0000000..0ad1732 --- /dev/null +++ b/embeddings.js @@ -0,0 +1,99 @@ +// Embeddings Module +// Handles text-to-vector conversion using OpenAI or Ollama +export class Embeddings { + provider; + model; + apiKey; + baseUrl; + constructor(options) { + this.provider = options.provider; + this.model = options.model || (options.provider === 'openai' ? 'text-embedding-3-small' : 'nomic-embed-text'); + this.apiKey = process.env.OPENAI_API_KEY; + this.baseUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434'; + } + async embed(text) { + if (this.provider === 'openai') { + return this.openAIEmbed(text); + } + else { + return this.ollamaEmbed(text); + } + } + async embedBatch(texts) { + if (this.provider === 'openai') { + return this.openAIEmbedBatch(texts); + } + else { + return Promise.all(texts.map(t => this.ollamaEmbed(t))); + } + } + async openAIEmbed(text) { + const response = await fetch('https://api.openai.com/v1/embeddings', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}` + }, + body: JSON.stringify({ + model: this.model, + input: text + }) + }); + if (!response.ok) { + throw new Error(`OpenAI embedding failed: ${response.statusText}`); + } + const data = await response.json(); + return data.data[0].embedding; + } + async openAIEmbedBatch(texts) { + const response = await fetch('https://api.openai.com/v1/embeddings', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}` + }, + body: JSON.stringify({ + model: this.model, + input: texts + }) + }); + if (!response.ok) { + throw new Error(`OpenAI embedding failed: ${response.statusText}`); + } + const data = await response.json(); + return data.data.map((item) => item.embedding); + } + async ollamaEmbed(text) { + const response = await fetch(`${this.baseUrl}/api/embeddings`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + model: this.model, + prompt: text + }) + }); + if (!response.ok) { + throw new Error(`Ollama embedding failed: ${response.statusText}`); + } + const data = await response.json(); + return data.embedding; + } + // Cosine similarity between two vectors + cosineSimilarity(a, b) { + if (a.length !== b.length) { + throw new Error('Vectors must have same dimensions'); + } + let dotProduct = 0; + let normA = 0; + let normB = 0; + for (let i = 0; i < a.length; i++) { + dotProduct += a[i] * b[i]; + normA += a[i] * a[i]; + normB += b[i] * b[i]; + } + return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); + } +} +//# sourceMappingURL=embeddings.js.map \ No newline at end of file diff --git a/embeddings.js.map b/embeddings.js.map new file mode 100644 index 0000000..2355935 --- /dev/null +++ b/embeddings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../src/embeddings.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/engine.d.ts b/engine.d.ts new file mode 100644 index 0000000..01b9542 --- /dev/null +++ b/engine.d.ts @@ -0,0 +1,44 @@ +import { Document, QueryResult, EmbeddingOptions, VectorStoreOptions } from './types.js'; +export interface KnowledgeEngineConfig { + embeddings: EmbeddingOptions; + vectorStore: VectorStoreOptions; + llm?: { + model?: string; + apiKey?: string; + baseUrl?: string; + }; +} +export declare class KnowledgeEngine { + private embeddings; + private vectorStore; + private ragQuery; + private citations; + private connectors; + private initialized; + constructor(config: KnowledgeEngineConfig); + initialize(): Promise; + addDocument(doc: Document): Promise; + addDocuments(docs: Document[]): Promise; + query(prompt: string, options?: { + maxTokens?: number; + temperature?: number; + }): Promise; + chat(message: string, history?: { + role: string; + content: string; + }[]): Promise; + registerConnector(name: string, connector: any): void; + syncConnector(name: string): Promise; + getStats(): { + documentCount: number; + sources: string[]; + topCitations: { + source: string; + count: number; + }[]; + }; + semanticSearch(query: string, limit?: number): Promise; + private ensureInitialized; +} +export declare function createKnowledgeEngine(config: KnowledgeEngineConfig): Promise; +//# sourceMappingURL=engine.d.ts.map \ No newline at end of file diff --git a/engine.d.ts.map b/engine.d.ts.map new file mode 100644 index 0000000..07cccdb --- /dev/null +++ b/engine.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEzF,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,GAAG,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,qBAAqB;IAOnC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAMnG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAMpG,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI;IAK/C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAchD,QAAQ;;;;;;;;IASF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU;IAKrD,OAAO,CAAC,iBAAiB;CAK1B;AAGD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAInG"} \ No newline at end of file diff --git a/engine.js b/engine.js new file mode 100644 index 0000000..9ba4c31 --- /dev/null +++ b/engine.js @@ -0,0 +1,85 @@ +// Knowledge Engine +// Main orchestrator for the knowledge layer +import { Embeddings } from './embeddings.js'; +import { VectorStore } from './vector-store.js'; +import { RAGQuery } from './rag-query.js'; +import { CitationTracker } from './citations.js'; +export class KnowledgeEngine { + embeddings; + vectorStore; + ragQuery; + citations; + connectors = new Map(); + initialized = false; + constructor(config) { + this.embeddings = new Embeddings(config.embeddings); + this.vectorStore = new VectorStore(this.embeddings, config.vectorStore); + this.citations = new CitationTracker(); + this.ragQuery = new RAGQuery(this.vectorStore, this.citations, config.llm); + } + async initialize() { + await this.vectorStore.initialize(); + this.initialized = true; + console.log('āœ… Knowledge Engine initialized'); + } + // Add a document directly + async addDocument(doc) { + this.ensureInitialized(); + await this.vectorStore.addDocument(doc); + } + // Add multiple documents + async addDocuments(docs) { + this.ensureInitialized(); + await this.vectorStore.addDocuments(docs); + } + // Query the knowledge base + async query(prompt, options) { + this.ensureInitialized(); + return this.ragQuery.query(prompt, options); + } + // Chat with context + async chat(message, history = []) { + this.ensureInitialized(); + return this.ragQuery.chat(message, history); + } + // Register a connector + registerConnector(name, connector) { + this.connectors.set(name, connector); + } + // Sync from a connector + async syncConnector(name) { + const connector = this.connectors.get(name); + if (!connector) { + throw new Error(`Connector ${name} not found`); + } + await connector.connect(); + const docs = await connector.fetch(); + await this.addDocuments(docs); + console.log(`šŸ“„ Synced ${docs.length} documents from ${name}`); + } + // Get stats + getStats() { + return { + documentCount: this.vectorStore.count(), + sources: [...new Set(this.vectorStore.getAllDocuments().map(d => d.source))], + topCitations: this.citations.getTopSources() + }; + } + // Search without LLM (just vector similarity) + async semanticSearch(query, limit = 5) { + this.ensureInitialized(); + return this.vectorStore.search(query, limit); + } + ensureInitialized() { + if (!this.initialized) { + throw new Error('Knowledge Engine not initialized. Call initialize() first.'); + } + } +} +// Factory function for easy creation +export async function createKnowledgeEngine(config) { + const engine = new KnowledgeEngine(config); + await engine.initialize(); + return engine; +} +//# sourceMappingURL=engine.js.map \ No newline at end of file diff --git a/engine.js.map b/engine.js.map new file mode 100644 index 0000000..7d38cc8 --- /dev/null +++ b/engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..2afe171 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,8 @@ +export { KnowledgeEngine, createKnowledgeEngine } from './engine.js'; +export { Embeddings } from './embeddings.js'; +export { VectorStore } from './vector-store.js'; +export { RAGQuery } from './rag-query.js'; +export { CitationTracker } from './citations.js'; +export { GitHubConnector } from './connectors/github.js'; +export type { Document, Citation, QueryResult, EmbeddingOptions, VectorStoreOptions, RAGOptions, Connector } from './types.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/index.d.ts.map b/index.d.ts.map new file mode 100644 index 0000000..f6a6938 --- /dev/null +++ b/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..601cb2f --- /dev/null +++ b/index.js @@ -0,0 +1,9 @@ +// Knowledge Layer Index +// Main entry point for Phantom Knowledge System +export { KnowledgeEngine, createKnowledgeEngine } from './engine.js'; +export { Embeddings } from './embeddings.js'; +export { VectorStore } from './vector-store.js'; +export { RAGQuery } from './rag-query.js'; +export { CitationTracker } from './citations.js'; +export { GitHubConnector } from './connectors/github.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/index.js.map b/index.js.map new file mode 100644 index 0000000..9016fe2 --- /dev/null +++ b/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,gDAAgD;AAEhD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"} \ No newline at end of file diff --git a/package.json b/package.json index 364d509..b039c9c 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "@phantom-pm/knowledge", - "version": "1.0.0", + "version": "1.1.0", "description": "Phantom Knowledge Layer - Vector embeddings, RAG, and connectors for Phantom PM OS", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", + "bin": { + "phantom-knowledge": "./cli/index.js" + }, "repository": { "type": "git", "url": "https://github.com/sir-ad/phantom-knowledge.git" diff --git a/rag-query.d.ts b/rag-query.d.ts new file mode 100644 index 0000000..821e587 --- /dev/null +++ b/rag-query.d.ts @@ -0,0 +1,23 @@ +import { VectorStore } from './vector-store.js'; +import { CitationTracker } from './citations.js'; +import { QueryResult, RAGOptions } from './types.js'; +export declare class RAGQuery { + private vectorStore; + private citations; + private model; + private apiKey?; + private baseUrl?; + constructor(vectorStore: VectorStore, citations: CitationTracker, options?: { + model?: string; + apiKey?: string; + baseUrl?: string; + }); + query(prompt: string, options?: RAGOptions): Promise; + private generateAnswer; + private summarizeFromContext; + chat(message: string, history?: { + role: string; + content: string; + }[]): Promise; +} +//# sourceMappingURL=rag-query.d.ts.map \ No newline at end of file diff --git a/rag-query.d.ts.map b/rag-query.d.ts.map new file mode 100644 index 0000000..1e487ee --- /dev/null +++ b/rag-query.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rag-query.d.ts","sourceRoot":"","sources":["../src/rag-query.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAY,UAAU,EAAE,MAAM,YAAY,CAAC;AAE/D,qBAAa,QAAQ;IACnB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;gBAGvB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,eAAe,EAC1B,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO;IAS/D,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,WAAW,CAAC;YA8E7D,cAAc;IA8B5B,OAAO,CAAC,oBAAoB;IAStB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC;CASrG"} \ No newline at end of file diff --git a/rag-query.js b/rag-query.js new file mode 100644 index 0000000..037f2ed --- /dev/null +++ b/rag-query.js @@ -0,0 +1,114 @@ +// RAG Query Engine +// Retrieves relevant context and generates answers with citations +export class RAGQuery { + vectorStore; + citations; + model; + apiKey; + baseUrl; + constructor(vectorStore, citations, options = {}) { + this.vectorStore = vectorStore; + this.citations = citations; + this.model = options.model || 'gpt-4o-mini'; + this.apiKey = options.apiKey || process.env.OPENAI_API_KEY; + this.baseUrl = options.baseUrl; + } + async query(prompt, options = {}) { + const { maxTokens = 4000, temperature = 0.7, includeCitations = true } = options; + // Step 1: Retrieve relevant documents + const relevantDocs = await this.vectorStore.search(prompt, 10); + if (relevantDocs.length === 0) { + return { + answer: "I don't have any relevant information to answer that question.", + citations: [], + sources: [], + contextUsed: 0 + }; + } + // Step 2: Build context from retrieved documents + const context = relevantDocs + .map((doc, i) => `[${i + 1}] ${doc.source}: ${doc.content}`) + .join('\n\n'); + // Step 3: Track citations + const citationList = []; + const sources = []; + if (includeCitations) { + relevantDocs.forEach((doc, i) => { + citationList.push({ + documentId: doc.id, + source: doc.source, + sourceUrl: doc.sourceUrl, + excerpt: doc.content.slice(0, 200) + '...', + relevanceScore: 1 - (i * 0.1) // Decreasing relevance score + }); + if (!sources.includes(doc.source)) { + sources.push(doc.source); + } + }); + this.citations.addCitations(citationList); + } + // Step 4: Generate answer using LLM + const systemPrompt = `You are a helpful assistant. Use the provided context to answer the user's question. +If you use information from the context, cite it using the source name in brackets. +If the context doesn't contain enough information to answer the question, say so.`; + const userPrompt = `Context: +${context} + +Question: ${prompt} + +Answer:`; + let answer; + try { + answer = await this.generateAnswer(systemPrompt, userPrompt, { + maxTokens, + temperature + }); + } + catch (error) { + // Fallback: summarize from context + answer = this.summarizeFromContext(relevantDocs, prompt); + } + return { + answer, + citations: citationList, + sources, + contextUsed: relevantDocs.length + }; + } + async generateAnswer(systemPrompt, userPrompt, options) { + const response = await fetch((this.baseUrl || 'https://api.openai.com/v1') + '/chat/completions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}` + }, + body: JSON.stringify({ + model: this.model, + messages: [ + { role: 'system', content: systemPrompt }, + { role: 'user', content: userPrompt } + ], + max_tokens: options.maxTokens, + temperature: options.temperature + }) + }); + if (!response.ok) { + throw new Error(`LLM query failed: ${response.statusText}`); + } + const data = await response.json(); + return data.choices[0].message.content; + } + summarizeFromContext(docs, query) { + const sources = [...new Set(docs.map(d => d.source))].join(', '); + return `Based on the available information from ${sources}:\n\n${docs.slice(0, 3).map(d => d.content).join('\n\n')}\n\nNote: This is a simplified answer. For more accurate results, please configure an LLM API key.`; + } + // Get conversation context + async chat(message, history = []) { + const result = await this.query(message); + // Add to history + history.push({ role: 'user', content: message }); + history.push({ role: 'assistant', content: result.answer }); + return result; + } +} +//# sourceMappingURL=rag-query.js.map \ No newline at end of file diff --git a/rag-query.js.map b/rag-query.js.map new file mode 100644 index 0000000..bd37b9f --- /dev/null +++ b/rag-query.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rag-query.js","sourceRoot":"","sources":["../src/rag-query.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 356f1af..0055467 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,10 @@ // Knowledge Layer Index // Main entry point for Phantom Knowledge System -export { KnowledgeEngine } from './engine.js'; +export { KnowledgeEngine, createKnowledgeEngine } from './engine.js'; export { Embeddings } from './embeddings.js'; export { VectorStore } from './vector-store.js'; export { RAGQuery } from './rag-query.js'; export { CitationTracker } from './citations.js'; export { GitHubConnector } from './connectors/github.js'; -export type { Document, Citation, QueryResult, EmbeddingOptions } from './types.js'; +export type { Document, Citation, QueryResult, EmbeddingOptions, VectorStoreOptions, RAGOptions, Connector } from './types.js'; diff --git a/types.d.ts b/types.d.ts new file mode 100644 index 0000000..3e72403 --- /dev/null +++ b/types.d.ts @@ -0,0 +1,53 @@ +export interface Document { + id: string; + content: string; + source: string; + sourceUrl?: string; + metadata: Record; + embeddedAt: number; +} +export interface EmbeddedDocument extends Document { + embedding: number[]; +} +export interface Citation { + documentId: string; + source: string; + sourceUrl?: string; + excerpt: string; + relevanceScore: number; +} +export interface QueryResult { + answer: string; + citations: Citation[]; + sources: string[]; + contextUsed: number; +} +export interface EmbeddingOptions { + provider: 'openai' | 'ollama'; + model?: string; + dimensions?: number; +} +export interface VectorStoreOptions { + type: 'memory' | 'file' | 'pinecone'; + path?: string; + apiKey?: string; +} +export interface KnowledgeIndex { + addDocument(doc: Document): Promise; + addDocuments(docs: Document[]): Promise; + search(query: string, limit?: number): Promise; + delete(id: string): Promise; + clear(): Promise; +} +export interface RAGOptions { + maxTokens?: number; + temperature?: number; + includeCitations?: boolean; +} +export interface Connector { + name: string; + connect(): Promise; + fetch(): Promise; + sync(): Promise; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/types.d.ts.map b/types.d.ts.map new file mode 100644 index 0000000..0091ac3 --- /dev/null +++ b/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACnE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"} \ No newline at end of file diff --git a/types.js b/types.js new file mode 100644 index 0000000..b2d067a --- /dev/null +++ b/types.js @@ -0,0 +1,3 @@ +// Knowledge Layer Types +export {}; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/types.js.map b/types.js.map new file mode 100644 index 0000000..4e4d20e --- /dev/null +++ b/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wBAAwB"} \ No newline at end of file diff --git a/vector-store.d.ts b/vector-store.d.ts new file mode 100644 index 0000000..46be26d --- /dev/null +++ b/vector-store.d.ts @@ -0,0 +1,33 @@ +import { EmbeddedDocument, VectorStoreOptions, KnowledgeIndex } from './types.js'; +import { Embeddings } from './embeddings.js'; +export declare class VectorStore implements KnowledgeIndex { + private documents; + private embeddings; + private storagePath?; + private storageType; + constructor(embeddings: Embeddings, options: VectorStoreOptions); + initialize(): Promise; + addDocument(doc: { + id: string; + content: string; + source: string; + sourceUrl?: string; + metadata: Record; + }): Promise; + addDocuments(docs: { + id: string; + content: string; + source: string; + sourceUrl?: string; + metadata: Record; + }[]): Promise; + search(query: string, limit?: number): Promise; + delete(id: string): Promise; + clear(): Promise; + getDocument(id: string): EmbeddedDocument | undefined; + getAllDocuments(): EmbeddedDocument[]; + count(): number; + private saveToFile; + private loadFromFile; +} +//# sourceMappingURL=vector-store.d.ts.map \ No newline at end of file diff --git a/vector-store.d.ts.map b/vector-store.d.ts.map new file mode 100644 index 0000000..89e1896 --- /dev/null +++ b/vector-store.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../src/vector-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAS7C,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAiC;gBAExC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB;IAMzD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,WAAW,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvI,YAAY,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB3I,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgBrE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIrD,eAAe,IAAI,gBAAgB,EAAE;IAIrC,KAAK,IAAI,MAAM;YAID,UAAU;YAWV,YAAY;CAc3B"} \ No newline at end of file diff --git a/vector-store.js b/vector-store.js new file mode 100644 index 0000000..6422200 --- /dev/null +++ b/vector-store.js @@ -0,0 +1,102 @@ +// Vector Store Module +// Stores and retrieves embeddings with similarity search +import { readFile, writeFile, access } from 'fs/promises'; +export class VectorStore { + documents = new Map(); + embeddings; + storagePath; + storageType; + constructor(embeddings, options) { + this.embeddings = embeddings; + this.storageType = options.type; + this.storagePath = options.path; + } + async initialize() { + if (this.storageType === 'file' && this.storagePath) { + await this.loadFromFile(); + } + } + async addDocument(doc) { + const embedding = await this.embeddings.embed(doc.content); + const embeddedDoc = { + ...doc, + embedding, + embeddedAt: Date.now() + }; + this.documents.set(doc.id, embeddedDoc); + if (this.storageType === 'file') { + await this.saveToFile(); + } + } + async addDocuments(docs) { + const contents = docs.map(d => d.content); + const embeddings = await this.embeddings.embedBatch(contents); + docs.forEach((doc, i) => { + const embeddedDoc = { + ...doc, + embedding: embeddings[i], + embeddedAt: Date.now() + }; + this.documents.set(doc.id, embeddedDoc); + }); + if (this.storageType === 'file') { + await this.saveToFile(); + } + } + async search(query, limit = 5) { + const queryEmbedding = await this.embeddings.embed(query); + const results = []; + for (const doc of this.documents.values()) { + const score = this.embeddings.cosineSimilarity(queryEmbedding, doc.embedding); + results.push({ doc, score }); + } + // Sort by score descending + results.sort((a, b) => b.score - a.score); + return results.slice(0, limit).map(r => r.doc); + } + async delete(id) { + this.documents.delete(id); + if (this.storageType === 'file') { + await this.saveToFile(); + } + } + async clear() { + this.documents.clear(); + if (this.storageType === 'file') { + await this.saveToFile(); + } + } + getDocument(id) { + return this.documents.get(id); + } + getAllDocuments() { + return Array.from(this.documents.values()); + } + count() { + return this.documents.size; + } + async saveToFile() { + if (!this.storagePath) + return; + const data = { + documents: Array.from(this.documents.values()), + version: 1 + }; + await writeFile(this.storagePath, JSON.stringify(data, null, 2), 'utf-8'); + } + async loadFromFile() { + if (!this.storagePath) + return; + try { + await access(this.storagePath); + const content = await readFile(this.storagePath, 'utf-8'); + const data = JSON.parse(content); + this.documents = new Map(data.documents.map(d => [d.id, d])); + } + catch { + // File doesn't exist yet, start fresh + this.documents = new Map(); + } + } +} +//# sourceMappingURL=vector-store.js.map \ No newline at end of file diff --git a/vector-store.js.map b/vector-store.js.map new file mode 100644 index 0000000..0029bca --- /dev/null +++ b/vector-store.js.map @@ -0,0 +1 @@ +{"version":3,"file":"vector-store.js","sourceRoot":"","sources":["../src/vector-store.ts"],"names":[],"mappings":"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"} \ No newline at end of file