@mcp-abap-adt/qdrant-rag 30.2.0 → 30.3.1
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 +12 -0
- package/dist/__tests__/catalog-update.test.d.ts +2 -0
- package/dist/__tests__/catalog-update.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-update.test.js +145 -0
- package/dist/__tests__/catalog-update.test.js.map +1 -0
- package/dist/__tests__/qdrant-stub.d.ts +4 -0
- package/dist/__tests__/qdrant-stub.d.ts.map +1 -1
- package/dist/__tests__/qdrant-stub.js +37 -4
- package/dist/__tests__/qdrant-stub.js.map +1 -1
- package/dist/__tests__/scan-delete.test.d.ts +2 -0
- package/dist/__tests__/scan-delete.test.d.ts.map +1 -0
- package/dist/__tests__/scan-delete.test.js +294 -0
- package/dist/__tests__/scan-delete.test.js.map +1 -0
- package/dist/payload-record.d.ts +10 -0
- package/dist/payload-record.d.ts.map +1 -0
- package/dist/payload-record.js +9 -0
- package/dist/payload-record.js.map +1 -0
- package/dist/qdrant-rag-provider.d.ts +15 -2
- package/dist/qdrant-rag-provider.d.ts.map +1 -1
- package/dist/qdrant-rag-provider.js +58 -1
- package/dist/qdrant-rag-provider.js.map +1 -1
- package/dist/qdrant-rag.d.ts +12 -2
- package/dist/qdrant-rag.d.ts.map +1 -1
- package/dist/qdrant-rag.js +50 -14
- package/dist/qdrant-rag.js.map +1 -1
- package/dist/scan-delete.d.ts +23 -0
- package/dist/scan-delete.d.ts.map +1 -0
- package/dist/scan-delete.js +143 -0
- package/dist/scan-delete.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,6 +29,18 @@ the collection; `describeCollections` reads the catalog back.
|
|
|
29
29
|
A collection created before this release has a collection and no record: take it over once with
|
|
30
30
|
`createCollection(..., { adoptExisting: true })`.
|
|
31
31
|
|
|
32
|
+
## Scan, filtered delete and catalog update
|
|
33
|
+
|
|
34
|
+
The store implements `IRagScanner` and `IRagFilteredDeleter`, and the provider implements `IRagCatalogUpdater` (guards `isRagScanner`, `isRagFilteredDeleter`, `isRagCatalogUpdater` from `@mcp-abap-adt/llm-agent`). The library wrappers (`OverlayRag`, `SessionScopedRag`, ...) do not forward them; use the provider's handle.
|
|
35
|
+
|
|
36
|
+
- `scan({ filter?, pageSize?, cursor? })` returns `{ records, cursor? }`: `id`, `text`, `metadata`, never a vector, expired records included. `filter` is strict string equality on `userId`, `sessionId`, `namespace`. `pageSize` is a positive integer (default `DEFAULT_SCAN_PAGE_SIZE`, 500), otherwise `INVALID_ARGUMENT`; a filter value that is not a string and a malformed cursor are `INVALID_ARGUMENT` too. **Only a missing `cursor` ends the scan**: a page may be short or empty while a cursor is still returned. `id` is `metadata.id` when the record has one, otherwise the Qdrant point id; the round trip into `getById` / `deleteById` is guaranteed only for records written with an id.
|
|
37
|
+
- `deleteWhere(filter)` deletes the matching records of this collection only and returns `{ deleted }`. An empty filter is `INVALID_ARGUMENT`. It is exact against a snapshot, not atomic: it scrolls the matching point ids with a payload filter, then deletes them with `wait=true` in batches and returns how many it deleted: Qdrant's delete reports no count, so before each batch it retrieves the batch ids, deletes exactly those still present and counts them: the count is exact except when another caller deletes the same ids in the window between that retrieve and the delete (Qdrant has no server-side count). The server-side `match` is only a prefilter: Qdrant's `match.value` also matches an element of an array payload value, so every scrolled point is re-checked with the strict string-equality matcher, and a point whose `userId`/`sessionId`/`namespace` is an array is neither scanned nor deleted. The scan cursor is Qdrant's point offset (unsigned integer or UUID); anything else is `INVALID_ARGUMENT`. A matching record inserted while it runs may survive; repeat the call if you need to.
|
|
38
|
+
- An aborted `signal` gives `ABORTED` (`Aborted after deleting N record(s)` once a delete has started).
|
|
39
|
+
- `updateCollection(storeName, { collectionName?, attributes? })` rewrites the catalog point's payload (the record is read first). `attributes` replaces the stored attributes as a whole; `storeName`, `scope` and the owner never change. A missing record is `RAG_COLLECTION_NOT_FOUND`, an empty patch or a `collectionName` that is not a non-empty string `INVALID_ARGUMENT`, an attribute value that cannot be stored `RAG_INVALID_ATTRIBUTES`.
|
|
40
|
+
|
|
41
|
+
`scan` uses `POST /collections/{c}/points/scroll` with the payload filter; the cursor is the scroll offset. A 404 on the catalog write is `RAG_COLLECTION_NOT_FOUND` too. Note: `match.value` also matches an element of an array payload (`userId: ['u1']` matches the filter `userId: 'u1'`), which the SQL and in-process stores do not; identity fields are strings by convention.
|
|
42
|
+
See [INTEGRATION.md](../../docs/INTEGRATION.md#scan-filtered-delete-and-catalog-update).
|
|
43
|
+
|
|
32
44
|
## License
|
|
33
45
|
|
|
34
46
|
**GNU Lesser General Public License v3.0 only** (`LGPL-3.0-only`) — see
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-update.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/catalog-update.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { after, before, describe, it } from 'node:test';
|
|
3
|
+
import { INVALID_ARGUMENT, RAG_COLLECTION_NOT_FOUND, symmetricEmbedder, } from '@mcp-abap-adt/llm-agent';
|
|
4
|
+
import { conformanceEmbedder } from '@mcp-abap-adt/llm-agent/testing/scan-delete-conformance';
|
|
5
|
+
import { deterministicUUID } from '../qdrant-rag.js';
|
|
6
|
+
import { QdrantRagProvider } from '../qdrant-rag-provider.js';
|
|
7
|
+
import { startQdrantStub } from './qdrant-stub.js';
|
|
8
|
+
const CATALOG = 'rag_collection_catalog';
|
|
9
|
+
const embedder = symmetricEmbedder(conformanceEmbedder());
|
|
10
|
+
let stub;
|
|
11
|
+
before(async () => {
|
|
12
|
+
stub = await startQdrantStub();
|
|
13
|
+
});
|
|
14
|
+
after(async () => {
|
|
15
|
+
await stub.close();
|
|
16
|
+
});
|
|
17
|
+
const provider = () => new QdrantRagProvider({ name: 'qdrant', url: stub.baseUrl, embedder });
|
|
18
|
+
const payloadOf = async (store) => stub.collections.get(CATALOG)?.points.get(await deterministicUUID(store))
|
|
19
|
+
?.payload;
|
|
20
|
+
const cyclic = {};
|
|
21
|
+
cyclic.self = cyclic;
|
|
22
|
+
const INVALID_ATTRIBUTES = [
|
|
23
|
+
{ x: Number.NaN },
|
|
24
|
+
{ x: undefined },
|
|
25
|
+
{ x: new Date() },
|
|
26
|
+
{ x: 10n },
|
|
27
|
+
cyclic,
|
|
28
|
+
];
|
|
29
|
+
describe('QdrantRagProvider.updateCollection', () => {
|
|
30
|
+
it('an empty patch is INVALID_ARGUMENT before any request', async () => {
|
|
31
|
+
const before = stub.requests.length;
|
|
32
|
+
for (const patch of [
|
|
33
|
+
{},
|
|
34
|
+
{ collectionName: undefined, attributes: undefined },
|
|
35
|
+
]) {
|
|
36
|
+
const r = await provider().updateCollection('a', patch);
|
|
37
|
+
assert.ok(!r.ok);
|
|
38
|
+
assert.equal(r.error.code, INVALID_ARGUMENT);
|
|
39
|
+
}
|
|
40
|
+
assert.equal(stub.requests.length, before);
|
|
41
|
+
});
|
|
42
|
+
it('attributes that have no JSON form are RAG_INVALID_ATTRIBUTES with no request', async () => {
|
|
43
|
+
const mark = stub.requests.length;
|
|
44
|
+
for (const attributes of INVALID_ATTRIBUTES) {
|
|
45
|
+
const r = await provider().updateCollection('a', {
|
|
46
|
+
attributes: attributes,
|
|
47
|
+
});
|
|
48
|
+
assert.ok(!r.ok);
|
|
49
|
+
assert.equal(r.error.code, 'RAG_INVALID_ATTRIBUTES');
|
|
50
|
+
}
|
|
51
|
+
assert.equal(stub.requests.length, mark);
|
|
52
|
+
});
|
|
53
|
+
it('sets only the given keys on the catalog point, with wait=true semantics', async () => {
|
|
54
|
+
const p = provider();
|
|
55
|
+
const made = await p.createCollection('upd_a', {
|
|
56
|
+
scope: 'user',
|
|
57
|
+
userId: 'u1',
|
|
58
|
+
attributes: { a: 1 },
|
|
59
|
+
});
|
|
60
|
+
assert.ok(made.ok);
|
|
61
|
+
const before = await payloadOf('upd_a');
|
|
62
|
+
const mark = stub.requests.length;
|
|
63
|
+
const r = await p.updateCollection('upd_a', { attributes: { b: 2 } });
|
|
64
|
+
assert.ok(r.ok);
|
|
65
|
+
const after = await payloadOf('upd_a');
|
|
66
|
+
assert.equal(after?.attributes_json, JSON.stringify({ b: 2 }));
|
|
67
|
+
assert.equal(after?.collection_name, before?.collection_name);
|
|
68
|
+
assert.equal(after?.scope, 'user');
|
|
69
|
+
assert.equal(after?.user_id, 'u1');
|
|
70
|
+
assert.equal(after?.store_name, 'upd_a');
|
|
71
|
+
const sent = stub.requests
|
|
72
|
+
.slice(mark)
|
|
73
|
+
.find((q) => q.path.endsWith('/points/payload'));
|
|
74
|
+
assert.ok(sent);
|
|
75
|
+
assert.deepEqual(Object.keys(sent.body.payload), [
|
|
76
|
+
'attributes_json',
|
|
77
|
+
]);
|
|
78
|
+
});
|
|
79
|
+
it('an absent record is RAG_COLLECTION_NOT_FOUND, no write is sent and no point is created', async () => {
|
|
80
|
+
const p = provider();
|
|
81
|
+
const made = await p.createCollection('upd_present', { scope: 'global' });
|
|
82
|
+
assert.ok(made.ok);
|
|
83
|
+
const mark = stub.requests.length;
|
|
84
|
+
const points = stub.collections.get(CATALOG)?.points.size;
|
|
85
|
+
const r = await p.updateCollection('upd_absent', { collectionName: 'x' });
|
|
86
|
+
assert.ok(!r.ok);
|
|
87
|
+
assert.equal(r.error.code, RAG_COLLECTION_NOT_FOUND);
|
|
88
|
+
assert.ok(stub.requests.slice(mark).every((q) => !q.path.endsWith('/payload')));
|
|
89
|
+
assert.equal(stub.collections.get(CATALOG)?.points.size, points);
|
|
90
|
+
});
|
|
91
|
+
it('a catalog collection that does not exist is RAG_COLLECTION_NOT_FOUND and is not created', async () => {
|
|
92
|
+
const fresh = await startQdrantStub();
|
|
93
|
+
try {
|
|
94
|
+
const r = await new QdrantRagProvider({
|
|
95
|
+
name: 'qdrant',
|
|
96
|
+
url: fresh.baseUrl,
|
|
97
|
+
embedder,
|
|
98
|
+
}).updateCollection('a', { collectionName: 'x' });
|
|
99
|
+
assert.ok(!r.ok);
|
|
100
|
+
assert.equal(r.error.code, RAG_COLLECTION_NOT_FOUND);
|
|
101
|
+
assert.equal(fresh.collections.size, 0);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await fresh.close();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
it('a record deleted between the read and the write is RAG_COLLECTION_NOT_FOUND, nothing is created', async () => {
|
|
108
|
+
const p = provider();
|
|
109
|
+
const made = await p.createCollection('upd_race', { scope: 'global' });
|
|
110
|
+
assert.ok(made.ok);
|
|
111
|
+
const id = await deterministicUUID('upd_race');
|
|
112
|
+
stub.beforePayloadWrite = () => {
|
|
113
|
+
stub.collections.get(CATALOG)?.points.delete(id);
|
|
114
|
+
};
|
|
115
|
+
try {
|
|
116
|
+
const mark = stub.requests.length;
|
|
117
|
+
const r = await p.updateCollection('upd_race', { collectionName: 'x' });
|
|
118
|
+
// The write was sent and the engine answered 404 (no such point).
|
|
119
|
+
assert.ok(stub.requests
|
|
120
|
+
.slice(mark)
|
|
121
|
+
.some((q) => q.path.endsWith('/points/payload')));
|
|
122
|
+
assert.ok(!r.ok);
|
|
123
|
+
assert.equal(r.error.code, RAG_COLLECTION_NOT_FOUND);
|
|
124
|
+
assert.equal(stub.collections.get(CATALOG)?.points.has(id), false);
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
stub.beforePayloadWrite = undefined;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
it('a refused set-payload is RAG_UPDATE_ERROR', async () => {
|
|
131
|
+
const p = provider();
|
|
132
|
+
const made = await p.createCollection('upd_fail', { scope: 'global' });
|
|
133
|
+
assert.ok(made.ok);
|
|
134
|
+
stub.failOn = (r) => r.path.endsWith('/points/payload');
|
|
135
|
+
try {
|
|
136
|
+
const r = await p.updateCollection('upd_fail', { collectionName: 'x' });
|
|
137
|
+
assert.ok(!r.ok);
|
|
138
|
+
assert.equal(r.error.code, 'RAG_UPDATE_ERROR');
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
stub.failOn = undefined;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=catalog-update.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-update.test.js","sourceRoot":"","sources":["../../src/__tests__/catalog-update.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,10 @@ export type QdrantStub = {
|
|
|
21
21
|
failOn?: (r: StubRequest) => boolean;
|
|
22
22
|
/** Runs inside a points PUT to the catalog, before it is applied — a racing writer. */
|
|
23
23
|
beforeCatalogWrite?: () => void;
|
|
24
|
+
/** Runs inside a set-payload request before it is applied — a racing delete. */
|
|
25
|
+
beforePayloadWrite?: () => void;
|
|
26
|
+
/** Runs inside a points retrieve before it is answered — a racing delete. */
|
|
27
|
+
beforePointsRetrieve?: () => void;
|
|
24
28
|
close(): Promise<void>;
|
|
25
29
|
};
|
|
26
30
|
export declare function startQdrantStub(catalog?: string): Promise<QdrantStub>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qdrant-stub.d.ts","sourceRoot":"","sources":["../../src/__tests__/qdrant-stub.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AACF,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAAE,CAAC;AAE9E;8EAC8E;AAC9E,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC;IACrC,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,eAAe,CACnC,OAAO,SAA2B,GACjC,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"qdrant-stub.d.ts","sourceRoot":"","sources":["../../src/__tests__/qdrant-stub.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AACF,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAAE,CAAC;AAE9E;8EAC8E;AAC9E,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC;IACrC,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,gFAAgF;IAChF,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,eAAe,CACnC,OAAO,SAA2B,GACjC,OAAO,CAAC,UAAU,CAAC,CA4MrB;AAUD,KAAK,eAAe,GAChB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAC1C;IAAE,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC7B;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,GACD,YAAY,CAAC;AAEjB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B,CAAC;AAiCF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,YAAY,GACnB,OAAO,CAUT"}
|
|
@@ -51,7 +51,7 @@ export async function startQdrantStub(catalog = 'rag_collection_catalog') {
|
|
|
51
51
|
});
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
const pts = r.path.match(/^\/collections\/([^/]+)\/points(\/scroll|\/delete|\/search)?$/);
|
|
54
|
+
const pts = r.path.match(/^\/collections\/([^/]+)\/points(\/scroll|\/delete|\/search|\/payload)?$/);
|
|
55
55
|
if (pts) {
|
|
56
56
|
const name = pts[1];
|
|
57
57
|
const action = pts[2];
|
|
@@ -73,6 +73,7 @@ export async function startQdrantStub(catalog = 'rag_collection_catalog') {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
if (r.method === 'POST' && action === undefined) {
|
|
76
|
+
stub?.beforePointsRetrieve?.();
|
|
76
77
|
const ids = body.ids;
|
|
77
78
|
reply(200, {
|
|
78
79
|
result: ids.flatMap((id) => {
|
|
@@ -83,8 +84,17 @@ export async function startQdrantStub(catalog = 'rag_collection_catalog') {
|
|
|
83
84
|
return;
|
|
84
85
|
}
|
|
85
86
|
if (r.method === 'POST' && action === '/scroll') {
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
// Qdrant scrolls in point-id order; the offset is the first id to
|
|
88
|
+
// return (inclusive), the filter is applied inside the scroll.
|
|
89
|
+
const filter = body.filter;
|
|
90
|
+
const ids = [...c.points.keys()]
|
|
91
|
+
.sort()
|
|
92
|
+
.filter((id) => filter === undefined ||
|
|
93
|
+
matchesFilter(c.points.get(id)?.payload ?? {}, filter));
|
|
94
|
+
const first = body.offset === undefined
|
|
95
|
+
? 0
|
|
96
|
+
: ids.findIndex((id) => id >= String(body.offset));
|
|
97
|
+
const start = first === -1 ? ids.length : first;
|
|
88
98
|
const limit = Number(body.limit ?? 10);
|
|
89
99
|
reply(200, {
|
|
90
100
|
result: {
|
|
@@ -96,6 +106,25 @@ export async function startQdrantStub(catalog = 'rag_collection_catalog') {
|
|
|
96
106
|
});
|
|
97
107
|
return;
|
|
98
108
|
}
|
|
109
|
+
if (r.method === 'POST' && action === '/payload') {
|
|
110
|
+
// Set payload by point id: keys are merged into an existing point; an
|
|
111
|
+
// id that is not there is a 404 and nothing is created (Qdrant's
|
|
112
|
+
// behaviour: "No point with id ... found").
|
|
113
|
+
stub?.beforePayloadWrite?.();
|
|
114
|
+
const set = (body.payload ?? {});
|
|
115
|
+
const ids = body.points ?? [];
|
|
116
|
+
const absent = ids.find((id) => !c.points.has(id));
|
|
117
|
+
if (absent !== undefined) {
|
|
118
|
+
reply(404, {
|
|
119
|
+
status: { error: `Not found: No point with id ${absent} found` },
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
for (const id of ids)
|
|
124
|
+
Object.assign(c.points.get(id)?.payload ?? {}, set);
|
|
125
|
+
reply(200, { result: { status: 'completed' } });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
99
128
|
if (r.method === 'POST' && action === '/delete') {
|
|
100
129
|
for (const id of body.points ?? [])
|
|
101
130
|
c.points.delete(id);
|
|
@@ -167,7 +196,11 @@ function holds(payload, cond) {
|
|
|
167
196
|
return (v === undefined || v === null || (Array.isArray(v) && v.length === 0));
|
|
168
197
|
}
|
|
169
198
|
if ('match' in cond) {
|
|
170
|
-
|
|
199
|
+
// Qdrant's match.value also matches an element of an array payload value.
|
|
200
|
+
const v = payload[cond.key];
|
|
201
|
+
return Array.isArray(v)
|
|
202
|
+
? v.includes(cond.match.value)
|
|
203
|
+
: cond.key in payload && v === cond.match.value;
|
|
171
204
|
}
|
|
172
205
|
if ('range' in cond) {
|
|
173
206
|
const v = payload[cond.key];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qdrant-stub.js","sourceRoot":"","sources":["../../src/__tests__/qdrant-stub.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"qdrant-stub.js","sourceRoot":"","sources":["../../src/__tests__/qdrant-stub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-delete.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scan-delete.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { after, before, describe, it } from 'node:test';
|
|
3
|
+
import { INVALID_ARGUMENT, RagError, symmetricEmbedder, } from '@mcp-abap-adt/llm-agent';
|
|
4
|
+
import { CONFORMANCE_EMBEDDING_DIM, conformanceEmbedder, isScanDeleteCaseSkipped, scanDeleteConformanceCases, } from '@mcp-abap-adt/llm-agent/testing/scan-delete-conformance';
|
|
5
|
+
import { QdrantRag } from '../qdrant-rag.js';
|
|
6
|
+
import { QdrantRagProvider } from '../qdrant-rag-provider.js';
|
|
7
|
+
import { scrollFilter } from '../scan-delete.js';
|
|
8
|
+
import { startQdrantStub } from './qdrant-stub.js';
|
|
9
|
+
const embedder = symmetricEmbedder(conformanceEmbedder());
|
|
10
|
+
let stub;
|
|
11
|
+
before(async () => {
|
|
12
|
+
stub = await startQdrantStub();
|
|
13
|
+
});
|
|
14
|
+
after(async () => {
|
|
15
|
+
await stub.close();
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Creates a collection the way test/integration/qdrant-scan/run.mjs does on a
|
|
19
|
+
* live Qdrant: `PUT /collections/{name}` with the vector size and the
|
|
20
|
+
* distance `QdrantRag` creates its collections with. `QdrantRag.scan` never
|
|
21
|
+
* creates one, so a kit subject must exist before its first scan.
|
|
22
|
+
*/
|
|
23
|
+
async function createCollection(baseUrl, name) {
|
|
24
|
+
const res = await fetch(`${baseUrl}/collections/${name}`, {
|
|
25
|
+
method: 'PUT',
|
|
26
|
+
headers: { 'Content-Type': 'application/json' },
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
vectors: { size: CONFORMANCE_EMBEDDING_DIM, distance: 'Cosine' },
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok)
|
|
32
|
+
throw new Error(`create ${name}: HTTP ${res.status}`);
|
|
33
|
+
}
|
|
34
|
+
let n = 0;
|
|
35
|
+
/** A store over a fresh, existing, empty collection of the shared stub. */
|
|
36
|
+
async function open() {
|
|
37
|
+
const collectionName = `scan_${n++}`;
|
|
38
|
+
await createCollection(stub.baseUrl, collectionName);
|
|
39
|
+
return new QdrantRag({ url: stub.baseUrl, collectionName, embedder });
|
|
40
|
+
}
|
|
41
|
+
// The shared kit over QdrantRag and a storing stub of the REST API; a second
|
|
42
|
+
// QdrantRag on another collection of the same stub is the `sibling`; a
|
|
43
|
+
// QdrantRagProvider over the same stub is the `catalog`.
|
|
44
|
+
describe('QdrantRag — scan/delete conformance (stub)', () => {
|
|
45
|
+
for (const c of scanDeleteConformanceCases) {
|
|
46
|
+
it(c.name, async (t) => {
|
|
47
|
+
try {
|
|
48
|
+
await c.run(async () => ({
|
|
49
|
+
store: async () => (await open()),
|
|
50
|
+
sibling: async () => (await open()),
|
|
51
|
+
catalog: async () => {
|
|
52
|
+
const provider = new QdrantRagProvider({
|
|
53
|
+
name: 'qdrant',
|
|
54
|
+
url: stub.baseUrl,
|
|
55
|
+
embedder,
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
provider,
|
|
59
|
+
async create(name) {
|
|
60
|
+
// The store the record names must exist, as the provider
|
|
61
|
+
// would have created it; the record itself goes through
|
|
62
|
+
// createCollection.
|
|
63
|
+
const r = await provider.createCollection(name, {
|
|
64
|
+
scope: 'user',
|
|
65
|
+
userId: 'u1',
|
|
66
|
+
attributes: { seeded: true },
|
|
67
|
+
});
|
|
68
|
+
if (!r.ok)
|
|
69
|
+
throw r.error;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
if (!isScanDeleteCaseSkipped(err))
|
|
77
|
+
throw err;
|
|
78
|
+
t.skip(err.message);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
describe('QdrantRag — scan/delete requests', () => {
|
|
84
|
+
it('scrollFilter matches the written payload keys by string value, no ttl', () => {
|
|
85
|
+
assert.equal(scrollFilter(undefined), undefined);
|
|
86
|
+
assert.equal(scrollFilter({}), undefined);
|
|
87
|
+
assert.deepEqual(scrollFilter({ userId: 'u', namespace: 'n' }), {
|
|
88
|
+
must: [
|
|
89
|
+
{ key: 'userId', match: { value: 'u' } },
|
|
90
|
+
{ key: 'namespace', match: { value: 'n' } },
|
|
91
|
+
],
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
it('scan posts a payload-only scroll and ends on a null offset', async () => {
|
|
95
|
+
const store = await open();
|
|
96
|
+
const w = store.writer();
|
|
97
|
+
await w.upsertRaw('a', 'text a', { userId: 'u1' });
|
|
98
|
+
await w.upsertRaw('b', 'text b', { userId: 'u2' });
|
|
99
|
+
stub.requests.length = 0;
|
|
100
|
+
const r = await store.scan({ filter: { userId: 'u1' }, pageSize: 5 });
|
|
101
|
+
assert.ok(r.ok);
|
|
102
|
+
assert.deepEqual(r.value.records.map((x) => x.id), ['a']);
|
|
103
|
+
assert.equal(r.value.cursor, undefined);
|
|
104
|
+
const req = stub.requests.find((x) => x.path.endsWith('/points/scroll'));
|
|
105
|
+
assert.deepEqual(req?.body, {
|
|
106
|
+
limit: 5,
|
|
107
|
+
with_payload: true,
|
|
108
|
+
filter: { must: [{ key: 'userId', match: { value: 'u1' } }] },
|
|
109
|
+
with_vector: false,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
it('scan falls back to the point id when the payload has no id', async () => {
|
|
113
|
+
const store = await open();
|
|
114
|
+
const name = store
|
|
115
|
+
.collectionName;
|
|
116
|
+
stub.collections
|
|
117
|
+
.get(name)
|
|
118
|
+
?.points.set('00000000-0000-0000-0000-000000000001', {
|
|
119
|
+
id: '00000000-0000-0000-0000-000000000001',
|
|
120
|
+
vector: [],
|
|
121
|
+
payload: { text: 'raw' },
|
|
122
|
+
});
|
|
123
|
+
const r = await store.scan();
|
|
124
|
+
assert.ok(r.ok);
|
|
125
|
+
assert.equal(r.value.records[0].id, '00000000-0000-0000-0000-000000000001');
|
|
126
|
+
assert.equal(r.value.records[0].text, 'raw');
|
|
127
|
+
});
|
|
128
|
+
it('scan rejects a bad pageSize before any request', async () => {
|
|
129
|
+
const store = await open();
|
|
130
|
+
stub.requests.length = 0;
|
|
131
|
+
for (const pageSize of [0, -1, 1.5, Number.NaN]) {
|
|
132
|
+
const r = await store.scan({ pageSize });
|
|
133
|
+
assert.ok(!r.ok);
|
|
134
|
+
assert.equal(r.error.code, INVALID_ARGUMENT);
|
|
135
|
+
}
|
|
136
|
+
assert.equal(stub.requests.length, 0);
|
|
137
|
+
});
|
|
138
|
+
it('scan rejects a cursor that is not a Qdrant point offset before any request', async () => {
|
|
139
|
+
const store = await open();
|
|
140
|
+
stub.requests.length = 0;
|
|
141
|
+
for (const cursor of [
|
|
142
|
+
'1.5',
|
|
143
|
+
'-1',
|
|
144
|
+
'abc',
|
|
145
|
+
'"abc"',
|
|
146
|
+
'"1"',
|
|
147
|
+
'"not-a-uuid"',
|
|
148
|
+
'9007199254740993',
|
|
149
|
+
'null',
|
|
150
|
+
'{}',
|
|
151
|
+
'',
|
|
152
|
+
]) {
|
|
153
|
+
const r = await store.scan({ cursor });
|
|
154
|
+
assert.ok(!r.ok, `cursor ${cursor} is refused`);
|
|
155
|
+
assert.equal(r.error.code, INVALID_ARGUMENT, cursor);
|
|
156
|
+
}
|
|
157
|
+
assert.equal(stub.requests.length, 0);
|
|
158
|
+
});
|
|
159
|
+
it('scan accepts an unsigned integer and a UUID cursor', async () => {
|
|
160
|
+
const store = await open();
|
|
161
|
+
stub.requests.length = 0;
|
|
162
|
+
for (const cursor of [
|
|
163
|
+
'0',
|
|
164
|
+
'42',
|
|
165
|
+
'"550e8400-e29b-41d4-a716-446655440000"',
|
|
166
|
+
]) {
|
|
167
|
+
const r = await store.scan({ cursor });
|
|
168
|
+
assert.ok(r.ok, `cursor ${cursor} is accepted`);
|
|
169
|
+
}
|
|
170
|
+
assert.equal(stub.requests.length, 3);
|
|
171
|
+
});
|
|
172
|
+
it('scan drops a point whose identity value is an array, whatever the page', async () => {
|
|
173
|
+
const store = await open();
|
|
174
|
+
const w = store.writer();
|
|
175
|
+
await w.upsertRaw('arr', 'text', { userId: ['u1', 'u2'] });
|
|
176
|
+
await w.upsertRaw('one', 'text', { userId: 'u1' });
|
|
177
|
+
const r = await store.scan({ filter: { userId: 'u1' } });
|
|
178
|
+
assert.ok(r.ok);
|
|
179
|
+
assert.deepEqual(r.value.records.map((x) => x.id), ['one']);
|
|
180
|
+
});
|
|
181
|
+
it('deleteWhere counts only the ids still present at delete time', async () => {
|
|
182
|
+
const store = await open();
|
|
183
|
+
const name = store
|
|
184
|
+
.collectionName;
|
|
185
|
+
const points = stub.collections.get(name)?.points;
|
|
186
|
+
assert.ok(points);
|
|
187
|
+
const ids = [];
|
|
188
|
+
for (let i = 0; i < 10; i++) {
|
|
189
|
+
const id = `00000000-0000-0000-0000-${String(i).padStart(12, '0')}`;
|
|
190
|
+
ids.push(id);
|
|
191
|
+
points.set(id, { id, vector: [], payload: { text: 't', userId: 'c' } });
|
|
192
|
+
}
|
|
193
|
+
// Another caller deletes one point after the snapshot, before the batch.
|
|
194
|
+
stub.beforePointsRetrieve = () => {
|
|
195
|
+
points.delete(ids[3]);
|
|
196
|
+
stub.beforePointsRetrieve = undefined;
|
|
197
|
+
};
|
|
198
|
+
const r = await store.deleteWhere({ userId: 'c' });
|
|
199
|
+
stub.beforePointsRetrieve = undefined;
|
|
200
|
+
assert.ok(r.ok);
|
|
201
|
+
assert.equal(r.value.deleted, 9);
|
|
202
|
+
assert.equal(points.size, 0);
|
|
203
|
+
const del = stub.requests.filter((x) => x.path.endsWith('/points/delete'));
|
|
204
|
+
const last = del[del.length - 1];
|
|
205
|
+
assert.equal(last.body.points.length, 9);
|
|
206
|
+
});
|
|
207
|
+
it('deleteWhere never deletes a point whose identity value is an array', async () => {
|
|
208
|
+
const store = await open();
|
|
209
|
+
const w = store.writer();
|
|
210
|
+
await w.upsertRaw('arr', 'text', { userId: ['u1', 'u2'] });
|
|
211
|
+
await w.upsertRaw('one', 'text', { userId: 'u1' });
|
|
212
|
+
const r = await store.deleteWhere({ userId: 'u1' });
|
|
213
|
+
assert.ok(r.ok);
|
|
214
|
+
assert.equal(r.value.deleted, 1);
|
|
215
|
+
const left = await store.scan();
|
|
216
|
+
assert.ok(left.ok);
|
|
217
|
+
assert.deepEqual(left.value.records.map((x) => x.id), ['arr']);
|
|
218
|
+
});
|
|
219
|
+
it('scan and deleteWhere return ABORTED for an aborted signal', async () => {
|
|
220
|
+
const store = await open();
|
|
221
|
+
const ctrl = new AbortController();
|
|
222
|
+
ctrl.abort();
|
|
223
|
+
stub.requests.length = 0;
|
|
224
|
+
const s = await store.scan({}, { signal: ctrl.signal });
|
|
225
|
+
assert.ok(!s.ok);
|
|
226
|
+
assert.equal(s.error.code, 'ABORTED');
|
|
227
|
+
const d = await store.deleteWhere({ userId: 'u' }, { signal: ctrl.signal });
|
|
228
|
+
assert.ok(!d.ok);
|
|
229
|
+
assert.equal(d.error.code, 'ABORTED');
|
|
230
|
+
assert.equal(stub.requests.length, 0);
|
|
231
|
+
});
|
|
232
|
+
it('a missing collection is an error, not an empty result', async () => {
|
|
233
|
+
const store = new QdrantRag({
|
|
234
|
+
url: stub.baseUrl,
|
|
235
|
+
collectionName: 'no_such_collection',
|
|
236
|
+
embedder,
|
|
237
|
+
});
|
|
238
|
+
const s = await store.scan();
|
|
239
|
+
assert.ok(!s.ok);
|
|
240
|
+
assert.ok(s.error instanceof RagError);
|
|
241
|
+
assert.equal(s.error.code, 'QUERY_ERROR');
|
|
242
|
+
const d = await store.deleteWhere({ userId: 'u' });
|
|
243
|
+
assert.ok(!d.ok);
|
|
244
|
+
assert.equal(d.error.code, 'DELETE_ERROR');
|
|
245
|
+
});
|
|
246
|
+
it('deleteWhere deletes in batches of at most 1000 with wait=true', async () => {
|
|
247
|
+
const store = await open();
|
|
248
|
+
const name = store
|
|
249
|
+
.collectionName;
|
|
250
|
+
const points = stub.collections.get(name)?.points;
|
|
251
|
+
assert.ok(points);
|
|
252
|
+
for (let i = 0; i < 2300; i++) {
|
|
253
|
+
const id = `00000000-0000-0000-0000-${String(i).padStart(12, '0')}`;
|
|
254
|
+
points.set(id, {
|
|
255
|
+
id,
|
|
256
|
+
vector: [],
|
|
257
|
+
payload: { text: 't', userId: i < 2200 ? 'bulk' : 'keep' },
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
stub.requests.length = 0;
|
|
261
|
+
const r = await store.deleteWhere({ userId: 'bulk' });
|
|
262
|
+
assert.ok(r.ok);
|
|
263
|
+
assert.equal(r.value.deleted, 2200);
|
|
264
|
+
assert.equal(points.size, 100);
|
|
265
|
+
const deletes = stub.requests.filter((x) => x.path.endsWith('/points/delete'));
|
|
266
|
+
assert.deepEqual(deletes.map((x) => x.body.points.length), [1000, 1000, 200]);
|
|
267
|
+
});
|
|
268
|
+
it('deleteWhere aborted between batches reports how many were deleted', async () => {
|
|
269
|
+
const store = await open();
|
|
270
|
+
const name = store
|
|
271
|
+
.collectionName;
|
|
272
|
+
const points = stub.collections.get(name)?.points;
|
|
273
|
+
assert.ok(points);
|
|
274
|
+
for (let i = 0; i < 1500; i++) {
|
|
275
|
+
const id = `00000000-0000-0000-0000-${String(i).padStart(12, '0')}`;
|
|
276
|
+
points.set(id, { id, vector: [], payload: { text: 't', userId: 'x' } });
|
|
277
|
+
}
|
|
278
|
+
const ctrl = new AbortController();
|
|
279
|
+
let deletes = 0;
|
|
280
|
+
stub.failOn = (req) => {
|
|
281
|
+
// abort while the second batch is in flight: the first is done
|
|
282
|
+
if (req.path.endsWith('/points/delete') && ++deletes === 2) {
|
|
283
|
+
setImmediate(() => ctrl.abort());
|
|
284
|
+
}
|
|
285
|
+
return false;
|
|
286
|
+
};
|
|
287
|
+
const r = await store.deleteWhere({ userId: 'x' }, { signal: ctrl.signal });
|
|
288
|
+
stub.failOn = undefined;
|
|
289
|
+
assert.ok(!r.ok);
|
|
290
|
+
assert.equal(r.error.code, 'ABORTED');
|
|
291
|
+
assert.match(r.error.message, /deleting 1000 record\(s\)/);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
//# sourceMappingURL=scan-delete.test.js.map
|