@chatcops/store-postgres 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +113 -2
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +8 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -0
- package/dist/conversations.d.ts +38 -0
- package/dist/conversations.d.ts.map +1 -0
- package/dist/conversations.js +230 -0
- package/dist/conversations.js.map +1 -0
- package/dist/counters.d.ts +37 -0
- package/dist/counters.d.ts.map +1 -0
- package/dist/counters.js +98 -0
- package/dist/counters.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/queryable.d.ts +26 -0
- package/dist/queryable.d.ts.map +1 -0
- package/dist/queryable.js +25 -0
- package/dist/queryable.js.map +1 -0
- package/dist/row-hook.d.ts +26 -0
- package/dist/row-hook.d.ts.map +1 -0
- package/dist/row-hook.js +38 -0
- package/dist/row-hook.js.map +1 -0
- package/dist/schema.d.ts +44 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +126 -0
- package/dist/schema.js.map +1 -0
- package/dist/sql.d.ts +9 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +9 -0
- package/dist/sql.js.map +1 -0
- package/dist/vectors.d.ts +15 -0
- package/dist/vectors.d.ts.map +1 -0
- package/dist/vectors.js +147 -0
- package/dist/vectors.js.map +1 -0
- package/package.json +64 -3
package/dist/vectors.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { segmentWords } from '@chatcops/core';
|
|
2
|
+
/** Postgres pgvector-backed storage for embedded page chunks. */
|
|
3
|
+
export class PostgresVectorStore {
|
|
4
|
+
dimensions;
|
|
5
|
+
db;
|
|
6
|
+
table;
|
|
7
|
+
constructor(dimensions, db, table) {
|
|
8
|
+
this.dimensions = dimensions;
|
|
9
|
+
this.db = db;
|
|
10
|
+
this.table = table;
|
|
11
|
+
if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 16_000) {
|
|
12
|
+
throw new Error(`dimensions must be a whole number from 1 to 16000; got ${dimensions}.`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async upsert(records) {
|
|
16
|
+
for (const record of records)
|
|
17
|
+
this.checkVector(record.vector, `record ${record.id}`);
|
|
18
|
+
for (const record of records) {
|
|
19
|
+
const words = segmentWords(record.text).join(' ');
|
|
20
|
+
await this.db.query(`INSERT INTO ${this.table} (id, source_id, source, text, metadata, embedding, keyword_vector)
|
|
21
|
+
VALUES ($1, $2, $3::text::jsonb, $4, $5::text::jsonb, $6::text::vector, to_tsvector('simple', $7))
|
|
22
|
+
ON CONFLICT (id) DO UPDATE SET source_id = EXCLUDED.source_id, source = EXCLUDED.source,
|
|
23
|
+
text = EXCLUDED.text, metadata = EXCLUDED.metadata, embedding = EXCLUDED.embedding,
|
|
24
|
+
keyword_vector = EXCLUDED.keyword_vector`, [record.id, record.source.id, JSON.stringify(record.source), record.text, JSON.stringify(record.metadata ?? {}), toVector(record.vector), words]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async query({ vector, topK, filter }) {
|
|
28
|
+
this.checkVector(vector, 'the query');
|
|
29
|
+
const limit = limitFor(topK);
|
|
30
|
+
if (!limit)
|
|
31
|
+
return [];
|
|
32
|
+
const params = [toVector(vector)];
|
|
33
|
+
const where = metadataWhere(filter, params);
|
|
34
|
+
params.push(limit);
|
|
35
|
+
const sql = `WITH nearest AS MATERIALIZED (
|
|
36
|
+
SELECT id, text, source, metadata, embedding <=> $1::text::vector AS distance
|
|
37
|
+
FROM ${this.table} ${where}
|
|
38
|
+
ORDER BY embedding <=> $1::text::vector
|
|
39
|
+
LIMIT $${params.length}
|
|
40
|
+
)
|
|
41
|
+
SELECT id, text, source, metadata, coalesce(1 - distance, 0)::float8 AS score
|
|
42
|
+
FROM nearest ORDER BY distance + 0, id`;
|
|
43
|
+
const hasFilter = Object.keys(filter ?? {}).length > 0;
|
|
44
|
+
const result = hasFilter
|
|
45
|
+
? await inTransaction(this.db, async (tx) => {
|
|
46
|
+
await tx.query("SET LOCAL hnsw.iterative_scan = 'relaxed_order'");
|
|
47
|
+
return tx.query(sql, params);
|
|
48
|
+
})
|
|
49
|
+
: await this.db.query(sql, params);
|
|
50
|
+
return result.rows.map(asScoredRecord);
|
|
51
|
+
}
|
|
52
|
+
async keywordQuery({ text, topK, filter }) {
|
|
53
|
+
const limit = limitFor(topK);
|
|
54
|
+
const words = segmentWords(text).join(' ');
|
|
55
|
+
if (!limit || !words)
|
|
56
|
+
return [];
|
|
57
|
+
const params = [words];
|
|
58
|
+
const where = metadataWhere(filter, params);
|
|
59
|
+
params.push(limit);
|
|
60
|
+
const { rows } = await this.db.query(
|
|
61
|
+
// Any of the words, not all of them (plainto_tsquery would AND them):
|
|
62
|
+
// a question has more words than any one page. Each lexeme is quoted,
|
|
63
|
+
// so nothing in the text is read as tsquery syntax.
|
|
64
|
+
`WITH search AS (
|
|
65
|
+
SELECT to_tsquery('simple', string_agg(quote_literal(lexeme), ' | ')) AS query
|
|
66
|
+
FROM unnest(tsvector_to_array(to_tsvector('simple', $1::text))) AS lexeme
|
|
67
|
+
)
|
|
68
|
+
SELECT id, text, source, metadata, ts_rank(keyword_vector, search.query)::float8 AS score
|
|
69
|
+
FROM ${this.table}, search
|
|
70
|
+
WHERE keyword_vector @@ search.query${where ? ` AND ${where.slice('WHERE '.length)}` : ''}
|
|
71
|
+
ORDER BY score DESC, id LIMIT $${params.length}`, params);
|
|
72
|
+
return rows.map(asScoredRecord);
|
|
73
|
+
}
|
|
74
|
+
async deleteBySource(sourceId) {
|
|
75
|
+
await this.db.query(`DELETE FROM ${this.table} WHERE source_id = $1`, [sourceId]);
|
|
76
|
+
}
|
|
77
|
+
checkVector(vector, what) {
|
|
78
|
+
if (vector.length !== this.dimensions) {
|
|
79
|
+
throw new Error(`The vector for ${what} has ${vector.length} dimensions, but this store holds ${this.dimensions}.`);
|
|
80
|
+
}
|
|
81
|
+
if (!vector.every(Number.isFinite))
|
|
82
|
+
throw new Error(`The vector for ${what} has a value that isn't a finite number.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function toVector(vector) {
|
|
86
|
+
return `[${Array.from(vector).join(',')}]`;
|
|
87
|
+
}
|
|
88
|
+
function limitFor(topK) {
|
|
89
|
+
return Number.isFinite(topK) && topK >= 1 ? Math.floor(topK) : 0;
|
|
90
|
+
}
|
|
91
|
+
function metadataWhere(filter, params) {
|
|
92
|
+
if (!filter)
|
|
93
|
+
return '';
|
|
94
|
+
const clauses = [];
|
|
95
|
+
for (const [key, value] of Object.entries(filter)) {
|
|
96
|
+
params.push(key);
|
|
97
|
+
const keyParam = `$${params.length}`;
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
params.push(JSON.stringify(value));
|
|
100
|
+
clauses.push(`EXISTS (SELECT 1 FROM jsonb_array_elements($${params.length}::text::jsonb) AS wanted(value) WHERE metadata -> ${keyParam}::text = wanted.value)`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
params.push(JSON.stringify(value));
|
|
104
|
+
clauses.push(`metadata -> ${keyParam}::text = $${params.length}::text::jsonb`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return clauses.length ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
108
|
+
}
|
|
109
|
+
function asScoredRecord(row) {
|
|
110
|
+
return {
|
|
111
|
+
id: row.id,
|
|
112
|
+
text: row.text,
|
|
113
|
+
source: row.source,
|
|
114
|
+
...(row.metadata && Object.keys(row.metadata).length ? { metadata: row.metadata } : {}),
|
|
115
|
+
score: Number(row.score),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function inTransaction(db, run) {
|
|
119
|
+
if (db.transaction)
|
|
120
|
+
return db.transaction(run);
|
|
121
|
+
const pool = db;
|
|
122
|
+
const fromPool = typeof pool.connect === 'function';
|
|
123
|
+
const client = fromPool ? await pool.connect() : db;
|
|
124
|
+
if (!fromPool && !client.connection) {
|
|
125
|
+
throw new Error('Filtered pgvector queries need a transaction-capable database connection for HNSW iterative scans.');
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
await client.query('BEGIN');
|
|
129
|
+
const result = await run(client);
|
|
130
|
+
await client.query('COMMIT');
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
try {
|
|
135
|
+
await client.query('ROLLBACK');
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Keep the query error if the connection has already been lost.
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
if (fromPool)
|
|
144
|
+
client.release?.();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=vectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectors.js","sourceRoot":"","sources":["../src/vectors.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatcops/store-postgres",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Postgres storage for ChatCops: conversations, counters, keys and analytics events",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"chatcops",
|
|
7
|
+
"chatbot",
|
|
8
|
+
"postgres",
|
|
9
|
+
"neon",
|
|
10
|
+
"storage"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://chat.codercops.com",
|
|
13
|
+
"bugs": "https://github.com/codercops/chatcops/issues",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"chatcops-postgres": "./dist/bin.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"pg": "^8.13.0",
|
|
31
|
+
"@chatcops/core": "^0.6.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"pg": {
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^22",
|
|
40
|
+
"@types/pg": "^8.11.10",
|
|
41
|
+
"pg": "^8.13.1",
|
|
42
|
+
"postgres": "^3.4.5",
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"vitest": "^4.1.11",
|
|
45
|
+
"@chatcops/core": "0.6.0"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/codercops/chatcops.git",
|
|
50
|
+
"directory": "packages/store-postgres"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=22"
|
|
58
|
+
},
|
|
59
|
+
"sideEffects": false,
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsc",
|
|
62
|
+
"typecheck": "tsc --noEmit",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:watch": "vitest",
|
|
65
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
66
|
+
}
|
|
6
67
|
}
|