bikky 0.2.2 → 0.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 +15 -2
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +31 -1
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +1 -1
- package/dist/config.test.js.map +1 -1
- package/dist/daemon/extraction.d.ts.map +1 -1
- package/dist/daemon/extraction.js +102 -42
- package/dist/daemon/extraction.js.map +1 -1
- package/dist/daemon/qdrant.d.ts.map +1 -1
- package/dist/daemon/qdrant.js +22 -17
- package/dist/daemon/qdrant.js.map +1 -1
- package/dist/daemon/relations.d.ts +4 -1
- package/dist/daemon/relations.d.ts.map +1 -1
- package/dist/daemon/relations.js +40 -17
- package/dist/daemon/relations.js.map +1 -1
- package/dist/lib/qdrant-client.d.ts +89 -0
- package/dist/lib/qdrant-client.d.ts.map +1 -0
- package/dist/lib/qdrant-client.js +242 -0
- package/dist/lib/qdrant-client.js.map +1 -0
- package/dist/lib/qdrant-client.test.d.ts +8 -0
- package/dist/lib/qdrant-client.test.d.ts.map +1 -0
- package/dist/lib/qdrant-client.test.js +207 -0
- package/dist/lib/qdrant-client.test.js.map +1 -0
- package/dist/mcp/api.d.ts.map +1 -1
- package/dist/mcp/api.js +42 -44
- package/dist/mcp/api.js.map +1 -1
- package/package.json +1 -2
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Qdrant HTTP client used by both the daemon and the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Adds the resilience features that the previous inline `fetch` wrappers lacked:
|
|
5
|
+
* - per-request timeout via AbortSignal
|
|
6
|
+
* - retry with exponential backoff + jitter on transient errors (5xx, 408, 425)
|
|
7
|
+
* - 429 handling that honours Retry-After
|
|
8
|
+
* - typed errors so callers can branch on status class instead of string-matching
|
|
9
|
+
*
|
|
10
|
+
* The client is intentionally minimal — it exposes a generic `request<T>` and a
|
|
11
|
+
* dedicated `ensureCollection` helper. Higher-level Qdrant operations
|
|
12
|
+
* (search/scroll/upsert/etc.) stay in the daemon and MCP modules so this lib
|
|
13
|
+
* does not need to know about payload shapes.
|
|
14
|
+
*/
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Error hierarchy
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export class QdrantError extends Error {
|
|
19
|
+
status;
|
|
20
|
+
responseBody;
|
|
21
|
+
constructor(message, status, responseBody) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "QdrantError";
|
|
24
|
+
this.status = status;
|
|
25
|
+
this.responseBody = responseBody;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** 401 / 403 — credentials are missing, wrong, or revoked. Not retried. */
|
|
29
|
+
export class QdrantAuthError extends QdrantError {
|
|
30
|
+
constructor(message, status, responseBody) {
|
|
31
|
+
super(message, status, responseBody);
|
|
32
|
+
this.name = "QdrantAuthError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** 404 — collection or point not found. Not retried. */
|
|
36
|
+
export class QdrantNotFoundError extends QdrantError {
|
|
37
|
+
constructor(message, status, responseBody) {
|
|
38
|
+
super(message, status, responseBody);
|
|
39
|
+
this.name = "QdrantNotFoundError";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** 429 — rate limit. Retried (Retry-After honoured if present). */
|
|
43
|
+
export class QdrantRateLimitError extends QdrantError {
|
|
44
|
+
retryAfterMs;
|
|
45
|
+
constructor(message, status, responseBody, retryAfterMs) {
|
|
46
|
+
super(message, status, responseBody);
|
|
47
|
+
this.name = "QdrantRateLimitError";
|
|
48
|
+
this.retryAfterMs = retryAfterMs;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** 408, 425, 5xx, network failures, timeouts. Retried. */
|
|
52
|
+
export class QdrantTransientError extends QdrantError {
|
|
53
|
+
constructor(message, status, responseBody) {
|
|
54
|
+
super(message, status, responseBody);
|
|
55
|
+
this.name = "QdrantTransientError";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** 400, 422 — malformed request. Not retried. */
|
|
59
|
+
export class QdrantBadRequestError extends QdrantError {
|
|
60
|
+
constructor(message, status, responseBody) {
|
|
61
|
+
super(message, status, responseBody);
|
|
62
|
+
this.name = "QdrantBadRequestError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Client
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
69
|
+
const DEFAULT_RETRIES = 3;
|
|
70
|
+
const DEFAULT_RETRY_BASE_DELAY_MS = 250;
|
|
71
|
+
const MAX_BACKOFF_MS = 5_000;
|
|
72
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
73
|
+
const jitter = (base) => {
|
|
74
|
+
const factor = 0.8 + Math.random() * 0.4; // ±20%
|
|
75
|
+
return Math.round(base * factor);
|
|
76
|
+
};
|
|
77
|
+
const parseRetryAfter = (header) => {
|
|
78
|
+
if (!header)
|
|
79
|
+
return undefined;
|
|
80
|
+
const seconds = Number(header);
|
|
81
|
+
if (Number.isFinite(seconds) && seconds >= 0)
|
|
82
|
+
return seconds * 1000;
|
|
83
|
+
// HTTP date format
|
|
84
|
+
const ts = Date.parse(header);
|
|
85
|
+
if (Number.isFinite(ts)) {
|
|
86
|
+
const delta = ts - Date.now();
|
|
87
|
+
return delta > 0 ? delta : 0;
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
};
|
|
91
|
+
const classifyStatus = (status, responseBody, method, path, retryAfterMs) => {
|
|
92
|
+
const summary = responseBody.slice(0, 500);
|
|
93
|
+
const message = `Qdrant ${method} ${path} failed (${status}): ${summary}`;
|
|
94
|
+
if (status === 401 || status === 403)
|
|
95
|
+
return new QdrantAuthError(message, status, responseBody);
|
|
96
|
+
if (status === 404)
|
|
97
|
+
return new QdrantNotFoundError(message, status, responseBody);
|
|
98
|
+
if (status === 429)
|
|
99
|
+
return new QdrantRateLimitError(message, status, responseBody, retryAfterMs);
|
|
100
|
+
if (status === 408 || status === 425 || status >= 500) {
|
|
101
|
+
return new QdrantTransientError(message, status, responseBody);
|
|
102
|
+
}
|
|
103
|
+
if (status === 400 || status === 422)
|
|
104
|
+
return new QdrantBadRequestError(message, status, responseBody);
|
|
105
|
+
return new QdrantError(message, status, responseBody);
|
|
106
|
+
};
|
|
107
|
+
export class QdrantClient {
|
|
108
|
+
url;
|
|
109
|
+
apiKey;
|
|
110
|
+
collection;
|
|
111
|
+
timeoutMs;
|
|
112
|
+
retries;
|
|
113
|
+
retryBaseDelayMs;
|
|
114
|
+
log;
|
|
115
|
+
constructor(opts) {
|
|
116
|
+
if (!opts.url)
|
|
117
|
+
throw new Error("QdrantClient: url is required");
|
|
118
|
+
if (!opts.apiKey)
|
|
119
|
+
throw new Error("QdrantClient: apiKey is required");
|
|
120
|
+
if (!opts.collection)
|
|
121
|
+
throw new Error("QdrantClient: collection is required");
|
|
122
|
+
this.url = opts.url.replace(/\/+$/, "");
|
|
123
|
+
this.apiKey = opts.apiKey;
|
|
124
|
+
this.collection = opts.collection;
|
|
125
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
126
|
+
this.retries = opts.retries ?? DEFAULT_RETRIES;
|
|
127
|
+
this.retryBaseDelayMs = opts.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS;
|
|
128
|
+
this.log = opts.log ?? (() => { });
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Perform a single Qdrant REST request. Retries transient errors and 429s
|
|
132
|
+
* with exponential backoff. Errors are classified into the typed hierarchy.
|
|
133
|
+
*/
|
|
134
|
+
async request(method, path, body, opts) {
|
|
135
|
+
const maxAttempts = (opts?.retries ?? this.retries) + 1;
|
|
136
|
+
const timeoutMs = opts?.timeoutMs ?? this.timeoutMs;
|
|
137
|
+
let attempt = 0;
|
|
138
|
+
let lastErr;
|
|
139
|
+
while (attempt < maxAttempts) {
|
|
140
|
+
attempt++;
|
|
141
|
+
try {
|
|
142
|
+
return await this.doRequest(method, path, body, timeoutMs);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
lastErr = err;
|
|
146
|
+
const retryable = err instanceof QdrantTransientError || err instanceof QdrantRateLimitError;
|
|
147
|
+
if (!retryable || attempt >= maxAttempts)
|
|
148
|
+
throw err;
|
|
149
|
+
const baseDelay = err instanceof QdrantRateLimitError && err.retryAfterMs !== undefined
|
|
150
|
+
? err.retryAfterMs
|
|
151
|
+
: Math.min(this.retryBaseDelayMs * 2 ** (attempt - 1), MAX_BACKOFF_MS);
|
|
152
|
+
const delay = jitter(baseDelay);
|
|
153
|
+
const status = err instanceof QdrantError ? err.status ?? "?" : "?";
|
|
154
|
+
this.log("WARN", `Qdrant retry ${attempt}/${maxAttempts - 1} after ${status} on ${method} ${path} (sleeping ${delay}ms)`);
|
|
155
|
+
await sleep(delay);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Defensive — loop always either returns or throws.
|
|
159
|
+
throw lastErr instanceof Error ? lastErr : new QdrantError(String(lastErr));
|
|
160
|
+
}
|
|
161
|
+
async doRequest(method, path, body, timeoutMs) {
|
|
162
|
+
const url = `${this.url}${path}`;
|
|
163
|
+
const headers = {
|
|
164
|
+
"Content-Type": "application/json",
|
|
165
|
+
"api-key": this.apiKey,
|
|
166
|
+
};
|
|
167
|
+
const init = { method, headers };
|
|
168
|
+
if (body !== undefined)
|
|
169
|
+
init.body = JSON.stringify(body);
|
|
170
|
+
let signal;
|
|
171
|
+
if (timeoutMs > 0) {
|
|
172
|
+
// AbortSignal.timeout is available in Node >= 17.3
|
|
173
|
+
signal = AbortSignal.timeout(timeoutMs);
|
|
174
|
+
init.signal = signal;
|
|
175
|
+
}
|
|
176
|
+
let resp;
|
|
177
|
+
try {
|
|
178
|
+
resp = await fetch(url, init);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
const isAbort = (err instanceof DOMException && err.name === "TimeoutError") ||
|
|
182
|
+
(err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError"));
|
|
183
|
+
if (isAbort) {
|
|
184
|
+
throw new QdrantTransientError(`Qdrant ${method} ${path} timed out after ${timeoutMs}ms`);
|
|
185
|
+
}
|
|
186
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
187
|
+
throw new QdrantTransientError(`Qdrant ${method} ${path} network error: ${msg}`);
|
|
188
|
+
}
|
|
189
|
+
if (!resp.ok) {
|
|
190
|
+
const text = await resp.text().catch(() => "");
|
|
191
|
+
const retryAfter = parseRetryAfter(resp.headers.get("retry-after"));
|
|
192
|
+
throw classifyStatus(resp.status, text, method, path, retryAfter);
|
|
193
|
+
}
|
|
194
|
+
// Some Qdrant endpoints (rare) return empty bodies on success.
|
|
195
|
+
const text = await resp.text();
|
|
196
|
+
if (!text)
|
|
197
|
+
return undefined;
|
|
198
|
+
try {
|
|
199
|
+
return JSON.parse(text);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
throw new QdrantError(`Qdrant ${method} ${path} returned invalid JSON: ${err instanceof Error ? err.message : String(err)}`, resp.status, text.slice(0, 500));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Ensure the configured collection exists with the given vector size, then
|
|
207
|
+
* (re-)create the supplied payload indexes. Index creation failures are
|
|
208
|
+
* logged but not fatal — Qdrant returns an error when an index already
|
|
209
|
+
* exists, and we want this to be idempotent.
|
|
210
|
+
*/
|
|
211
|
+
async ensureCollection(vectorSize, indexes) {
|
|
212
|
+
const col = this.collection;
|
|
213
|
+
let exists = false;
|
|
214
|
+
try {
|
|
215
|
+
await this.request("GET", `/collections/${col}`);
|
|
216
|
+
exists = true;
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
if (!(err instanceof QdrantNotFoundError))
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
if (!exists) {
|
|
223
|
+
await this.request("PUT", `/collections/${col}`, {
|
|
224
|
+
vectors: { size: vectorSize, distance: "Cosine" },
|
|
225
|
+
});
|
|
226
|
+
this.log("INFO", `Qdrant collection '${col}' created (vector size ${vectorSize})`);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.log("DEBUG", `Qdrant collection '${col}' already exists`);
|
|
230
|
+
}
|
|
231
|
+
for (const idx of indexes) {
|
|
232
|
+
try {
|
|
233
|
+
await this.request("PUT", `/collections/${col}/index`, idx);
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
// Index already-exists / harmless conflicts surface as 4xx — log and continue.
|
|
237
|
+
this.log("WARN", `Qdrant index ${idx.field_name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=qdrant-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qdrant-client.js","sourceRoot":"","sources":["../../src/lib/qdrant-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qdrant-client.test.d.ts","sourceRoot":"","sources":["../../src/lib/qdrant-client.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the shared QdrantClient.
|
|
3
|
+
*
|
|
4
|
+
* No real network — `globalThis.fetch` is monkey-patched per test to return
|
|
5
|
+
* scripted responses or throw scripted errors.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, afterEach } from "node:test";
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
import { QdrantClient, QdrantAuthError, QdrantBadRequestError, QdrantNotFoundError, QdrantRateLimitError, QdrantTransientError, } from "./qdrant-client.js";
|
|
10
|
+
const buildResponse = (step) => {
|
|
11
|
+
const body = step.body ?? "";
|
|
12
|
+
return new Response(body, { status: step.status, headers: step.headers });
|
|
13
|
+
};
|
|
14
|
+
const installFetchMock = (steps) => {
|
|
15
|
+
const original = globalThis.fetch;
|
|
16
|
+
const calls = [];
|
|
17
|
+
let i = 0;
|
|
18
|
+
globalThis.fetch = (async (input, init) => {
|
|
19
|
+
calls.push({ url: String(input), init });
|
|
20
|
+
const step = steps[i++];
|
|
21
|
+
if (!step)
|
|
22
|
+
throw new Error(`fetch mock exhausted after ${i} call(s)`);
|
|
23
|
+
if ("error" in step)
|
|
24
|
+
throw step.error;
|
|
25
|
+
return buildResponse(step);
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
calls,
|
|
29
|
+
restore: () => {
|
|
30
|
+
globalThis.fetch = original;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
const baseOpts = {
|
|
35
|
+
url: "https://example.qdrant.io",
|
|
36
|
+
apiKey: "test-key",
|
|
37
|
+
collection: "bikky-test",
|
|
38
|
+
retryBaseDelayMs: 1, // keep tests fast
|
|
39
|
+
};
|
|
40
|
+
describe("QdrantClient", () => {
|
|
41
|
+
let mock = null;
|
|
42
|
+
afterEach(() => {
|
|
43
|
+
if (mock) {
|
|
44
|
+
mock.restore();
|
|
45
|
+
mock = null;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
describe("request — happy path", () => {
|
|
49
|
+
it("parses JSON success response and sends api-key header", async () => {
|
|
50
|
+
mock = installFetchMock([{ status: 200, body: JSON.stringify({ result: { ok: true } }) }]);
|
|
51
|
+
const client = new QdrantClient(baseOpts);
|
|
52
|
+
const out = await client.request("GET", "/collections");
|
|
53
|
+
assert.deepEqual(out, { result: { ok: true } });
|
|
54
|
+
assert.equal(mock.calls.length, 1);
|
|
55
|
+
assert.equal(mock.calls[0].url, "https://example.qdrant.io/collections");
|
|
56
|
+
const headers = mock.calls[0].init?.headers;
|
|
57
|
+
assert.equal(headers["api-key"], "test-key");
|
|
58
|
+
assert.equal(headers["Content-Type"], "application/json");
|
|
59
|
+
});
|
|
60
|
+
it("strips trailing slashes from the configured URL", async () => {
|
|
61
|
+
mock = installFetchMock([{ status: 200, body: "{}" }]);
|
|
62
|
+
const client = new QdrantClient({ ...baseOpts, url: "https://example.qdrant.io///" });
|
|
63
|
+
await client.request("GET", "/collections");
|
|
64
|
+
assert.equal(mock.calls[0].url, "https://example.qdrant.io/collections");
|
|
65
|
+
});
|
|
66
|
+
it("returns undefined for empty success bodies", async () => {
|
|
67
|
+
mock = installFetchMock([{ status: 200, body: "" }]);
|
|
68
|
+
const client = new QdrantClient(baseOpts);
|
|
69
|
+
const out = await client.request("GET", "/collections/foo");
|
|
70
|
+
assert.equal(out, undefined);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe("error classification", () => {
|
|
74
|
+
it("401 → QdrantAuthError, no retry", async () => {
|
|
75
|
+
mock = installFetchMock([{ status: 401, body: "unauthorized" }]);
|
|
76
|
+
const client = new QdrantClient(baseOpts);
|
|
77
|
+
await assert.rejects(() => client.request("GET", "/collections"), QdrantAuthError);
|
|
78
|
+
assert.equal(mock.calls.length, 1);
|
|
79
|
+
});
|
|
80
|
+
it("404 → QdrantNotFoundError, no retry", async () => {
|
|
81
|
+
mock = installFetchMock([{ status: 404, body: "not found" }]);
|
|
82
|
+
const client = new QdrantClient(baseOpts);
|
|
83
|
+
await assert.rejects(() => client.request("GET", "/collections/missing"), QdrantNotFoundError);
|
|
84
|
+
assert.equal(mock.calls.length, 1);
|
|
85
|
+
});
|
|
86
|
+
it("400 → QdrantBadRequestError, no retry", async () => {
|
|
87
|
+
mock = installFetchMock([{ status: 400, body: "bad request" }]);
|
|
88
|
+
const client = new QdrantClient(baseOpts);
|
|
89
|
+
await assert.rejects(() => client.request("PUT", "/collections/foo", {}), QdrantBadRequestError);
|
|
90
|
+
assert.equal(mock.calls.length, 1);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe("retry on transient errors", () => {
|
|
94
|
+
it("retries 503 then succeeds", async () => {
|
|
95
|
+
mock = installFetchMock([
|
|
96
|
+
{ status: 503, body: "service unavailable" },
|
|
97
|
+
{ status: 200, body: JSON.stringify({ ok: true }) },
|
|
98
|
+
]);
|
|
99
|
+
const client = new QdrantClient(baseOpts);
|
|
100
|
+
const out = await client.request("POST", "/collections/foo/points/search");
|
|
101
|
+
assert.deepEqual(out, { ok: true });
|
|
102
|
+
assert.equal(mock.calls.length, 2);
|
|
103
|
+
});
|
|
104
|
+
it("retries network failure (TypeError) then succeeds", async () => {
|
|
105
|
+
mock = installFetchMock([
|
|
106
|
+
{ error: new TypeError("network down") },
|
|
107
|
+
{ status: 200, body: "{}" },
|
|
108
|
+
]);
|
|
109
|
+
const client = new QdrantClient(baseOpts);
|
|
110
|
+
await client.request("GET", "/collections");
|
|
111
|
+
assert.equal(mock.calls.length, 2);
|
|
112
|
+
});
|
|
113
|
+
it("exhausts retries and throws QdrantTransientError", async () => {
|
|
114
|
+
mock = installFetchMock([
|
|
115
|
+
{ status: 502, body: "bad gateway" },
|
|
116
|
+
{ status: 502, body: "bad gateway" },
|
|
117
|
+
{ status: 502, body: "bad gateway" },
|
|
118
|
+
{ status: 502, body: "bad gateway" },
|
|
119
|
+
]);
|
|
120
|
+
const client = new QdrantClient({ ...baseOpts, retries: 3 });
|
|
121
|
+
await assert.rejects(() => client.request("GET", "/collections"), QdrantTransientError);
|
|
122
|
+
assert.equal(mock.calls.length, 4); // initial + 3 retries
|
|
123
|
+
});
|
|
124
|
+
it("does not retry when retries=0", async () => {
|
|
125
|
+
mock = installFetchMock([{ status: 503, body: "" }]);
|
|
126
|
+
const client = new QdrantClient({ ...baseOpts, retries: 0 });
|
|
127
|
+
await assert.rejects(() => client.request("GET", "/collections"), QdrantTransientError);
|
|
128
|
+
assert.equal(mock.calls.length, 1);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("rate limiting", () => {
|
|
132
|
+
it("retries 429 then succeeds", async () => {
|
|
133
|
+
mock = installFetchMock([
|
|
134
|
+
{ status: 429, body: "slow down", headers: { "retry-after": "0" } },
|
|
135
|
+
{ status: 200, body: "{}" },
|
|
136
|
+
]);
|
|
137
|
+
const client = new QdrantClient(baseOpts);
|
|
138
|
+
await client.request("POST", "/collections/foo/points");
|
|
139
|
+
assert.equal(mock.calls.length, 2);
|
|
140
|
+
});
|
|
141
|
+
it("attaches retryAfterMs from Retry-After header", async () => {
|
|
142
|
+
mock = installFetchMock([{ status: 429, body: "", headers: { "retry-after": "2" } }]);
|
|
143
|
+
const client = new QdrantClient({ ...baseOpts, retries: 0 });
|
|
144
|
+
try {
|
|
145
|
+
await client.request("GET", "/collections");
|
|
146
|
+
assert.fail("should have thrown");
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
assert.ok(err instanceof QdrantRateLimitError);
|
|
150
|
+
assert.equal(err.retryAfterMs, 2000);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe("timeout", () => {
|
|
155
|
+
it("aborted fetch surfaces as QdrantTransientError", async () => {
|
|
156
|
+
const abortErr = new Error("The operation was aborted");
|
|
157
|
+
abortErr.name = "TimeoutError";
|
|
158
|
+
mock = installFetchMock([{ error: abortErr }, { error: abortErr }]);
|
|
159
|
+
const client = new QdrantClient({ ...baseOpts, retries: 1, timeoutMs: 1 });
|
|
160
|
+
await assert.rejects(() => client.request("GET", "/collections"), QdrantTransientError);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe("ensureCollection", () => {
|
|
164
|
+
it("creates collection when GET returns 404", async () => {
|
|
165
|
+
mock = installFetchMock([
|
|
166
|
+
{ status: 404, body: "not found" }, // GET /collections/foo
|
|
167
|
+
{ status: 200, body: "{}" }, // PUT /collections/foo
|
|
168
|
+
{ status: 200, body: "{}" }, // PUT index 1
|
|
169
|
+
]);
|
|
170
|
+
const client = new QdrantClient(baseOpts);
|
|
171
|
+
await client.ensureCollection(1024, [{ field_name: "category", field_schema: "keyword" }]);
|
|
172
|
+
assert.equal(mock.calls.length, 3);
|
|
173
|
+
assert.equal(mock.calls[1].init?.method, "PUT");
|
|
174
|
+
const putBody = JSON.parse(mock.calls[1].init?.body);
|
|
175
|
+
assert.deepEqual(putBody, { vectors: { size: 1024, distance: "Cosine" } });
|
|
176
|
+
});
|
|
177
|
+
it("skips creation when collection already exists", async () => {
|
|
178
|
+
mock = installFetchMock([
|
|
179
|
+
{ status: 200, body: "{}" }, // GET succeeds
|
|
180
|
+
{ status: 200, body: "{}" }, // PUT index
|
|
181
|
+
]);
|
|
182
|
+
const client = new QdrantClient(baseOpts);
|
|
183
|
+
await client.ensureCollection(1024, [{ field_name: "category", field_schema: "keyword" }]);
|
|
184
|
+
assert.equal(mock.calls.length, 2);
|
|
185
|
+
});
|
|
186
|
+
it("swallows index creation failures", async () => {
|
|
187
|
+
mock = installFetchMock([
|
|
188
|
+
{ status: 200, body: "{}" }, // GET
|
|
189
|
+
{ status: 400, body: "index already exists" }, // PUT index — error swallowed
|
|
190
|
+
]);
|
|
191
|
+
const client = new QdrantClient(baseOpts);
|
|
192
|
+
await client.ensureCollection(1024, [{ field_name: "category", field_schema: "keyword" }]);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
describe("constructor validation", () => {
|
|
196
|
+
it("rejects empty url", () => {
|
|
197
|
+
assert.throws(() => new QdrantClient({ ...baseOpts, url: "" }), /url is required/);
|
|
198
|
+
});
|
|
199
|
+
it("rejects empty apiKey", () => {
|
|
200
|
+
assert.throws(() => new QdrantClient({ ...baseOpts, apiKey: "" }), /apiKey is required/);
|
|
201
|
+
});
|
|
202
|
+
it("rejects empty collection", () => {
|
|
203
|
+
assert.throws(() => new QdrantClient({ ...baseOpts, collection: "" }), /collection is required/);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=qdrant-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qdrant-client.test.js","sourceRoot":"","sources":["../../src/lib/qdrant-client.test.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/mcp/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAA2B,MAAM,iBAAiB,CAAC;AAC5H,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/mcp/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAA2B,MAAM,iBAAiB,CAAC;AAC5H,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAU5E,eAAO,MAAM,UAAU,QAAY,CAAC;AAGpC,wBAAgB,aAAa,IAAI,MAAM,CAA2B;AAClE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGhD;AAWD,eAAO,IAAI,SAAS,EAAE,MAAM,GAAG,IAAW,CAAC;AAC3C,eAAO,IAAI,YAAY,EAAE,MAAM,GAAG,IAAW,CAAC;AAC9C,eAAO,IAAI,KAAK,SAAQ,CAAC;AAIzB,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGnD;AACD,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGtD;AACD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAe;AAMzD,eAAO,MAAM,GAAG,8BAGd,CAAC;AA0BH,wBAAsB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6B5F;AAgBD,wBAAsB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAE9F;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlH;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAInH;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAO7H;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAMhG;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAKxG;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAK7E"}
|
package/dist/mcp/api.js
CHANGED
|
@@ -8,13 +8,17 @@ import { embed, getEmbeddingDimensions, getEmbeddingConfig, initEmbedding, chatC
|
|
|
8
8
|
export { embed, getEmbeddingDimensions, getEmbeddingConfig, initEmbedding };
|
|
9
9
|
import { createLogger } from "../logger.js";
|
|
10
10
|
import { BIKKY_DIR, LOG_DIR, loadConfig } from "../config.js";
|
|
11
|
+
import { QdrantClient } from "../lib/qdrant-client.js";
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
12
13
|
// Config
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
export const MEMORY_DIR = BIKKY_DIR;
|
|
15
16
|
let collectionName = "bikky";
|
|
16
17
|
export function getCollection() { return collectionName; }
|
|
17
|
-
export function setCollection(name) {
|
|
18
|
+
export function setCollection(name) {
|
|
19
|
+
collectionName = name;
|
|
20
|
+
rebuildClient();
|
|
21
|
+
}
|
|
18
22
|
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
19
23
|
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
20
24
|
let llmInitialized = false;
|
|
@@ -24,8 +28,15 @@ let llmInitialized = false;
|
|
|
24
28
|
export let qdrantUrl = null;
|
|
25
29
|
export let qdrantApiKey = null;
|
|
26
30
|
export let ready = false;
|
|
27
|
-
|
|
28
|
-
export function
|
|
31
|
+
let client = null;
|
|
32
|
+
export function setQdrantUrl(v) {
|
|
33
|
+
qdrantUrl = v ? v.replace(/\/+$/, "") : v;
|
|
34
|
+
rebuildClient();
|
|
35
|
+
}
|
|
36
|
+
export function setQdrantApiKey(v) {
|
|
37
|
+
qdrantApiKey = v;
|
|
38
|
+
rebuildClient();
|
|
39
|
+
}
|
|
29
40
|
export function setReady(v) { ready = v; }
|
|
30
41
|
// ---------------------------------------------------------------------------
|
|
31
42
|
// Logging (to file only — stdout/stderr are MCP stdio transport)
|
|
@@ -34,6 +45,25 @@ export const log = createLogger("memory-mcp", path.join(LOG_DIR, "mcp.log"), {
|
|
|
34
45
|
maxSize: 2 * 1024 * 1024,
|
|
35
46
|
maxFiles: 3,
|
|
36
47
|
});
|
|
48
|
+
// Adapter to bridge QdrantClient's QdrantLogFn signature to our file logger.
|
|
49
|
+
const qdrantLogAdapter = (level, msg) => log(level, msg);
|
|
50
|
+
function rebuildClient() {
|
|
51
|
+
if (qdrantUrl && qdrantApiKey && collectionName) {
|
|
52
|
+
const cfg = loadConfig();
|
|
53
|
+
client = new QdrantClient({
|
|
54
|
+
url: qdrantUrl,
|
|
55
|
+
apiKey: qdrantApiKey,
|
|
56
|
+
collection: collectionName,
|
|
57
|
+
timeoutMs: cfg.qdrant_client.timeout_ms,
|
|
58
|
+
retries: cfg.qdrant_client.retries,
|
|
59
|
+
retryBaseDelayMs: cfg.qdrant_client.retry_base_delay_ms,
|
|
60
|
+
log: qdrantLogAdapter,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
client = null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
37
67
|
// ---------------------------------------------------------------------------
|
|
38
68
|
// LLM Chat Completion (for distillation)
|
|
39
69
|
// ---------------------------------------------------------------------------
|
|
@@ -69,51 +99,19 @@ export async function chatComplete(systemPrompt, userPrompt) {
|
|
|
69
99
|
// ---------------------------------------------------------------------------
|
|
70
100
|
// Qdrant REST Client
|
|
71
101
|
// ---------------------------------------------------------------------------
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
}
|
|
102
|
+
function getClient() {
|
|
103
|
+
if (!client) {
|
|
104
|
+
throw new Error("Qdrant client not initialized — credentials missing. " +
|
|
105
|
+
"Use configure_credentials or set QDRANT_URL + QDRANT_API_KEY.");
|
|
106
|
+
}
|
|
107
|
+
return client;
|
|
77
108
|
}
|
|
78
109
|
export async function qdrantReq(method, urlPath, body) {
|
|
79
|
-
|
|
80
|
-
const opts = { method, headers: qdrantHeaders() };
|
|
81
|
-
if (body)
|
|
82
|
-
opts.body = JSON.stringify(body);
|
|
83
|
-
const resp = await fetch(url, opts);
|
|
84
|
-
if (!resp.ok) {
|
|
85
|
-
const text = await resp.text();
|
|
86
|
-
throw new Error(`Qdrant ${method} ${urlPath} failed (${resp.status}): ${text}`);
|
|
87
|
-
}
|
|
88
|
-
return resp.json();
|
|
110
|
+
return getClient().request(method, urlPath, body);
|
|
89
111
|
}
|
|
90
112
|
export async function ensureCollection(indexes) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
await qdrantReq("GET", `/collections/${col}`);
|
|
95
|
-
log("INFO", `Collection '${col}' exists ✓`);
|
|
96
|
-
exists = true;
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
if (!(e instanceof Error && e.message.includes("404")))
|
|
100
|
-
throw e;
|
|
101
|
-
}
|
|
102
|
-
if (!exists) {
|
|
103
|
-
await qdrantReq("PUT", `/collections/${col}`, {
|
|
104
|
-
vectors: { size: getEmbeddingDimensions(), distance: "Cosine" },
|
|
105
|
-
});
|
|
106
|
-
log("INFO", `Collection '${col}' created`);
|
|
107
|
-
}
|
|
108
|
-
for (const idx of indexes) {
|
|
109
|
-
try {
|
|
110
|
-
await qdrantReq("PUT", `/collections/${col}/index`, idx);
|
|
111
|
-
}
|
|
112
|
-
catch (e) {
|
|
113
|
-
log("WARN", `Index creation for ${idx.field_name}: ${e instanceof Error ? e.message : String(e)}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
log("INFO", "Payload indexes created");
|
|
113
|
+
await getClient().ensureCollection(getEmbeddingDimensions(), indexes);
|
|
114
|
+
log("INFO", `Collection '${getCollection()}' ready (vector size ${getEmbeddingDimensions()}, ${indexes.length} indexes)`);
|
|
117
115
|
}
|
|
118
116
|
export async function qdrantUpsert(id, vector, payload) {
|
|
119
117
|
return qdrantReq("PUT", `/collections/${getCollection()}/points`, {
|