@mcp-abap-adt/pg-vector-rag 11.0.0
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 +31 -0
- package/dist/__tests__/connection.test.d.ts +2 -0
- package/dist/__tests__/connection.test.d.ts.map +1 -0
- package/dist/__tests__/connection.test.js +34 -0
- package/dist/__tests__/connection.test.js.map +1 -0
- package/dist/__tests__/pg-vector-rag-provider.test.d.ts +2 -0
- package/dist/__tests__/pg-vector-rag-provider.test.d.ts.map +1 -0
- package/dist/__tests__/pg-vector-rag-provider.test.js +123 -0
- package/dist/__tests__/pg-vector-rag-provider.test.js.map +1 -0
- package/dist/__tests__/pg-vector-rag.test.d.ts +2 -0
- package/dist/__tests__/pg-vector-rag.test.d.ts.map +1 -0
- package/dist/__tests__/pg-vector-rag.test.js +84 -0
- package/dist/__tests__/pg-vector-rag.test.js.map +1 -0
- package/dist/__tests__/schema.test.d.ts +2 -0
- package/dist/__tests__/schema.test.d.ts.map +1 -0
- package/dist/__tests__/schema.test.js +30 -0
- package/dist/__tests__/schema.test.js.map +1 -0
- package/dist/connection.d.ts +26 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +24 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/pg-vector-rag-provider.d.ts +49 -0
- package/dist/pg-vector-rag-provider.d.ts.map +1 -0
- package/dist/pg-vector-rag-provider.js +87 -0
- package/dist/pg-vector-rag-provider.js.map +1 -0
- package/dist/pg-vector-rag.d.ts +34 -0
- package/dist/pg-vector-rag.d.ts.map +1 -0
- package/dist/pg-vector-rag.js +179 -0
- package/dist/pg-vector-rag.js.map +1 -0
- package/dist/schema.d.ts +6 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +28 -0
- package/dist/schema.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @mcp-abap-adt/pg-vector-rag
|
|
2
|
+
|
|
3
|
+
PostgreSQL + pgvector backend for @mcp-abap-adt/llm-agent.
|
|
4
|
+
|
|
5
|
+
Provides:
|
|
6
|
+
- `PgVectorRag` — `IRag` implementation backed by `vector(dim)` columns (pgvector extension).
|
|
7
|
+
- `PgVectorRagProvider` — `IRagProvider` for session/user/global collections.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- PostgreSQL 13+
|
|
12
|
+
- `pgvector` extension installed (`CREATE EXTENSION IF NOT EXISTS vector;`)
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @mcp-abap-adt/pg-vector-rag pg
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Minimal config
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
rag:
|
|
24
|
+
type: pg-vector
|
|
25
|
+
connectionString: postgres://user:pass@host:5432/mydb
|
|
26
|
+
collectionName: llm_agent_docs
|
|
27
|
+
dimension: 1536
|
|
28
|
+
autoCreateSchema: true
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
See the monorepo root README for full configuration surface.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/connection.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { resolvePgConnectArgs } from '../connection.js';
|
|
4
|
+
describe('resolvePgConnectArgs', () => {
|
|
5
|
+
it('parses postgres:// URL', () => {
|
|
6
|
+
const a = resolvePgConnectArgs({
|
|
7
|
+
connectionString: 'postgres://u:p@host:5432/db',
|
|
8
|
+
collectionName: 't',
|
|
9
|
+
});
|
|
10
|
+
assert.equal(a.connectionString, 'postgres://u:p@host:5432/db');
|
|
11
|
+
assert.equal(a.max, 10);
|
|
12
|
+
});
|
|
13
|
+
it('uses explicit fields', () => {
|
|
14
|
+
const a = resolvePgConnectArgs({
|
|
15
|
+
host: 'h',
|
|
16
|
+
port: 6543,
|
|
17
|
+
user: 'u',
|
|
18
|
+
password: 'p',
|
|
19
|
+
database: 'db',
|
|
20
|
+
poolMax: 3,
|
|
21
|
+
collectionName: 't',
|
|
22
|
+
});
|
|
23
|
+
assert.equal(a.host, 'h');
|
|
24
|
+
assert.equal(a.port, 6543);
|
|
25
|
+
assert.equal(a.user, 'u');
|
|
26
|
+
assert.equal(a.password, 'p');
|
|
27
|
+
assert.equal(a.database, 'db');
|
|
28
|
+
assert.equal(a.max, 3);
|
|
29
|
+
});
|
|
30
|
+
it('rejects missing host and connectionString', () => {
|
|
31
|
+
assert.throws(() => resolvePgConnectArgs({ user: 'u', password: 'p', collectionName: 't' }), /host|connectionString/i);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=connection.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../../src/__tests__/connection.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,gBAAgB,EAAE,6BAA6B;YAC/C,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,CAAC;YACV,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CACH,oBAAoB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,EACzE,wBAAwB,CACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag-provider.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pg-vector-rag-provider.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { PgVectorRagProvider } from '../pg-vector-rag-provider.js';
|
|
4
|
+
function makeEmbedder() {
|
|
5
|
+
return {
|
|
6
|
+
async embed() {
|
|
7
|
+
return { vector: [0, 0, 0] };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function makeFakeClient(rows = []) {
|
|
12
|
+
const calls = [];
|
|
13
|
+
return {
|
|
14
|
+
calls,
|
|
15
|
+
async query(sql, params = []) {
|
|
16
|
+
calls.push({ sql, params });
|
|
17
|
+
return { rows, rowCount: rows.length };
|
|
18
|
+
},
|
|
19
|
+
async end() { },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
describe('PgVectorRagProvider', () => {
|
|
23
|
+
it('createCollection runs schema bootstrap when autoCreateSchema=true', async () => {
|
|
24
|
+
const client = makeFakeClient();
|
|
25
|
+
const provider = new PgVectorRagProvider({
|
|
26
|
+
name: 'pg',
|
|
27
|
+
embedder: makeEmbedder(),
|
|
28
|
+
connection: {
|
|
29
|
+
collectionName: '__ignored',
|
|
30
|
+
host: 'h',
|
|
31
|
+
user: 'u',
|
|
32
|
+
password: 'p',
|
|
33
|
+
database: 'd',
|
|
34
|
+
},
|
|
35
|
+
defaultDimension: 3,
|
|
36
|
+
autoCreateSchema: true,
|
|
37
|
+
clientFactory: () => client,
|
|
38
|
+
});
|
|
39
|
+
const r = await provider.createCollection('docs', { scope: 'global' });
|
|
40
|
+
assert.equal(r.ok, true);
|
|
41
|
+
assert.ok(client.calls.some((c) => c.sql.includes('CREATE TABLE') && c.sql.includes('"docs"')));
|
|
42
|
+
});
|
|
43
|
+
it('createCollection skips DDL when autoCreateSchema=false', async () => {
|
|
44
|
+
const client = makeFakeClient();
|
|
45
|
+
const provider = new PgVectorRagProvider({
|
|
46
|
+
name: 'pg',
|
|
47
|
+
embedder: makeEmbedder(),
|
|
48
|
+
connection: {
|
|
49
|
+
collectionName: '__ignored',
|
|
50
|
+
host: 'h',
|
|
51
|
+
user: 'u',
|
|
52
|
+
password: 'p',
|
|
53
|
+
database: 'd',
|
|
54
|
+
},
|
|
55
|
+
defaultDimension: 3,
|
|
56
|
+
autoCreateSchema: false,
|
|
57
|
+
clientFactory: () => client,
|
|
58
|
+
});
|
|
59
|
+
const r = await provider.createCollection('docs', { scope: 'global' });
|
|
60
|
+
assert.equal(r.ok, true);
|
|
61
|
+
assert.ok(!client.calls.some((c) => c.sql.includes('CREATE TABLE')));
|
|
62
|
+
});
|
|
63
|
+
it('deleteCollection emits DROP TABLE', async () => {
|
|
64
|
+
const client = makeFakeClient();
|
|
65
|
+
const provider = new PgVectorRagProvider({
|
|
66
|
+
name: 'pg',
|
|
67
|
+
embedder: makeEmbedder(),
|
|
68
|
+
connection: {
|
|
69
|
+
collectionName: '__ignored',
|
|
70
|
+
host: 'h',
|
|
71
|
+
user: 'u',
|
|
72
|
+
password: 'p',
|
|
73
|
+
database: 'd',
|
|
74
|
+
},
|
|
75
|
+
clientFactory: () => client,
|
|
76
|
+
});
|
|
77
|
+
const r = await provider.deleteCollection('docs');
|
|
78
|
+
assert.equal(r.ok, true);
|
|
79
|
+
assert.ok(client.calls.some((c) => c.sql.startsWith('DROP TABLE')));
|
|
80
|
+
});
|
|
81
|
+
it('listCollections queries information_schema.tables', async () => {
|
|
82
|
+
const client = makeFakeClient([
|
|
83
|
+
{ table_name: 'docs' },
|
|
84
|
+
{ table_name: 'other' },
|
|
85
|
+
]);
|
|
86
|
+
const provider = new PgVectorRagProvider({
|
|
87
|
+
name: 'pg',
|
|
88
|
+
embedder: makeEmbedder(),
|
|
89
|
+
connection: {
|
|
90
|
+
collectionName: '__ignored',
|
|
91
|
+
host: 'h',
|
|
92
|
+
user: 'u',
|
|
93
|
+
password: 'p',
|
|
94
|
+
database: 'd',
|
|
95
|
+
},
|
|
96
|
+
clientFactory: () => client,
|
|
97
|
+
});
|
|
98
|
+
const r = await provider.listCollections();
|
|
99
|
+
assert.equal(r.ok, true);
|
|
100
|
+
if (!r.ok)
|
|
101
|
+
throw new Error('unreachable');
|
|
102
|
+
assert.deepEqual(r.value, ['docs', 'other']);
|
|
103
|
+
});
|
|
104
|
+
it('rejects unsupported scope', async () => {
|
|
105
|
+
const client = makeFakeClient();
|
|
106
|
+
const provider = new PgVectorRagProvider({
|
|
107
|
+
name: 'pg',
|
|
108
|
+
embedder: makeEmbedder(),
|
|
109
|
+
connection: {
|
|
110
|
+
collectionName: '__ignored',
|
|
111
|
+
host: 'h',
|
|
112
|
+
user: 'u',
|
|
113
|
+
password: 'p',
|
|
114
|
+
database: 'd',
|
|
115
|
+
},
|
|
116
|
+
clientFactory: () => client,
|
|
117
|
+
supportedScopes: ['global'],
|
|
118
|
+
});
|
|
119
|
+
const r = await provider.createCollection('docs', { scope: 'session' });
|
|
120
|
+
assert.equal(r.ok, false);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=pg-vector-rag-provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag-provider.test.js","sourceRoot":"","sources":["../../src/__tests__/pg-vector-rag-provider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pg-vector-rag.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { PgVectorRag } from '../pg-vector-rag.js';
|
|
4
|
+
function makeEmbedder(dim = 3) {
|
|
5
|
+
return {
|
|
6
|
+
async embed(text) {
|
|
7
|
+
let h = 0;
|
|
8
|
+
for (const ch of text)
|
|
9
|
+
h = (h * 31 + ch.charCodeAt(0)) | 0;
|
|
10
|
+
return {
|
|
11
|
+
vector: Array.from({ length: dim }, (_, i) => ((h >> i) & 0xff) / 255),
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function makeFakeClient(rows = []) {
|
|
17
|
+
const calls = [];
|
|
18
|
+
return {
|
|
19
|
+
calls,
|
|
20
|
+
async query(sql, params = []) {
|
|
21
|
+
calls.push({ sql, params });
|
|
22
|
+
return { rows, rowCount: rows.length };
|
|
23
|
+
},
|
|
24
|
+
async end() { },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
describe('PgVectorRag', () => {
|
|
28
|
+
it('ensureSchema runs CREATE EXTENSION + CREATE TABLE once', async () => {
|
|
29
|
+
const client = makeFakeClient();
|
|
30
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
31
|
+
await rag.ensureSchema();
|
|
32
|
+
await rag.ensureSchema();
|
|
33
|
+
const extCount = client.calls.filter((c) => c.sql.includes('CREATE EXTENSION')).length;
|
|
34
|
+
const tblCount = client.calls.filter((c) => c.sql.includes('CREATE TABLE')).length;
|
|
35
|
+
assert.equal(extCount, 1);
|
|
36
|
+
assert.equal(tblCount, 1);
|
|
37
|
+
});
|
|
38
|
+
it('query uses pgvector <=> distance and maps rows', async () => {
|
|
39
|
+
const rows = [
|
|
40
|
+
{ id: 'a', text: 'hello', metadata: { namespace: 'n' }, score: 0.1 },
|
|
41
|
+
];
|
|
42
|
+
const client = makeFakeClient(rows);
|
|
43
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
44
|
+
const r = await rag.query({ text: 'test query', toVector: async () => [0.1, 0.2, 0.3] }, 5);
|
|
45
|
+
assert.equal(r.ok, true);
|
|
46
|
+
if (!r.ok)
|
|
47
|
+
throw new Error('unreachable');
|
|
48
|
+
assert.equal(r.value[0].text, 'hello');
|
|
49
|
+
assert.equal(r.value[0].metadata?.namespace, 'n');
|
|
50
|
+
assert.ok(client.calls.some((c) => c.sql.includes('<=>')));
|
|
51
|
+
});
|
|
52
|
+
it('upsertRaw issues INSERT … ON CONFLICT', async () => {
|
|
53
|
+
const client = makeFakeClient();
|
|
54
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
55
|
+
const r = await rag.writer().upsertRaw('id1', 'text', { namespace: 'n' });
|
|
56
|
+
assert.equal(r.ok, true);
|
|
57
|
+
assert.ok(client.calls.some((c) => c.sql.includes('ON CONFLICT')));
|
|
58
|
+
});
|
|
59
|
+
it('deleteByIdRaw issues DELETE', async () => {
|
|
60
|
+
const client = makeFakeClient([{ '?column?': 1 }]);
|
|
61
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
62
|
+
const r = await rag.writer().deleteByIdRaw('id1');
|
|
63
|
+
assert.equal(r.ok, true);
|
|
64
|
+
assert.ok(client.calls.some((c) => c.sql.startsWith('DELETE FROM')));
|
|
65
|
+
});
|
|
66
|
+
it('clearAll issues TRUNCATE', async () => {
|
|
67
|
+
const client = makeFakeClient();
|
|
68
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
69
|
+
const r = await rag.writer().clearAll();
|
|
70
|
+
assert.equal(r.ok, true);
|
|
71
|
+
assert.ok(client.calls.some((c) => c.sql.startsWith('TRUNCATE')));
|
|
72
|
+
});
|
|
73
|
+
it('healthCheck runs SELECT 1', async () => {
|
|
74
|
+
const client = makeFakeClient([{ '?column?': 1 }]);
|
|
75
|
+
const rag = new PgVectorRag({ collectionName: 'docs', dimension: 3, embedder: makeEmbedder(3) }, client);
|
|
76
|
+
const r = await rag.healthCheck();
|
|
77
|
+
assert.equal(r.ok, true);
|
|
78
|
+
assert.ok(client.calls.some((c) => c.sql === 'SELECT 1'));
|
|
79
|
+
});
|
|
80
|
+
it('rejects invalid collection name', () => {
|
|
81
|
+
assert.throws(() => new PgVectorRag({ collectionName: "bad'; DROP", embedder: makeEmbedder() }, makeFakeClient()), (err) => err.code === 'INVALID_COLLECTION_NAME');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=pg-vector-rag.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag.test.js","sourceRoot":"","sources":["../../src/__tests__/pg-vector-rag.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { assertCollectionName, createExtensionSql, createTableSql, dropTableSql, quoteIdent, } from '../schema.js';
|
|
4
|
+
describe('pg schema', () => {
|
|
5
|
+
it('accepts a safe collection name', () => {
|
|
6
|
+
assertCollectionName('docs_2');
|
|
7
|
+
});
|
|
8
|
+
it('rejects digit-led name', () => {
|
|
9
|
+
assert.throws(() => assertCollectionName('1bad'), (err) => err.code === 'INVALID_COLLECTION_NAME');
|
|
10
|
+
});
|
|
11
|
+
it('rejects punctuation', () => {
|
|
12
|
+
assert.throws(() => assertCollectionName("x'); DROP"), (err) => err.code === 'INVALID_COLLECTION_NAME');
|
|
13
|
+
});
|
|
14
|
+
it('quotes identifiers with double-quotes', () => {
|
|
15
|
+
assert.equal(quoteIdent('docs'), '"docs"');
|
|
16
|
+
});
|
|
17
|
+
it('emits CREATE EXTENSION IF NOT EXISTS vector', () => {
|
|
18
|
+
assert.match(createExtensionSql(), /CREATE EXTENSION IF NOT EXISTS vector/);
|
|
19
|
+
});
|
|
20
|
+
it('emits CREATE TABLE with vector(n) and jsonb', () => {
|
|
21
|
+
const sql = createTableSql('docs', 1536);
|
|
22
|
+
assert.match(sql, /CREATE TABLE IF NOT EXISTS "docs"/);
|
|
23
|
+
assert.match(sql, /vector\(1536\)/);
|
|
24
|
+
assert.match(sql, /metadata JSONB/);
|
|
25
|
+
});
|
|
26
|
+
it('emits DROP TABLE DDL', () => {
|
|
27
|
+
assert.equal(dropTableSql('docs'), 'DROP TABLE IF EXISTS "docs"');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=schema.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.test.js","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,UAAU,GACX,MAAM,cAAc,CAAC;AAEtB,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAClC,CAAC,GAA8B,EAAE,EAAE,CACjC,GAAG,CAAC,IAAI,KAAK,yBAAyB,CACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,oBAAoB,CAAC,WAAW,CAAC,EACvC,CAAC,GAA8B,EAAE,EAAE,CACjC,GAAG,CAAC,IAAI,KAAK,yBAAyB,CACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,uCAAuC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,6BAA6B,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface PgVectorRagConfig {
|
|
2
|
+
connectionString?: string;
|
|
3
|
+
host?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
user?: string;
|
|
6
|
+
password?: string;
|
|
7
|
+
database?: string;
|
|
8
|
+
schema?: string;
|
|
9
|
+
collectionName: string;
|
|
10
|
+
dimension?: number;
|
|
11
|
+
autoCreateSchema?: boolean;
|
|
12
|
+
poolMax?: number;
|
|
13
|
+
connectTimeout?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PgPoolConfig {
|
|
16
|
+
connectionString?: string;
|
|
17
|
+
host?: string;
|
|
18
|
+
port?: number;
|
|
19
|
+
user?: string;
|
|
20
|
+
password?: string;
|
|
21
|
+
database?: string;
|
|
22
|
+
max: number;
|
|
23
|
+
connectionTimeoutMillis: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function resolvePgConnectArgs(cfg: PgVectorRagConfig): PgPoolConfig;
|
|
26
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,YAAY,CAwBzE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function resolvePgConnectArgs(cfg) {
|
|
2
|
+
const max = cfg.poolMax ?? 10;
|
|
3
|
+
const connectionTimeoutMillis = cfg.connectTimeout ?? 30_000;
|
|
4
|
+
if (cfg.connectionString) {
|
|
5
|
+
return {
|
|
6
|
+
connectionString: cfg.connectionString,
|
|
7
|
+
max,
|
|
8
|
+
connectionTimeoutMillis,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
if (!cfg.host) {
|
|
12
|
+
throw new Error('Postgres connectionString or host is required');
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
host: cfg.host,
|
|
16
|
+
port: cfg.port ?? 5432,
|
|
17
|
+
user: cfg.user,
|
|
18
|
+
password: cfg.password,
|
|
19
|
+
database: cfg.database,
|
|
20
|
+
max,
|
|
21
|
+
connectionTimeoutMillis,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,oBAAoB,CAAC,GAAsB;IACzD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAC9B,MAAM,uBAAuB,GAAG,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC;IAE7D,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzB,OAAO;YACL,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,GAAG;YACH,uBAAuB;SACxB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,GAAG;QACH,uBAAuB;KACxB,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { PgVectorRagConfig } from './pg-vector-rag.js';
|
|
2
|
+
export { PgVectorRag } from './pg-vector-rag.js';
|
|
3
|
+
export type { PgVectorRagProviderConfig } from './pg-vector-rag-provider.js';
|
|
4
|
+
export { PgVectorRagProvider } from './pg-vector-rag-provider.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { IEmbedder, IIdStrategy, IRag, IRagEditor, RagCollectionScope, Result } from '@mcp-abap-adt/llm-agent';
|
|
2
|
+
import { AbstractRagProvider, RagError } from '@mcp-abap-adt/llm-agent';
|
|
3
|
+
import type { PgVectorRagConfig } from './connection.js';
|
|
4
|
+
import { type PgClient } from './pg-vector-rag.js';
|
|
5
|
+
export interface PgVectorRagProviderConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
embedder: IEmbedder;
|
|
8
|
+
connection: PgVectorRagConfig | string;
|
|
9
|
+
defaultDimension?: number;
|
|
10
|
+
autoCreateSchema?: boolean;
|
|
11
|
+
editable?: boolean;
|
|
12
|
+
supportedScopes?: readonly RagCollectionScope[];
|
|
13
|
+
idStrategyFactory?: (opts: {
|
|
14
|
+
scope: RagCollectionScope;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
userId?: string;
|
|
17
|
+
}) => IIdStrategy;
|
|
18
|
+
/**
|
|
19
|
+
* Optional factory for driver clients used by deleteCollection / listCollections
|
|
20
|
+
* and (in tests) by createCollection. When omitted, deleteCollection and
|
|
21
|
+
* listCollections throw because schema-level operations require a shared client
|
|
22
|
+
* outside the per-collection PgVectorRag lifecycle.
|
|
23
|
+
*/
|
|
24
|
+
clientFactory?: () => PgClient;
|
|
25
|
+
}
|
|
26
|
+
export declare class PgVectorRagProvider extends AbstractRagProvider {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly kind = "vector";
|
|
29
|
+
readonly editable: boolean;
|
|
30
|
+
readonly supportedScopes: readonly RagCollectionScope[];
|
|
31
|
+
private readonly embedder;
|
|
32
|
+
private readonly connection;
|
|
33
|
+
private readonly defaultDimension;
|
|
34
|
+
private readonly autoCreateSchema;
|
|
35
|
+
private readonly clientFactory?;
|
|
36
|
+
constructor(cfg: PgVectorRagProviderConfig);
|
|
37
|
+
createCollection(name: string, opts: {
|
|
38
|
+
scope: RagCollectionScope;
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
userId?: string;
|
|
41
|
+
}): Promise<Result<{
|
|
42
|
+
rag: IRag;
|
|
43
|
+
editor: IRagEditor;
|
|
44
|
+
}, RagError>>;
|
|
45
|
+
deleteCollection(name: string): Promise<Result<void, RagError>>;
|
|
46
|
+
listCollections(): Promise<Result<string[], RagError>>;
|
|
47
|
+
private requireClient;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=pg-vector-rag-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag-provider.d.ts","sourceRoot":"","sources":["../src/pg-vector-rag-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,IAAI,EACJ,UAAU,EACV,kBAAkB,EAClB,MAAM,EACP,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,oBAAoB,CAAC;AAGhE,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE;QACzB,KAAK,EAAE,kBAAkB,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,KAAK,WAAW,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,QAAQ,CAAC;CAChC;AAQD,qBAAa,mBAAoB,SAAQ,mBAAmB;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAExD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAiB;gBAEpC,GAAG,EAAE,yBAAyB;IAapC,gBAAgB,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,KAAK,EAAE,kBAAkB,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACvE,OAAO,CAAC,MAAM,CAAC;QAAE,GAAG,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,EAAE,QAAQ,CAAC,CAAC;IAyBzD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAa/D,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;IAc5D,OAAO,CAAC,aAAa;CAQtB"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { AbstractRagProvider, RagError } from '@mcp-abap-adt/llm-agent';
|
|
2
|
+
import { PgVectorRag } from './pg-vector-rag.js';
|
|
3
|
+
import { dropTableSql } from './schema.js';
|
|
4
|
+
function normalizeConnection(c) {
|
|
5
|
+
return typeof c === 'string'
|
|
6
|
+
? { connectionString: c, collectionName: '__unused' }
|
|
7
|
+
: c;
|
|
8
|
+
}
|
|
9
|
+
export class PgVectorRagProvider extends AbstractRagProvider {
|
|
10
|
+
name;
|
|
11
|
+
kind = 'vector';
|
|
12
|
+
editable;
|
|
13
|
+
supportedScopes;
|
|
14
|
+
embedder;
|
|
15
|
+
connection;
|
|
16
|
+
defaultDimension;
|
|
17
|
+
autoCreateSchema;
|
|
18
|
+
clientFactory;
|
|
19
|
+
constructor(cfg) {
|
|
20
|
+
super();
|
|
21
|
+
this.name = cfg.name;
|
|
22
|
+
this.embedder = cfg.embedder;
|
|
23
|
+
this.connection = normalizeConnection(cfg.connection);
|
|
24
|
+
this.defaultDimension = cfg.defaultDimension ?? 1536;
|
|
25
|
+
this.autoCreateSchema = cfg.autoCreateSchema ?? true;
|
|
26
|
+
this.editable = cfg.editable ?? true;
|
|
27
|
+
this.supportedScopes = cfg.supportedScopes ?? ['session', 'user', 'global'];
|
|
28
|
+
this.clientFactory = cfg.clientFactory;
|
|
29
|
+
if (cfg.idStrategyFactory)
|
|
30
|
+
this.idStrategyFactory = cfg.idStrategyFactory;
|
|
31
|
+
}
|
|
32
|
+
async createCollection(name, opts) {
|
|
33
|
+
const scopeCheck = this.checkScope(opts.scope);
|
|
34
|
+
if (!scopeCheck.ok)
|
|
35
|
+
return scopeCheck;
|
|
36
|
+
try {
|
|
37
|
+
const rag = new PgVectorRag({
|
|
38
|
+
...this.connection,
|
|
39
|
+
collectionName: name,
|
|
40
|
+
dimension: this.connection.dimension ?? this.defaultDimension,
|
|
41
|
+
autoCreateSchema: this.autoCreateSchema,
|
|
42
|
+
embedder: this.embedder,
|
|
43
|
+
}, this.clientFactory?.());
|
|
44
|
+
if (this.autoCreateSchema)
|
|
45
|
+
await rag.ensureSchema();
|
|
46
|
+
const editor = this.buildEditor(rag, this.pickIdStrategy(opts));
|
|
47
|
+
return { ok: true, value: { rag, editor } };
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return {
|
|
51
|
+
ok: false,
|
|
52
|
+
error: new RagError(String(err), 'RAG_CREATE_ERROR'),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async deleteCollection(name) {
|
|
57
|
+
try {
|
|
58
|
+
const client = this.requireClient();
|
|
59
|
+
await client.query(dropTableSql(name));
|
|
60
|
+
return { ok: true, value: undefined };
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: new RagError(String(err), 'RAG_DELETE_ERROR'),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async listCollections() {
|
|
70
|
+
try {
|
|
71
|
+
const client = this.requireClient();
|
|
72
|
+
const schema = this.connection.schema ?? 'public';
|
|
73
|
+
const { rows } = await client.query('SELECT table_name FROM information_schema.tables WHERE table_schema = $1', [schema]);
|
|
74
|
+
return { ok: true, value: rows.map((r) => String(r.table_name)) };
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
return { ok: false, error: new RagError(String(err), 'RAG_LIST_ERROR') };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
requireClient() {
|
|
81
|
+
if (!this.clientFactory) {
|
|
82
|
+
throw new Error('PgVectorRagProvider deleteCollection/listCollections require clientFactory; provide one to enable schema-level operations');
|
|
83
|
+
}
|
|
84
|
+
return this.clientFactory();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pg-vector-rag-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag-provider.js","sourceRoot":"","sources":["../src/pg-vector-rag-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CallOptions, IEmbedder, IQueryEmbedding, IRag, IRagBackendWriter, RagMetadata, RagResult, Result } from '@mcp-abap-adt/llm-agent';
|
|
2
|
+
import { RagError } from '@mcp-abap-adt/llm-agent';
|
|
3
|
+
import type { PgVectorRagConfig } from './connection.js';
|
|
4
|
+
export type { PgVectorRagConfig };
|
|
5
|
+
export interface PgClient {
|
|
6
|
+
query(sql: string, params?: readonly unknown[]): Promise<{
|
|
7
|
+
rows: Array<Record<string, unknown>>;
|
|
8
|
+
rowCount: number;
|
|
9
|
+
}>;
|
|
10
|
+
end(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare class PgVectorRag implements IRag {
|
|
13
|
+
private readonly collectionName;
|
|
14
|
+
private readonly dimension;
|
|
15
|
+
private readonly embedder;
|
|
16
|
+
private readonly autoCreateSchema;
|
|
17
|
+
private readonly clientPromise;
|
|
18
|
+
private schemaReady;
|
|
19
|
+
private schemaPromise?;
|
|
20
|
+
constructor(config: PgVectorRagConfig & {
|
|
21
|
+
embedder: IEmbedder;
|
|
22
|
+
}, injectedClient?: PgClient);
|
|
23
|
+
private createDriverClient;
|
|
24
|
+
ensureSchema(): Promise<void>;
|
|
25
|
+
private maybeEnsureSchema;
|
|
26
|
+
query(embedding: IQueryEmbedding, k: number, options?: CallOptions): Promise<Result<RagResult[], RagError>>;
|
|
27
|
+
getById(id: string, options?: CallOptions): Promise<Result<RagResult | null, RagError>>;
|
|
28
|
+
healthCheck(): Promise<Result<void, RagError>>;
|
|
29
|
+
upsert(text: string, metadata: RagMetadata, options?: CallOptions): Promise<Result<void, RagError>>;
|
|
30
|
+
upsertPrecomputed(text: string, vector: number[], metadata: RagMetadata): Promise<Result<void, RagError>>;
|
|
31
|
+
private upsertKnown;
|
|
32
|
+
writer(): IRagBackendWriter;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=pg-vector-rag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag.d.ts","sourceRoot":"","sources":["../src/pg-vector-rag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,eAAe,EACf,IAAI,EACJ,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,MAAM,EACP,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAA0B,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AASzD,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,MAAM,WAAW,QAAQ;IACvB,KAAK,CACH,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAC1B,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAMD,qBAAa,WAAY,YAAW,IAAI;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAGpC,MAAM,EAAE,iBAAiB,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,EACnD,cAAc,CAAC,EAAE,QAAQ;YAgBb,kBAAkB;IAqB1B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAWrB,iBAAiB;IAIzB,KAAK,CACT,SAAS,EAAE,eAAe,EAC1B,CAAC,EAAE,MAAM,EACT,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,CAAC;IAuBnC,OAAO,CACX,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC;IAyBxC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAa9C,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAW5B,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAIpB,WAAW;IAmBzB,MAAM,IAAI,iBAAiB;CAoC5B"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { FallbackQueryEmbedding, RagError } from '@mcp-abap-adt/llm-agent';
|
|
2
|
+
import { resolvePgConnectArgs } from './connection.js';
|
|
3
|
+
import { assertCollectionName, createExtensionSql, createTableSql, quoteIdent, } from './schema.js';
|
|
4
|
+
function vectorLiteral(vec) {
|
|
5
|
+
return `'[${vec.join(',')}]'::vector`;
|
|
6
|
+
}
|
|
7
|
+
export class PgVectorRag {
|
|
8
|
+
collectionName;
|
|
9
|
+
dimension;
|
|
10
|
+
embedder;
|
|
11
|
+
autoCreateSchema;
|
|
12
|
+
clientPromise;
|
|
13
|
+
schemaReady = false;
|
|
14
|
+
schemaPromise;
|
|
15
|
+
constructor(config, injectedClient) {
|
|
16
|
+
assertCollectionName(config.collectionName);
|
|
17
|
+
this.collectionName = config.collectionName;
|
|
18
|
+
this.dimension = config.dimension ?? 1536;
|
|
19
|
+
this.embedder = config.embedder;
|
|
20
|
+
this.autoCreateSchema = config.autoCreateSchema ?? true;
|
|
21
|
+
// Attach a no-op catch so the eager import never becomes an unhandledRejection.
|
|
22
|
+
// The rejection is re-thrown when clientPromise is actually awaited.
|
|
23
|
+
const driverPromise = injectedClient
|
|
24
|
+
? Promise.resolve(injectedClient)
|
|
25
|
+
: this.createDriverClient(config);
|
|
26
|
+
driverPromise.catch(() => { });
|
|
27
|
+
this.clientPromise = driverPromise;
|
|
28
|
+
}
|
|
29
|
+
async createDriverClient(cfg) {
|
|
30
|
+
const args = resolvePgConnectArgs(cfg);
|
|
31
|
+
const mod = (await import('pg'));
|
|
32
|
+
const PoolCtor = mod.Pool ?? mod.default?.Pool;
|
|
33
|
+
if (!PoolCtor)
|
|
34
|
+
throw new Error('pg module did not expose Pool');
|
|
35
|
+
const pool = new PoolCtor(args);
|
|
36
|
+
return {
|
|
37
|
+
query: (sql, params = []) => pool.query(sql, params),
|
|
38
|
+
end: () => pool.end(),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async ensureSchema() {
|
|
42
|
+
if (this.schemaReady)
|
|
43
|
+
return;
|
|
44
|
+
this.schemaPromise ??= (async () => {
|
|
45
|
+
const client = await this.clientPromise;
|
|
46
|
+
await client.query(createExtensionSql());
|
|
47
|
+
await client.query(createTableSql(this.collectionName, this.dimension));
|
|
48
|
+
this.schemaReady = true;
|
|
49
|
+
})();
|
|
50
|
+
await this.schemaPromise;
|
|
51
|
+
}
|
|
52
|
+
async maybeEnsureSchema() {
|
|
53
|
+
if (this.autoCreateSchema)
|
|
54
|
+
await this.ensureSchema();
|
|
55
|
+
}
|
|
56
|
+
async query(embedding, k, options) {
|
|
57
|
+
if (options?.signal?.aborted)
|
|
58
|
+
return { ok: false, error: new RagError('Aborted', 'ABORTED') };
|
|
59
|
+
try {
|
|
60
|
+
await this.maybeEnsureSchema();
|
|
61
|
+
const safe = new FallbackQueryEmbedding(embedding, this.embedder);
|
|
62
|
+
const vector = await safe.toVector();
|
|
63
|
+
const client = await this.clientPromise;
|
|
64
|
+
const table = quoteIdent(this.collectionName);
|
|
65
|
+
const lit = vectorLiteral(vector);
|
|
66
|
+
const sql = `SELECT id, text, metadata, vector <=> ${lit} AS score FROM ${table} ORDER BY vector <=> ${lit} LIMIT ${Math.max(1, k)}`;
|
|
67
|
+
const { rows } = await client.query(sql);
|
|
68
|
+
const results = rows.map((row) => ({
|
|
69
|
+
text: String(row.text ?? ''),
|
|
70
|
+
metadata: row.metadata ?? {},
|
|
71
|
+
score: 1 - Number(row.score ?? 0),
|
|
72
|
+
}));
|
|
73
|
+
return { ok: true, value: results };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return { ok: false, error: new RagError(String(err), 'QUERY_ERROR') };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async getById(id, options) {
|
|
80
|
+
if (options?.signal?.aborted)
|
|
81
|
+
return { ok: false, error: new RagError('Aborted', 'ABORTED') };
|
|
82
|
+
try {
|
|
83
|
+
await this.maybeEnsureSchema();
|
|
84
|
+
const client = await this.clientPromise;
|
|
85
|
+
const { rows } = await client.query(`SELECT id, text, metadata FROM ${quoteIdent(this.collectionName)} WHERE id = $1`, [id]);
|
|
86
|
+
const row = rows[0];
|
|
87
|
+
if (!row)
|
|
88
|
+
return { ok: true, value: null };
|
|
89
|
+
return {
|
|
90
|
+
ok: true,
|
|
91
|
+
value: {
|
|
92
|
+
text: String(row.text ?? ''),
|
|
93
|
+
metadata: row.metadata ?? {},
|
|
94
|
+
score: 1,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
return { ok: false, error: new RagError(String(err), 'QUERY_ERROR') };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async healthCheck() {
|
|
103
|
+
try {
|
|
104
|
+
const client = await this.clientPromise;
|
|
105
|
+
await client.query('SELECT 1');
|
|
106
|
+
return { ok: true, value: undefined };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: new RagError(String(err), 'HEALTH_CHECK_ERROR'),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async upsert(text, metadata, options) {
|
|
116
|
+
if (options?.signal?.aborted)
|
|
117
|
+
return { ok: false, error: new RagError('Aborted', 'ABORTED') };
|
|
118
|
+
try {
|
|
119
|
+
const { vector } = await this.embedder.embed(text, options);
|
|
120
|
+
return this.upsertKnown(text, vector, metadata);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
return { ok: false, error: new RagError(String(err), 'UPSERT_ERROR') };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async upsertPrecomputed(text, vector, metadata) {
|
|
127
|
+
return this.upsertKnown(text, vector, metadata);
|
|
128
|
+
}
|
|
129
|
+
async upsertKnown(text, vector, metadata) {
|
|
130
|
+
try {
|
|
131
|
+
await this.maybeEnsureSchema();
|
|
132
|
+
const client = await this.clientPromise;
|
|
133
|
+
const id = metadata?.id ?? crypto.randomUUID();
|
|
134
|
+
const { id: _omit, ...rest } = metadata ?? {};
|
|
135
|
+
const table = quoteIdent(this.collectionName);
|
|
136
|
+
const sql = `INSERT INTO ${table} (id, text, vector, metadata) VALUES ($1, $2, ${vectorLiteral(vector)}, $3::jsonb) ON CONFLICT (id) DO UPDATE SET text = EXCLUDED.text, vector = EXCLUDED.vector, metadata = EXCLUDED.metadata`;
|
|
137
|
+
await client.query(sql, [id, text, JSON.stringify(rest)]);
|
|
138
|
+
return { ok: true, value: undefined };
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
return { ok: false, error: new RagError(String(err), 'UPSERT_ERROR') };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
writer() {
|
|
145
|
+
return {
|
|
146
|
+
upsertRaw: async (id, text, metadata, options) => {
|
|
147
|
+
const r = await this.upsert(text, { ...metadata, id }, options);
|
|
148
|
+
return r.ok ? { ok: true, value: undefined } : r;
|
|
149
|
+
},
|
|
150
|
+
deleteByIdRaw: async (id) => {
|
|
151
|
+
try {
|
|
152
|
+
await this.maybeEnsureSchema();
|
|
153
|
+
const client = await this.clientPromise;
|
|
154
|
+
const res = await client.query(`DELETE FROM ${quoteIdent(this.collectionName)} WHERE id = $1`, [id]);
|
|
155
|
+
return { ok: true, value: res.rowCount > 0 };
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
return {
|
|
159
|
+
ok: false,
|
|
160
|
+
error: new RagError(String(err), 'DELETE_ERROR'),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
clearAll: async () => {
|
|
165
|
+
try {
|
|
166
|
+
await this.maybeEnsureSchema();
|
|
167
|
+
const client = await this.clientPromise;
|
|
168
|
+
await client.query(`TRUNCATE ${quoteIdent(this.collectionName)}`);
|
|
169
|
+
return { ok: true, value: undefined };
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
return { ok: false, error: new RagError(String(err), 'CLEAR_ERROR') };
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
upsertPrecomputedRaw: async (id, text, vector, metadata) => this.upsertPrecomputed(text, vector, { ...metadata, id }),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=pg-vector-rag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-rag.js","sourceRoot":"","sources":["../src/pg-vector-rag.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function assertCollectionName(name: string): void;
|
|
2
|
+
export declare function quoteIdent(ident: string): string;
|
|
3
|
+
export declare function createExtensionSql(): string;
|
|
4
|
+
export declare function createTableSql(collection: string, dimension: number): string;
|
|
5
|
+
export declare function dropTableSql(collection: string): string;
|
|
6
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAS5E;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RagError } from '@mcp-abap-adt/llm-agent';
|
|
2
|
+
const COLLECTION_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;
|
|
3
|
+
export function assertCollectionName(name) {
|
|
4
|
+
if (!COLLECTION_NAME_RE.test(name)) {
|
|
5
|
+
throw new RagError(`Invalid collection name: ${name}`, 'INVALID_COLLECTION_NAME');
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function quoteIdent(ident) {
|
|
9
|
+
assertCollectionName(ident);
|
|
10
|
+
return `"${ident}"`;
|
|
11
|
+
}
|
|
12
|
+
export function createExtensionSql() {
|
|
13
|
+
return 'CREATE EXTENSION IF NOT EXISTS vector';
|
|
14
|
+
}
|
|
15
|
+
export function createTableSql(collection, dimension) {
|
|
16
|
+
const table = quoteIdent(collection);
|
|
17
|
+
return `CREATE TABLE IF NOT EXISTS ${table} (
|
|
18
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
19
|
+
text TEXT,
|
|
20
|
+
vector vector(${dimension}),
|
|
21
|
+
metadata JSONB,
|
|
22
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
23
|
+
)`;
|
|
24
|
+
}
|
|
25
|
+
export function dropTableSql(collection) {
|
|
26
|
+
return `DROP TABLE IF EXISTS ${quoteIdent(collection)}`;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,kBAAkB,GAAG,+BAA+B,CAAC;AAE3D,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,QAAQ,CAChB,4BAA4B,IAAI,EAAE,EAClC,yBAAyB,CAC1B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,IAAI,KAAK,GAAG,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,uCAAuC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,SAAiB;IAClE,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO,8BAA8B,KAAK;;;oBAGxB,SAAS;;;IAGzB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,OAAO,wBAAwB,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;AAC1D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcp-abap-adt/pg-vector-rag",
|
|
3
|
+
"version": "11.0.0",
|
|
4
|
+
"description": "PgVectorRag (PostgreSQL + pgvector) and PgVectorRagProvider for @mcp-abap-adt/llm-agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.json",
|
|
22
|
+
"clean": "tsc -p tsconfig.json --clean",
|
|
23
|
+
"test": "node --import tsx/esm --test --test-reporter=spec 'src/**/*.test.ts'"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@mcp-abap-adt/llm-agent": "*",
|
|
27
|
+
"pg": "^8.13.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/pg": "^8.11.0"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/fr0ster/llm-agent.git"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|