@retrivora-ai/rag-engine 1.9.7 → 1.9.8

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.
Files changed (58) hide show
  1. package/README.md +127 -135
  2. package/dist/{ILLMProvider-Bhk6zJOK.d.mts → ILLMProvider-B8ROITYK.d.mts} +57 -2
  3. package/dist/{ILLMProvider-Bhk6zJOK.d.ts → ILLMProvider-B8ROITYK.d.ts} +57 -2
  4. package/dist/handlers/index.d.mts +2 -2
  5. package/dist/handlers/index.d.ts +2 -2
  6. package/dist/handlers/index.js +2198 -457
  7. package/dist/handlers/index.mjs +2195 -457
  8. package/dist/{index-BJ4cd-t5.d.mts → index-B8PbEFSY.d.mts} +12 -2
  9. package/dist/{index-Bu7T6xgr.d.ts → index-BCPKUAVL.d.ts} +27 -52
  10. package/dist/{index-C3SVtPYg.d.mts → index-CrxCy36A.d.mts} +27 -52
  11. package/dist/{index-B9J_XEh0.d.ts → index-DNvoi-sV.d.ts} +12 -2
  12. package/dist/index.css +578 -273
  13. package/dist/index.d.mts +29 -7
  14. package/dist/index.d.ts +29 -7
  15. package/dist/index.js +1160 -282
  16. package/dist/index.mjs +1185 -292
  17. package/dist/server.d.mts +62 -6
  18. package/dist/server.d.ts +62 -6
  19. package/dist/server.js +2061 -306
  20. package/dist/server.mjs +2055 -306
  21. package/package.json +11 -7
  22. package/src/app/constants.tsx +37 -7
  23. package/src/components/AmbientBackground.tsx +10 -10
  24. package/src/components/ArchitectureCard.tsx +43 -7
  25. package/src/components/ArchitectureCardsSection.tsx +37 -4
  26. package/src/components/ChatWidget.tsx +2 -1
  27. package/src/components/ChatWindow.tsx +4 -1
  28. package/src/components/CodeViewer.tsx +19 -14
  29. package/src/components/DocViewer.tsx +43 -49
  30. package/src/components/Documentation.tsx +71 -51
  31. package/src/components/Hero.tsx +103 -20
  32. package/src/components/Lifecycle.tsx +65 -25
  33. package/src/components/MarkdownComponents.tsx +44 -1
  34. package/src/components/MessageBubble.tsx +162 -50
  35. package/src/components/constants.tsx +4 -0
  36. package/src/config/RagConfig.ts +46 -0
  37. package/src/config/constants.ts +4 -0
  38. package/src/config/serverConfig.ts +15 -0
  39. package/src/core/ConfigResolver.ts +6 -0
  40. package/src/core/DatabaseStorage.ts +469 -0
  41. package/src/core/LicenseVerifier.ts +154 -0
  42. package/src/core/MultiAgentCoordinator.ts +239 -0
  43. package/src/core/Pipeline.ts +146 -15
  44. package/src/core/Retrivora.ts +6 -0
  45. package/src/core/VectorPlugin.ts +12 -3
  46. package/src/core/mcp.ts +261 -0
  47. package/src/handlers/index.ts +449 -63
  48. package/src/hooks/useRagChat.ts +96 -42
  49. package/src/hooks/useStoredMessages.ts +15 -4
  50. package/src/index.ts +5 -0
  51. package/src/llm/LLMFactory.ts +9 -1
  52. package/src/llm/providers/GroqProvider.ts +176 -0
  53. package/src/llm/providers/QwenProvider.ts +191 -0
  54. package/src/server.ts +7 -0
  55. package/src/types/chat.ts +14 -0
  56. package/src/types/props.ts +12 -0
  57. package/.env.example +0 -80
  58. package/LICENSE.txt +0 -21
@@ -0,0 +1,261 @@
1
+ import { spawn, ChildProcess } from 'child_process';
2
+ import { MCPServerConfig } from '../config/RagConfig';
3
+
4
+ interface MCPTool {
5
+ name: string;
6
+ description?: string;
7
+ inputSchema: any;
8
+ }
9
+
10
+ interface MCPCallResult {
11
+ content: Array<{ type: string; text?: string; [key: string]: any }>;
12
+ isError?: boolean;
13
+ }
14
+
15
+ export class MCPClient {
16
+ private childProcess?: ChildProcess;
17
+ private sseUrl?: string;
18
+ private messageIdCounter = 0;
19
+ private pendingRequests = new Map<number, { resolve: (val: any) => void; reject: (err: any) => void }>();
20
+ private stdioBuffer = '';
21
+ private initialized = false;
22
+
23
+ constructor(private config: MCPServerConfig) {}
24
+
25
+ private getNextMessageId(): number {
26
+ return ++this.messageIdCounter;
27
+ }
28
+
29
+ /**
30
+ * Connect and initialize the MCP server connection.
31
+ */
32
+ async connect(): Promise<void> {
33
+ if (this.initialized) return;
34
+
35
+ if (this.config.transport === 'stdio') {
36
+ await this.connectStdio();
37
+ } else {
38
+ await this.connectSSE();
39
+ }
40
+
41
+ // Call initialize
42
+ try {
43
+ const response = await this.sendJsonRpc('initialize', {
44
+ protocolVersion: '2024-11-05',
45
+ capabilities: {},
46
+ clientInfo: {
47
+ name: 'retrivora-sdk',
48
+ version: '1.0.0',
49
+ },
50
+ });
51
+
52
+ // Send initialized notification
53
+ await this.sendNotification('notifications/initialized');
54
+ this.initialized = true;
55
+ console.log(`[MCPClient] Connected and initialized server "${this.config.name}" successfully.`);
56
+ } catch (err: any) {
57
+ this.disconnect();
58
+ throw new Error(`[MCPClient] Failed to initialize server "${this.config.name}": ${err.message}`);
59
+ }
60
+ }
61
+
62
+ private async connectStdio(): Promise<void> {
63
+ const cmd = this.config.command;
64
+ if (!cmd) {
65
+ throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
66
+ }
67
+
68
+ const args = this.config.args || [];
69
+ const env = { ...process.env, ...(this.config.env || {}) };
70
+
71
+ this.childProcess = spawn(cmd, args, { env, shell: true });
72
+
73
+ if (!this.childProcess || !this.childProcess.stdout || !this.childProcess.stdin) {
74
+ throw new Error(`[MCPClient] Failed to spawn stdio child process for "${this.config.name}"`);
75
+ }
76
+
77
+ this.childProcess.stdout.on('data', (data: Buffer) => {
78
+ this.stdioBuffer += data.toString('utf-8');
79
+ this.processStdioLines();
80
+ });
81
+
82
+ this.childProcess.stderr?.on('data', (data: Buffer) => {
83
+ console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString('utf-8'));
84
+ });
85
+
86
+ this.childProcess.on('close', (code) => {
87
+ console.log(`[MCPClient] Connection closed for "${this.config.name}" with exit code: ${code}`);
88
+ this.disconnect();
89
+ });
90
+
91
+ // Wait a brief tick to ensure stdout is set up
92
+ await new Promise((resolve) => setTimeout(resolve, 100));
93
+ }
94
+
95
+ private processStdioLines() {
96
+ let newlineIndex: number;
97
+ while ((newlineIndex = this.stdioBuffer.indexOf('\n')) !== -1) {
98
+ const line = this.stdioBuffer.substring(0, newlineIndex).trim();
99
+ this.stdioBuffer = this.stdioBuffer.substring(newlineIndex + 1);
100
+
101
+ if (!line) continue;
102
+
103
+ try {
104
+ const payload = JSON.parse(line);
105
+ if (payload.id !== undefined) {
106
+ const req = this.pendingRequests.get(Number(payload.id));
107
+ if (req) {
108
+ this.pendingRequests.delete(Number(payload.id));
109
+ if (payload.error) {
110
+ req.reject(new Error(payload.error.message || JSON.stringify(payload.error)));
111
+ } else {
112
+ req.resolve(payload.result);
113
+ }
114
+ }
115
+ }
116
+ } catch (e) {
117
+ console.warn(`[MCPClient] Error parsing stdio JSON-RPC line from "${this.config.name}":`, e, 'Line content:', line);
118
+ }
119
+ }
120
+ }
121
+
122
+ private async connectSSE(): Promise<void> {
123
+ if (!this.config.url) {
124
+ throw new Error(`[MCPClient] URL is required for sse transport on "${this.config.name}"`);
125
+ }
126
+
127
+ // Set up standard SSE handshake / SSE connection
128
+ // In serverless contexts, we pull initial SSE transport configuration,
129
+ // and route HTTP POSTs to the client URL.
130
+ this.sseUrl = this.config.url;
131
+ }
132
+
133
+ private async sendJsonRpc(method: string, params: any): Promise<any> {
134
+ const id = this.getNextMessageId();
135
+ const request = {
136
+ jsonrpc: '2.0',
137
+ id,
138
+ method,
139
+ params,
140
+ };
141
+
142
+ if (this.config.transport === 'stdio') {
143
+ if (!this.childProcess || !this.childProcess.stdin) {
144
+ throw new Error(`[MCPClient] Server "${this.config.name}" is not connected (stdio process missing)`);
145
+ }
146
+ return new Promise((resolve, reject) => {
147
+ this.pendingRequests.set(id, { resolve, reject });
148
+ this.childProcess!.stdin!.write(JSON.stringify(request) + '\n', 'utf-8');
149
+ });
150
+ } else {
151
+ // SSE / HTTP POST fallback for cloud/serverless setups
152
+ if (!this.sseUrl) {
153
+ throw new Error(`[MCPClient] Server "${this.config.name}" SSE URL is not initialized`);
154
+ }
155
+ const response = await fetch(this.sseUrl, {
156
+ method: 'POST',
157
+ headers: { 'Content-Type': 'application/json' },
158
+ body: JSON.stringify(request),
159
+ });
160
+ if (!response.ok) {
161
+ throw new Error(`SSE JSON-RPC POST failed with status ${response.status}`);
162
+ }
163
+ const payload = await response.json();
164
+ if (payload.error) {
165
+ throw new Error(payload.error.message || JSON.stringify(payload.error));
166
+ }
167
+ return payload.result;
168
+ }
169
+ }
170
+
171
+ private async sendNotification(method: string, params?: any): Promise<void> {
172
+ const notification = {
173
+ jsonrpc: '2.0',
174
+ method,
175
+ params,
176
+ };
177
+
178
+ if (this.config.transport === 'stdio') {
179
+ if (this.childProcess?.stdin) {
180
+ this.childProcess.stdin.write(JSON.stringify(notification) + '\n', 'utf-8');
181
+ }
182
+ } else if (this.sseUrl) {
183
+ await fetch(this.sseUrl, {
184
+ method: 'POST',
185
+ headers: { 'Content-Type': 'application/json' },
186
+ body: JSON.stringify(notification),
187
+ }).catch(err => console.warn('[MCPClient] Failed to send notification over SSE:', err));
188
+ }
189
+ }
190
+
191
+ /**
192
+ * List all tools offered by the MCP server.
193
+ */
194
+ async listTools(): Promise<MCPTool[]> {
195
+ await this.connect();
196
+ const result = await this.sendJsonRpc('tools/list', {});
197
+ return result?.tools || [];
198
+ }
199
+
200
+ /**
201
+ * Execute a tool on the MCP server.
202
+ */
203
+ async callTool(name: string, args: Record<string, any> = {}): Promise<MCPCallResult> {
204
+ await this.connect();
205
+ return await this.sendJsonRpc('tools/call', { name, arguments: args });
206
+ }
207
+
208
+ disconnect() {
209
+ this.initialized = false;
210
+ this.pendingRequests.forEach(req => req.reject(new Error('MCPClient disconnected')));
211
+ this.pendingRequests.clear();
212
+
213
+ if (this.childProcess) {
214
+ try {
215
+ this.childProcess.kill();
216
+ } catch { /* silent */ }
217
+ this.childProcess = undefined;
218
+ }
219
+ }
220
+ }
221
+
222
+ export class MCPRegistry {
223
+ private clients: MCPClient[] = [];
224
+
225
+ constructor(servers: MCPServerConfig[] = []) {
226
+ this.clients = servers.map(cfg => new MCPClient(cfg));
227
+ }
228
+
229
+ async getAllTools(): Promise<Array<{ serverName: string; tool: MCPTool }>> {
230
+ const list: Array<{ serverName: string; tool: MCPTool }> = [];
231
+ await Promise.all(
232
+ this.clients.map(async (client) => {
233
+ try {
234
+ const tools = await client.listTools();
235
+ tools.forEach(t => list.push({ serverName: client['config'].name, tool: t }));
236
+ } catch (e) {
237
+ console.warn(`[MCPRegistry] Failed to fetch tools from server "${client['config'].name}":`, e);
238
+ }
239
+ })
240
+ );
241
+ return list;
242
+ }
243
+
244
+ async callTool(toolName: string, args: Record<string, any> = {}): Promise<MCPCallResult> {
245
+ // Find client hosting this tool. (In standard MCP, tool names are unique per server block)
246
+ // We will search across all connected clients.
247
+ for (const client of this.clients) {
248
+ try {
249
+ const tools = await client.listTools();
250
+ if (tools.some(t => t.name === toolName)) {
251
+ return await client.callTool(toolName, args);
252
+ }
253
+ } catch { /* silent fallback */ }
254
+ }
255
+ throw new Error(`[MCPRegistry] Tool "${toolName}" not found on any registered MCP server.`);
256
+ }
257
+
258
+ disconnectAll() {
259
+ this.clients.forEach(c => c.disconnect());
260
+ }
261
+ }