@sparkleideas/plugins 3.0.0-alpha.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.
- package/README.md +401 -0
- package/__tests__/collection-manager.test.ts +332 -0
- package/__tests__/dependency-graph.test.ts +434 -0
- package/__tests__/enhanced-plugin-registry.test.ts +488 -0
- package/__tests__/plugin-registry.test.ts +368 -0
- package/__tests__/ruvector-bridge.test.ts +2429 -0
- package/__tests__/ruvector-integration.test.ts +1602 -0
- package/__tests__/ruvector-migrations.test.ts +1099 -0
- package/__tests__/ruvector-quantization.test.ts +846 -0
- package/__tests__/ruvector-streaming.test.ts +1088 -0
- package/__tests__/sdk.test.ts +325 -0
- package/__tests__/security.test.ts +348 -0
- package/__tests__/utils/ruvector-test-utils.ts +860 -0
- package/examples/plugin-creator/index.ts +636 -0
- package/examples/plugin-creator/plugin-creator.test.ts +312 -0
- package/examples/ruvector/README.md +288 -0
- package/examples/ruvector/attention-patterns.ts +394 -0
- package/examples/ruvector/basic-usage.ts +288 -0
- package/examples/ruvector/docker-compose.yml +75 -0
- package/examples/ruvector/gnn-analysis.ts +501 -0
- package/examples/ruvector/hyperbolic-hierarchies.ts +557 -0
- package/examples/ruvector/init-db.sql +119 -0
- package/examples/ruvector/quantization.ts +680 -0
- package/examples/ruvector/self-learning.ts +447 -0
- package/examples/ruvector/semantic-search.ts +576 -0
- package/examples/ruvector/streaming-large-data.ts +507 -0
- package/examples/ruvector/transactions.ts +594 -0
- package/examples/ruvector-plugins/hook-pattern-library.ts +486 -0
- package/examples/ruvector-plugins/index.ts +79 -0
- package/examples/ruvector-plugins/intent-router.ts +354 -0
- package/examples/ruvector-plugins/mcp-tool-optimizer.ts +424 -0
- package/examples/ruvector-plugins/reasoning-bank.ts +657 -0
- package/examples/ruvector-plugins/ruvector-plugins.test.ts +518 -0
- package/examples/ruvector-plugins/semantic-code-search.ts +498 -0
- package/examples/ruvector-plugins/shared/index.ts +20 -0
- package/examples/ruvector-plugins/shared/vector-utils.ts +257 -0
- package/examples/ruvector-plugins/sona-learning.ts +445 -0
- package/package.json +97 -0
- package/src/collections/collection-manager.ts +661 -0
- package/src/collections/index.ts +56 -0
- package/src/collections/official/index.ts +1040 -0
- package/src/core/base-plugin.ts +416 -0
- package/src/core/plugin-interface.ts +215 -0
- package/src/hooks/index.ts +685 -0
- package/src/index.ts +378 -0
- package/src/integrations/agentic-flow.ts +743 -0
- package/src/integrations/index.ts +88 -0
- package/src/integrations/ruvector/ARCHITECTURE.md +1245 -0
- package/src/integrations/ruvector/attention-advanced.ts +1040 -0
- package/src/integrations/ruvector/attention-executor.ts +782 -0
- package/src/integrations/ruvector/attention-mechanisms.ts +757 -0
- package/src/integrations/ruvector/attention.ts +1063 -0
- package/src/integrations/ruvector/gnn.ts +3050 -0
- package/src/integrations/ruvector/hyperbolic.ts +1948 -0
- package/src/integrations/ruvector/index.ts +394 -0
- package/src/integrations/ruvector/migrations/001_create_extension.sql +135 -0
- package/src/integrations/ruvector/migrations/002_create_vector_tables.sql +259 -0
- package/src/integrations/ruvector/migrations/003_create_indices.sql +328 -0
- package/src/integrations/ruvector/migrations/004_create_functions.sql +598 -0
- package/src/integrations/ruvector/migrations/005_create_attention_functions.sql +654 -0
- package/src/integrations/ruvector/migrations/006_create_gnn_functions.sql +728 -0
- package/src/integrations/ruvector/migrations/007_create_hyperbolic_functions.sql +762 -0
- package/src/integrations/ruvector/migrations/index.ts +35 -0
- package/src/integrations/ruvector/migrations/migrations.ts +647 -0
- package/src/integrations/ruvector/quantization.ts +2036 -0
- package/src/integrations/ruvector/ruvector-bridge.ts +2000 -0
- package/src/integrations/ruvector/self-learning.ts +2376 -0
- package/src/integrations/ruvector/streaming.ts +1737 -0
- package/src/integrations/ruvector/types.ts +1945 -0
- package/src/providers/index.ts +643 -0
- package/src/registry/dependency-graph.ts +568 -0
- package/src/registry/enhanced-plugin-registry.ts +994 -0
- package/src/registry/plugin-registry.ts +604 -0
- package/src/sdk/index.ts +563 -0
- package/src/security/index.ts +594 -0
- package/src/types/index.ts +446 -0
- package/src/workers/index.ts +700 -0
- package/tmp.json +0 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +23 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Creator Tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect } from 'vitest';
|
|
6
|
+
import {
|
|
7
|
+
pluginCreatorPlugin,
|
|
8
|
+
generatePlugin,
|
|
9
|
+
generateToolCode,
|
|
10
|
+
generateHookCode,
|
|
11
|
+
generateWorkerCode,
|
|
12
|
+
generateAgentTypeCode,
|
|
13
|
+
PLUGIN_TEMPLATES,
|
|
14
|
+
type CreatePluginOptions,
|
|
15
|
+
} from './index.js';
|
|
16
|
+
import { HookEvent } from '../../src/types/index.js';
|
|
17
|
+
|
|
18
|
+
describe('Plugin Creator Plugin', () => {
|
|
19
|
+
describe('pluginCreatorPlugin', () => {
|
|
20
|
+
it('should have correct metadata', () => {
|
|
21
|
+
expect(pluginCreatorPlugin.metadata.name).toBe('plugin-creator');
|
|
22
|
+
expect(pluginCreatorPlugin.metadata.version).toBe('1.0.0');
|
|
23
|
+
expect(pluginCreatorPlugin.metadata.tags).toContain('meta');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should register MCP tools', () => {
|
|
27
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
28
|
+
expect(tools.length).toBeGreaterThan(0);
|
|
29
|
+
|
|
30
|
+
const toolNames = tools.map(t => t.name);
|
|
31
|
+
expect(toolNames).toContain('create-plugin');
|
|
32
|
+
expect(toolNames).toContain('list-plugin-templates');
|
|
33
|
+
expect(toolNames).toContain('generate-tool');
|
|
34
|
+
expect(toolNames).toContain('generate-hook');
|
|
35
|
+
expect(toolNames).toContain('generate-worker');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should register hooks', () => {
|
|
39
|
+
const hooks = pluginCreatorPlugin.registerHooks?.() ?? [];
|
|
40
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
41
|
+
expect(hooks[0].name).toBe('plugin-creator-logger');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should register workers', () => {
|
|
45
|
+
const workers = pluginCreatorPlugin.registerWorkers?.() ?? [];
|
|
46
|
+
expect(workers.length).toBeGreaterThan(0);
|
|
47
|
+
expect(workers[0].name).toBe('plugin-code-generator');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('PLUGIN_TEMPLATES', () => {
|
|
52
|
+
it('should have all expected templates', () => {
|
|
53
|
+
const templateNames = Object.keys(PLUGIN_TEMPLATES);
|
|
54
|
+
expect(templateNames).toContain('minimal');
|
|
55
|
+
expect(templateNames).toContain('tool-plugin');
|
|
56
|
+
expect(templateNames).toContain('hooks-plugin');
|
|
57
|
+
expect(templateNames).toContain('worker-plugin');
|
|
58
|
+
expect(templateNames).toContain('swarm-plugin');
|
|
59
|
+
expect(templateNames).toContain('full-featured');
|
|
60
|
+
expect(templateNames).toContain('security-focused');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should have valid template structures', () => {
|
|
64
|
+
for (const [name, template] of Object.entries(PLUGIN_TEMPLATES)) {
|
|
65
|
+
expect(template.name).toBeDefined();
|
|
66
|
+
expect(template.description).toBeDefined();
|
|
67
|
+
expect(template.category).toMatch(/^(tools|hooks|workers|swarm|full)$/);
|
|
68
|
+
expect(Array.isArray(template.features)).toBe(true);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('generatePlugin', () => {
|
|
74
|
+
it('should generate a minimal plugin', () => {
|
|
75
|
+
const result = generatePlugin({
|
|
76
|
+
name: 'test-plugin',
|
|
77
|
+
version: '1.0.0',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(result.plugin).toBeDefined();
|
|
81
|
+
expect(result.metadata.name).toBe('test-plugin');
|
|
82
|
+
expect(result.metadata.version).toBe('1.0.0');
|
|
83
|
+
expect(result.code).toContain("PluginBuilder('test-plugin'");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should generate a plugin with tools', () => {
|
|
87
|
+
const result = generatePlugin({
|
|
88
|
+
name: 'tools-test',
|
|
89
|
+
features: { tools: true },
|
|
90
|
+
toolNames: ['my-tool', 'another-tool'],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const tools = result.plugin.registerMCPTools?.() ?? [];
|
|
94
|
+
expect(tools.length).toBe(2);
|
|
95
|
+
expect(tools[0].name).toBe('my-tool');
|
|
96
|
+
expect(tools[1].name).toBe('another-tool');
|
|
97
|
+
expect(result.code).toContain('MCPToolBuilder');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should generate a plugin with hooks', () => {
|
|
101
|
+
const result = generatePlugin({
|
|
102
|
+
name: 'hooks-test',
|
|
103
|
+
features: { hooks: true },
|
|
104
|
+
hookEvents: [HookEvent.SessionStart, HookEvent.PostTaskComplete],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const hooks = result.plugin.registerHooks?.() ?? [];
|
|
108
|
+
expect(hooks.length).toBe(2);
|
|
109
|
+
expect(result.code).toContain('HookBuilder');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should generate a plugin with workers', () => {
|
|
113
|
+
const result = generatePlugin({
|
|
114
|
+
name: 'workers-test',
|
|
115
|
+
features: { workers: true },
|
|
116
|
+
workerTypes: ['coder', 'reviewer'],
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const workers = result.plugin.registerWorkers?.() ?? [];
|
|
120
|
+
expect(workers.length).toBe(2);
|
|
121
|
+
expect(result.code).toContain('WorkerFactory');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should generate a plugin with swarm capabilities', () => {
|
|
125
|
+
const result = generatePlugin({
|
|
126
|
+
name: 'swarm-test',
|
|
127
|
+
features: { swarm: true },
|
|
128
|
+
agentTypes: ['coordinator', 'worker-agent'],
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const agents = result.plugin.registerAgentTypes?.() ?? [];
|
|
132
|
+
expect(agents.length).toBe(2);
|
|
133
|
+
expect(result.code).toContain('AgentTypeDefinition');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should apply template features', () => {
|
|
137
|
+
const result = generatePlugin({
|
|
138
|
+
name: 'full-test',
|
|
139
|
+
template: 'full-featured',
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const tools = result.plugin.registerMCPTools?.() ?? [];
|
|
143
|
+
const hooks = result.plugin.registerHooks?.() ?? [];
|
|
144
|
+
const workers = result.plugin.registerWorkers?.() ?? [];
|
|
145
|
+
const agents = result.plugin.registerAgentTypes?.() ?? [];
|
|
146
|
+
|
|
147
|
+
expect(tools.length).toBeGreaterThan(0);
|
|
148
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
149
|
+
expect(workers.length).toBeGreaterThan(0);
|
|
150
|
+
expect(agents.length).toBeGreaterThan(0);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should reject invalid plugin names', () => {
|
|
154
|
+
expect(() => generatePlugin({ name: 'Invalid Name' })).toThrow();
|
|
155
|
+
expect(() => generatePlugin({ name: '123-start' })).toThrow();
|
|
156
|
+
expect(() => generatePlugin({ name: 'ab' })).toThrow(); // Too short
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('generateToolCode', () => {
|
|
161
|
+
it('should generate valid tool definition', () => {
|
|
162
|
+
const { definition, code } = generateToolCode('my-tool');
|
|
163
|
+
|
|
164
|
+
expect(definition.name).toBe('my-tool');
|
|
165
|
+
expect(definition.handler).toBeDefined();
|
|
166
|
+
expect(code).toContain('MCPToolBuilder');
|
|
167
|
+
expect(code).toContain('my-tool');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('should sanitize invalid tool names', () => {
|
|
171
|
+
const { definition } = generateToolCode('Invalid Tool Name!');
|
|
172
|
+
expect(definition.name).toBe('custom-tool');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should create working handler', async () => {
|
|
176
|
+
const { definition } = generateToolCode('test-tool');
|
|
177
|
+
const result = await definition.handler({ input: 'test' });
|
|
178
|
+
|
|
179
|
+
expect(result.content).toBeDefined();
|
|
180
|
+
expect(result.content[0].type).toBe('text');
|
|
181
|
+
expect(result.content[0].text).toContain('test-tool');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('generateHookCode', () => {
|
|
186
|
+
it('should generate valid hook definition', () => {
|
|
187
|
+
const { definition, code } = generateHookCode(HookEvent.SessionStart);
|
|
188
|
+
|
|
189
|
+
expect(definition.event).toBe(HookEvent.SessionStart);
|
|
190
|
+
expect(definition.handler).toBeDefined();
|
|
191
|
+
expect(code).toContain('HookBuilder');
|
|
192
|
+
expect(code).toContain('SessionStart');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should create working handler', async () => {
|
|
196
|
+
const { definition } = generateHookCode(HookEvent.PostTaskComplete);
|
|
197
|
+
const result = await definition.handler({
|
|
198
|
+
event: HookEvent.PostTaskComplete,
|
|
199
|
+
data: { taskId: '123' },
|
|
200
|
+
timestamp: new Date(),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
expect(result.success).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
describe('generateWorkerCode', () => {
|
|
208
|
+
it('should generate valid worker definitions for known types', () => {
|
|
209
|
+
const types = ['coder', 'reviewer', 'tester', 'researcher', 'planner', 'coordinator', 'security', 'performance'];
|
|
210
|
+
|
|
211
|
+
for (const type of types) {
|
|
212
|
+
const { definition, code } = generateWorkerCode(type);
|
|
213
|
+
|
|
214
|
+
expect(definition.type).toBe(type);
|
|
215
|
+
expect(definition.name).toBe(`${type}-worker`);
|
|
216
|
+
expect(definition.capabilities.length).toBeGreaterThan(0);
|
|
217
|
+
expect(code).toContain('WorkerFactory');
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should fallback to specialized for unknown types', () => {
|
|
222
|
+
const { definition, code } = generateWorkerCode('custom-type');
|
|
223
|
+
|
|
224
|
+
expect(definition.type).toBe('specialized');
|
|
225
|
+
expect(code).toContain('createSpecialized');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
describe('generateAgentTypeCode', () => {
|
|
230
|
+
it('should generate valid agent type definition', () => {
|
|
231
|
+
const { definition, code } = generateAgentTypeCode('coordinator');
|
|
232
|
+
|
|
233
|
+
expect(definition.type).toBe('coordinator');
|
|
234
|
+
expect(definition.name).toBe('coordinator Agent');
|
|
235
|
+
expect(definition.model).toBe('claude-sonnet-4-20250514');
|
|
236
|
+
expect(code).toContain('AgentTypeDefinition');
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('should sanitize invalid agent type names', () => {
|
|
240
|
+
const { definition } = generateAgentTypeCode('Invalid Agent!');
|
|
241
|
+
expect(definition.type).toBe('custom-agent');
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('MCP Tool Handlers', () => {
|
|
247
|
+
it('create-plugin tool should work', async () => {
|
|
248
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
249
|
+
const createTool = tools.find(t => t.name === 'create-plugin');
|
|
250
|
+
|
|
251
|
+
expect(createTool).toBeDefined();
|
|
252
|
+
|
|
253
|
+
const result = await createTool!.handler({
|
|
254
|
+
name: 'test-created-plugin',
|
|
255
|
+
version: '1.0.0',
|
|
256
|
+
template: 'tool-plugin',
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
expect(result.content[0].text).toContain('test-created-plugin');
|
|
260
|
+
expect(result.content[0].text).toContain('created successfully');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('list-plugin-templates tool should work', async () => {
|
|
264
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
265
|
+
const listTool = tools.find(t => t.name === 'list-plugin-templates');
|
|
266
|
+
|
|
267
|
+
expect(listTool).toBeDefined();
|
|
268
|
+
|
|
269
|
+
const result = await listTool!.handler({});
|
|
270
|
+
|
|
271
|
+
expect(result.content[0].text).toContain('Available Plugin Templates');
|
|
272
|
+
expect(result.content[0].text).toContain('minimal');
|
|
273
|
+
expect(result.content[0].text).toContain('full-featured');
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('generate-tool tool should work', async () => {
|
|
277
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
278
|
+
const genTool = tools.find(t => t.name === 'generate-tool');
|
|
279
|
+
|
|
280
|
+
expect(genTool).toBeDefined();
|
|
281
|
+
|
|
282
|
+
const result = await genTool!.handler({ name: 'my-custom-tool' });
|
|
283
|
+
|
|
284
|
+
expect(result.content[0].text).toContain('Generated Tool');
|
|
285
|
+
expect(result.content[0].text).toContain('my-custom-tool');
|
|
286
|
+
expect(result.content[0].text).toContain('MCPToolBuilder');
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('generate-hook tool should work', async () => {
|
|
290
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
291
|
+
const genHook = tools.find(t => t.name === 'generate-hook');
|
|
292
|
+
|
|
293
|
+
expect(genHook).toBeDefined();
|
|
294
|
+
|
|
295
|
+
const result = await genHook!.handler({ event: HookEvent.SessionStart });
|
|
296
|
+
|
|
297
|
+
expect(result.content[0].text).toContain('Generated Hook');
|
|
298
|
+
expect(result.content[0].text).toContain('HookBuilder');
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('generate-worker tool should work', async () => {
|
|
302
|
+
const tools = pluginCreatorPlugin.registerMCPTools?.() ?? [];
|
|
303
|
+
const genWorker = tools.find(t => t.name === 'generate-worker');
|
|
304
|
+
|
|
305
|
+
expect(genWorker).toBeDefined();
|
|
306
|
+
|
|
307
|
+
const result = await genWorker!.handler({ type: 'coder' });
|
|
308
|
+
|
|
309
|
+
expect(result.content[0].text).toContain('Generated Worker');
|
|
310
|
+
expect(result.content[0].text).toContain('WorkerFactory');
|
|
311
|
+
});
|
|
312
|
+
});
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# RuVector PostgreSQL Bridge Examples
|
|
2
|
+
|
|
3
|
+
Comprehensive examples demonstrating the RuVector PostgreSQL Bridge plugin features.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18+
|
|
8
|
+
- Docker and Docker Compose
|
|
9
|
+
- TypeScript / ts-node
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### 1. Start PostgreSQL with pgvector
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd examples/ruvector
|
|
17
|
+
docker compose up -d
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This starts:
|
|
21
|
+
- PostgreSQL 16 with pgvector extension on port 5432
|
|
22
|
+
- Adminer (database UI) on port 8080
|
|
23
|
+
|
|
24
|
+
### 2. Install Dependencies
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# From the plugins root directory
|
|
28
|
+
npm install
|
|
29
|
+
npm run build
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 3. Run Examples
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Basic vector operations
|
|
36
|
+
npx ts-node examples/ruvector/basic-usage.ts
|
|
37
|
+
|
|
38
|
+
# Semantic code search
|
|
39
|
+
npx ts-node examples/ruvector/semantic-search.ts
|
|
40
|
+
|
|
41
|
+
# Attention mechanisms
|
|
42
|
+
npx ts-node examples/ruvector/attention-patterns.ts
|
|
43
|
+
|
|
44
|
+
# Graph neural networks
|
|
45
|
+
npx ts-node examples/ruvector/gnn-analysis.ts
|
|
46
|
+
|
|
47
|
+
# Hyperbolic embeddings
|
|
48
|
+
npx ts-node examples/ruvector/hyperbolic-hierarchies.ts
|
|
49
|
+
|
|
50
|
+
# Self-learning optimization
|
|
51
|
+
npx ts-node examples/ruvector/self-learning.ts
|
|
52
|
+
|
|
53
|
+
# Large-scale streaming
|
|
54
|
+
npx ts-node examples/ruvector/streaming-large-data.ts
|
|
55
|
+
|
|
56
|
+
# Quantization methods
|
|
57
|
+
npx ts-node examples/ruvector/quantization.ts
|
|
58
|
+
|
|
59
|
+
# Transaction patterns
|
|
60
|
+
npx ts-node examples/ruvector/transactions.ts
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Examples Overview
|
|
64
|
+
|
|
65
|
+
### 1. basic-usage.ts
|
|
66
|
+
|
|
67
|
+
Getting started with RuVector PostgreSQL Bridge:
|
|
68
|
+
- Connecting to PostgreSQL
|
|
69
|
+
- Creating collections with HNSW indexes
|
|
70
|
+
- Inserting and searching vectors
|
|
71
|
+
- Batch operations
|
|
72
|
+
- Update and delete operations
|
|
73
|
+
|
|
74
|
+
**Expected output:**
|
|
75
|
+
```
|
|
76
|
+
RuVector PostgreSQL Bridge - Basic Usage Example
|
|
77
|
+
================================================
|
|
78
|
+
|
|
79
|
+
1. Connecting to PostgreSQL...
|
|
80
|
+
Connected successfully!
|
|
81
|
+
|
|
82
|
+
2. Creating collection "documents"...
|
|
83
|
+
Collection created!
|
|
84
|
+
|
|
85
|
+
3. Inserting vectors...
|
|
86
|
+
Inserted: doc-1
|
|
87
|
+
...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. semantic-search.ts
|
|
91
|
+
|
|
92
|
+
Semantic code search implementation:
|
|
93
|
+
- Embedding code snippets
|
|
94
|
+
- Natural language queries
|
|
95
|
+
- Hybrid search (semantic + keyword)
|
|
96
|
+
- Relevance feedback / re-ranking
|
|
97
|
+
|
|
98
|
+
**Key concepts:**
|
|
99
|
+
- Code embeddings capture semantic meaning
|
|
100
|
+
- Natural language queries find relevant code
|
|
101
|
+
- Hybrid scoring combines multiple signals
|
|
102
|
+
|
|
103
|
+
### 3. attention-patterns.ts
|
|
104
|
+
|
|
105
|
+
Using attention mechanisms:
|
|
106
|
+
- Multi-head attention
|
|
107
|
+
- Self-attention
|
|
108
|
+
- Cross-attention (encoder-decoder)
|
|
109
|
+
- Causal attention (autoregressive)
|
|
110
|
+
- Flash attention simulation
|
|
111
|
+
- KV cache for inference
|
|
112
|
+
|
|
113
|
+
**Key concepts:**
|
|
114
|
+
- Different attention patterns for different use cases
|
|
115
|
+
- Memory and compute optimizations
|
|
116
|
+
- SQL generation for PostgreSQL execution
|
|
117
|
+
|
|
118
|
+
### 4. gnn-analysis.ts
|
|
119
|
+
|
|
120
|
+
Graph Neural Network analysis:
|
|
121
|
+
- Building code dependency graphs
|
|
122
|
+
- GCN (Graph Convolutional Network)
|
|
123
|
+
- GAT (Graph Attention Network)
|
|
124
|
+
- GraphSAGE for inductive learning
|
|
125
|
+
- Finding structurally similar modules
|
|
126
|
+
|
|
127
|
+
**Key concepts:**
|
|
128
|
+
- Code structure as a graph
|
|
129
|
+
- Learning from dependencies
|
|
130
|
+
- Structural similarity detection
|
|
131
|
+
|
|
132
|
+
### 5. hyperbolic-hierarchies.ts
|
|
133
|
+
|
|
134
|
+
Hyperbolic embeddings for hierarchies:
|
|
135
|
+
- File tree embeddings
|
|
136
|
+
- Class inheritance hierarchies
|
|
137
|
+
- Poincare ball model
|
|
138
|
+
- Hierarchy-aware distances
|
|
139
|
+
|
|
140
|
+
**Key concepts:**
|
|
141
|
+
- Hyperbolic space captures hierarchies better
|
|
142
|
+
- Nodes closer to origin = higher in hierarchy
|
|
143
|
+
- Distance reflects tree structure
|
|
144
|
+
|
|
145
|
+
### 6. self-learning.ts
|
|
146
|
+
|
|
147
|
+
Self-optimization features:
|
|
148
|
+
- Enabling the learning loop
|
|
149
|
+
- Query pattern recognition
|
|
150
|
+
- Auto-tuning HNSW parameters
|
|
151
|
+
- Anomaly detection
|
|
152
|
+
- EWC++ for preventing forgetting
|
|
153
|
+
|
|
154
|
+
**Key concepts:**
|
|
155
|
+
- Continuous learning from query patterns
|
|
156
|
+
- Automatic index optimization
|
|
157
|
+
- Pattern-based query prediction
|
|
158
|
+
|
|
159
|
+
### 7. streaming-large-data.ts
|
|
160
|
+
|
|
161
|
+
Handling large datasets:
|
|
162
|
+
- Streaming millions of vectors
|
|
163
|
+
- Backpressure handling
|
|
164
|
+
- Progress monitoring
|
|
165
|
+
- Memory-efficient processing
|
|
166
|
+
|
|
167
|
+
**Key concepts:**
|
|
168
|
+
- Async generators for streaming
|
|
169
|
+
- Semaphore-based backpressure
|
|
170
|
+
- Concurrent batch processing
|
|
171
|
+
|
|
172
|
+
### 8. quantization.ts
|
|
173
|
+
|
|
174
|
+
Memory optimization:
|
|
175
|
+
- Int8 scalar quantization (4x compression)
|
|
176
|
+
- Int4 scalar quantization (8x compression)
|
|
177
|
+
- Binary quantization (32x compression)
|
|
178
|
+
- Product Quantization (PQ)
|
|
179
|
+
- Recall vs compression trade-offs
|
|
180
|
+
|
|
181
|
+
**Key concepts:**
|
|
182
|
+
- Quantization reduces memory significantly
|
|
183
|
+
- Trade-off between compression and recall
|
|
184
|
+
- Different methods for different use cases
|
|
185
|
+
|
|
186
|
+
### 9. transactions.ts
|
|
187
|
+
|
|
188
|
+
ACID operations:
|
|
189
|
+
- Multi-vector atomic updates
|
|
190
|
+
- Savepoint usage
|
|
191
|
+
- Error recovery patterns
|
|
192
|
+
- Optimistic locking
|
|
193
|
+
|
|
194
|
+
**Key concepts:**
|
|
195
|
+
- Transactions ensure consistency
|
|
196
|
+
- Savepoints for partial rollbacks
|
|
197
|
+
- Retry with exponential backoff
|
|
198
|
+
|
|
199
|
+
## Configuration
|
|
200
|
+
|
|
201
|
+
### Environment Variables
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# PostgreSQL connection
|
|
205
|
+
export POSTGRES_HOST=localhost
|
|
206
|
+
export POSTGRES_PORT=5432
|
|
207
|
+
export POSTGRES_DB=vectors
|
|
208
|
+
export POSTGRES_USER=postgres
|
|
209
|
+
export POSTGRES_PASSWORD=postgres
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Docker Compose Services
|
|
213
|
+
|
|
214
|
+
| Service | Port | Description |
|
|
215
|
+
|---------|------|-------------|
|
|
216
|
+
| postgres | 5432 | PostgreSQL 16 with pgvector |
|
|
217
|
+
| adminer | 8080 | Database management UI |
|
|
218
|
+
|
|
219
|
+
Access Adminer at http://localhost:8080:
|
|
220
|
+
- System: PostgreSQL
|
|
221
|
+
- Server: postgres
|
|
222
|
+
- Username: postgres
|
|
223
|
+
- Password: postgres
|
|
224
|
+
- Database: vectors
|
|
225
|
+
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
### Connection Refused
|
|
229
|
+
|
|
230
|
+
Ensure PostgreSQL is running:
|
|
231
|
+
```bash
|
|
232
|
+
docker compose ps
|
|
233
|
+
docker compose logs postgres
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Extension Not Found
|
|
237
|
+
|
|
238
|
+
The pgvector extension should be auto-created. Verify:
|
|
239
|
+
```sql
|
|
240
|
+
SELECT * FROM pg_extension WHERE extname = 'vector';
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Out of Memory
|
|
244
|
+
|
|
245
|
+
For large datasets, adjust PostgreSQL memory settings in docker-compose.yml:
|
|
246
|
+
```yaml
|
|
247
|
+
command: >
|
|
248
|
+
postgres
|
|
249
|
+
-c shared_buffers=512MB
|
|
250
|
+
-c work_mem=32MB
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Slow Searches
|
|
254
|
+
|
|
255
|
+
Ensure HNSW index exists:
|
|
256
|
+
```sql
|
|
257
|
+
SELECT indexname FROM pg_indexes WHERE tablename = 'your_table';
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Tune search parameters:
|
|
261
|
+
```sql
|
|
262
|
+
SET hnsw.ef_search = 100; -- Increase for better recall
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Performance Tips
|
|
266
|
+
|
|
267
|
+
1. **Batch inserts** for bulk loading (1000+ vectors at a time)
|
|
268
|
+
2. **Use HNSW indexes** for approximate nearest neighbor search
|
|
269
|
+
3. **Tune ef_search** based on recall requirements
|
|
270
|
+
4. **Consider quantization** for large datasets
|
|
271
|
+
5. **Use connection pooling** for concurrent access
|
|
272
|
+
|
|
273
|
+
## Cleanup
|
|
274
|
+
|
|
275
|
+
Stop and remove containers:
|
|
276
|
+
```bash
|
|
277
|
+
docker compose down
|
|
278
|
+
|
|
279
|
+
# Remove data volumes too:
|
|
280
|
+
docker compose down -v
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Resources
|
|
284
|
+
|
|
285
|
+
- [pgvector Documentation](https://github.com/pgvector/pgvector)
|
|
286
|
+
- [RuVector Plugin Documentation](../../src/integrations/ruvector/README.md)
|
|
287
|
+
- [HNSW Algorithm Paper](https://arxiv.org/abs/1603.09320)
|
|
288
|
+
- [Poincare Embeddings Paper](https://arxiv.org/abs/1705.08039)
|