@remnic/core 9.3.651 → 9.3.652
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/dist/access-cli.js +9 -9
- package/dist/access-http.d.ts +3 -2
- package/dist/access-http.js +10 -10
- package/dist/access-mcp.d.ts +3 -2
- package/dist/access-mcp.js +9 -9
- package/dist/{access-service-DIZRHQ7Q.d.ts → access-service-CdJFd3_b.d.ts} +23 -2
- package/dist/access-service.d.ts +3 -2
- package/dist/access-service.js +8 -8
- package/dist/bootstrap.d.ts +2 -1
- package/dist/{chunk-QT4THOLT.js → chunk-2DGQLOOM.js} +1 -1
- package/dist/chunk-2DGQLOOM.js.map +1 -0
- package/dist/{chunk-SLYD3AH4.js → chunk-5V3TAB7D.js} +176 -4
- package/dist/chunk-5V3TAB7D.js.map +1 -0
- package/dist/{chunk-FOVPSMGI.js → chunk-7WEB3FLJ.js} +2 -2
- package/dist/{chunk-WJK75OCH.js → chunk-GI45G4BK.js} +2 -2
- package/dist/{chunk-76QTEJ2Q.js → chunk-JBHXMCYN.js} +2 -2
- package/dist/{chunk-4PTKFBST.js → chunk-JVRPJ7D4.js} +126 -26
- package/dist/chunk-JVRPJ7D4.js.map +1 -0
- package/dist/{chunk-TQUWNX7C.js → chunk-JX2RINDR.js} +2 -2
- package/dist/{chunk-RSS2KWN6.js → chunk-MGGNV3H2.js} +2 -2
- package/dist/{chunk-I4COC5XW.js → chunk-PYWNNF2I.js} +47 -9
- package/dist/chunk-PYWNNF2I.js.map +1 -0
- package/dist/{chunk-5WSDHTBO.js → chunk-TCX4WLKK.js} +7 -4
- package/dist/chunk-TCX4WLKK.js.map +1 -0
- package/dist/{chunk-RKN5J4RO.js → chunk-WSFNYPAT.js} +6 -6
- package/dist/{chunk-LFTLXOFX.js → chunk-WTI35CVJ.js} +2 -2
- package/dist/{chunk-6UKL6IXM.js → chunk-YM3LR4LS.js} +5 -5
- package/dist/{chunk-MF32AL7N.js → chunk-YOVKPOMD.js} +3 -3
- package/dist/{cli-BG4ybtJr.d.ts → cli-DDo7Qgs-.d.ts} +2 -2
- package/dist/cli.d.ts +4 -3
- package/dist/cli.js +13 -13
- package/dist/explicit-capture.d.ts +2 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -14
- package/dist/mcp-memory-inspector-app.d.ts +3 -2
- package/dist/namespaces/migrate.js +8 -8
- package/dist/namespaces/search.d.ts +18 -1
- package/dist/namespaces/search.js +7 -7
- package/dist/operator-toolkit.js +9 -9
- package/dist/{orchestrator-CX-oqwJq.d.ts → orchestrator-8fTZsa0y.d.ts} +2 -0
- package/dist/orchestrator.d.ts +2 -1
- package/dist/orchestrator.js +8 -8
- package/dist/qmd.d.ts +2 -1
- package/dist/qmd.js +2 -2
- package/dist/schemas.d.ts +22 -22
- package/dist/search/factory.js +6 -6
- package/dist/search/index.js +6 -6
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +6 -0
- package/dist/search/port.js +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/package.json +1 -1
- package/src/access-service-health.test.ts +402 -0
- package/src/access-service.ts +274 -2
- package/src/namespaces/search.test.ts +258 -3
- package/src/namespaces/search.ts +184 -30
- package/src/orchestrator.ts +11 -1
- package/src/qmd.test.ts +102 -0
- package/src/qmd.ts +54 -7
- package/src/search/port.ts +6 -0
- package/dist/chunk-4PTKFBST.js.map +0 -1
- package/dist/chunk-5WSDHTBO.js.map +0 -1
- package/dist/chunk-I4COC5XW.js.map +0 -1
- package/dist/chunk-QT4THOLT.js.map +0 -1
- package/dist/chunk-SLYD3AH4.js.map +0 -1
- /package/dist/{chunk-FOVPSMGI.js.map → chunk-7WEB3FLJ.js.map} +0 -0
- /package/dist/{chunk-WJK75OCH.js.map → chunk-GI45G4BK.js.map} +0 -0
- /package/dist/{chunk-76QTEJ2Q.js.map → chunk-JBHXMCYN.js.map} +0 -0
- /package/dist/{chunk-TQUWNX7C.js.map → chunk-JX2RINDR.js.map} +0 -0
- /package/dist/{chunk-RSS2KWN6.js.map → chunk-MGGNV3H2.js.map} +0 -0
- /package/dist/{chunk-RKN5J4RO.js.map → chunk-WSFNYPAT.js.map} +0 -0
- /package/dist/{chunk-LFTLXOFX.js.map → chunk-WTI35CVJ.js.map} +0 -0
- /package/dist/{chunk-6UKL6IXM.js.map → chunk-YM3LR4LS.js.map} +0 -0
- /package/dist/{chunk-MF32AL7N.js.map → chunk-YOVKPOMD.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-CINZGPSJ.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveEnsureCollectionArgs
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2DGQLOOM.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
13
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -491,4 +491,4 @@ function isMissingVectorProviderColumnError(err) {
|
|
|
491
491
|
export {
|
|
492
492
|
LanceDbBackend
|
|
493
493
|
};
|
|
494
|
-
//# sourceMappingURL=chunk-
|
|
494
|
+
//# sourceMappingURL=chunk-7WEB3FLJ.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-ORGWWNJG.js";
|
|
4
4
|
import {
|
|
5
5
|
namespaceCollectionName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JVRPJ7D4.js";
|
|
7
7
|
import {
|
|
8
8
|
namespaceIdentityFromToken,
|
|
9
9
|
namespaceIdentityToken
|
|
@@ -204,4 +204,4 @@ export {
|
|
|
204
204
|
verifyNamespaces,
|
|
205
205
|
runNamespaceMigration
|
|
206
206
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
207
|
+
//# sourceMappingURL=chunk-GI45G4BK.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-CINZGPSJ.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveEnsureCollectionArgs
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2DGQLOOM.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
13
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -605,4 +605,4 @@ export {
|
|
|
605
605
|
resolveOramaCollectionDbFilePath,
|
|
606
606
|
OramaBackend
|
|
607
607
|
};
|
|
608
|
-
//# sourceMappingURL=chunk-
|
|
608
|
+
//# sourceMappingURL=chunk-JBHXMCYN.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSearchBackend
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YM3LR4LS.js";
|
|
4
4
|
import {
|
|
5
5
|
namespaceIdentityToken,
|
|
6
6
|
normalizeNamespaceIdentity
|
|
@@ -125,6 +125,50 @@ var NamespaceSearchRouter = class {
|
|
|
125
125
|
const record = await this.backendRecordFor(namespace, execution);
|
|
126
126
|
return record.collectionState;
|
|
127
127
|
}
|
|
128
|
+
async healthForNamespace(namespace, execution) {
|
|
129
|
+
const key = namespace.trim() || this.config.defaultNamespace;
|
|
130
|
+
const record = await this.createBackendRecordFor(
|
|
131
|
+
key,
|
|
132
|
+
execution,
|
|
133
|
+
{
|
|
134
|
+
autoCreateCollection: false,
|
|
135
|
+
abortAsUnavailable: true,
|
|
136
|
+
failOpenMissingGuardedCollection: false
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
try {
|
|
140
|
+
const liveRecord = await this.liveCachedRecordForHealth(key, record, execution);
|
|
141
|
+
const diagnosticBackend = liveRecord?.backend ?? record.backend;
|
|
142
|
+
const versionStatus = "getVersionStatus" in diagnosticBackend && typeof diagnosticBackend.getVersionStatus === "function" ? diagnosticBackend.getVersionStatus() : null;
|
|
143
|
+
const daemonMode = daemonModeForBackend(diagnosticBackend);
|
|
144
|
+
const collectionState = liveRecord?.collectionState === "missing" ? "missing" : record.collectionState;
|
|
145
|
+
return {
|
|
146
|
+
collection: record.collection,
|
|
147
|
+
memoryDir: record.memoryDir,
|
|
148
|
+
available: liveRecord?.available ?? record.available,
|
|
149
|
+
collectionState,
|
|
150
|
+
debugStatus: diagnosticBackend.debugStatus(),
|
|
151
|
+
installedVersion: versionStatus?.installedVersion ?? null,
|
|
152
|
+
supportedVersion: versionStatus?.supportedVersion ?? null,
|
|
153
|
+
supported: versionStatus?.supported ?? null,
|
|
154
|
+
upgradeAvailable: versionStatus?.upgradeAvailable ?? null,
|
|
155
|
+
doctorAvailable: versionStatus?.capabilities?.doctor ?? null,
|
|
156
|
+
daemonMode
|
|
157
|
+
};
|
|
158
|
+
} finally {
|
|
159
|
+
const dispose = record.backend.dispose;
|
|
160
|
+
await dispose?.call(record.backend);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async liveCachedRecordForHealth(key, disposableRecord, execution) {
|
|
164
|
+
const pending = this.cache.get(key);
|
|
165
|
+
if (!pending) return null;
|
|
166
|
+
const cachedRecord = await awaitWithAbort(pending, execution?.signal).catch(() => null);
|
|
167
|
+
if (!cachedRecord) return null;
|
|
168
|
+
if (cachedRecord.collection !== disposableRecord.collection) return null;
|
|
169
|
+
if (cachedRecord.memoryDir !== disposableRecord.memoryDir) return null;
|
|
170
|
+
return cachedRecord;
|
|
171
|
+
}
|
|
128
172
|
/** Clear cached backend records so the next access re-probes availability. */
|
|
129
173
|
clearCache() {
|
|
130
174
|
this.cache.clear();
|
|
@@ -146,25 +190,54 @@ var NamespaceSearchRouter = class {
|
|
|
146
190
|
const key = namespace.trim() || this.config.defaultNamespace;
|
|
147
191
|
const existing = this.cache.get(key);
|
|
148
192
|
if (existing) return await existing;
|
|
149
|
-
const pending = (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
193
|
+
const pending = this.createBackendRecordFor(key, execution, {
|
|
194
|
+
autoCreateCollection: true,
|
|
195
|
+
abortAsUnavailable: false,
|
|
196
|
+
failOpenMissingGuardedCollection: true
|
|
197
|
+
}).catch((error) => {
|
|
198
|
+
this.cache.delete(key);
|
|
199
|
+
throw error;
|
|
200
|
+
});
|
|
201
|
+
this.cache.set(key, pending);
|
|
202
|
+
return await pending;
|
|
203
|
+
}
|
|
204
|
+
async createBackendRecordFor(namespace, execution, options) {
|
|
205
|
+
const key = namespace.trim() || this.config.defaultNamespace;
|
|
206
|
+
const storage = await this.storageRouter.storageFor(key);
|
|
207
|
+
const useLegacyDefaultCollection = key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
|
|
208
|
+
const filtersNestedNamespaces = this.config.namespacesEnabled === true && useLegacyDefaultCollection;
|
|
209
|
+
const rootHostEmbeddingScope = this.config.hostEmbeddingProviderScope ?? this.config.memoryDir;
|
|
210
|
+
const scopedConfig = {
|
|
211
|
+
...this.config,
|
|
212
|
+
memoryDir: storage.dir,
|
|
213
|
+
hostEmbeddingProviderScope: rootHostEmbeddingScope,
|
|
214
|
+
qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {
|
|
215
|
+
defaultNamespace: this.config.defaultNamespace,
|
|
216
|
+
useLegacyDefaultCollection
|
|
217
|
+
})
|
|
218
|
+
};
|
|
219
|
+
const backend = this.createBackend(scopedConfig);
|
|
220
|
+
try {
|
|
221
|
+
const availabilityProbe = options.autoCreateCollection || typeof backend.checkAvailability !== "function" ? backend.probe() : backend.checkAvailability({ signal: execution?.signal });
|
|
222
|
+
const available = await awaitWithAbort(availabilityProbe, execution?.signal).catch((error) => {
|
|
223
|
+
if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
});
|
|
228
|
+
const collectionState = available ? await awaitWithAbort(
|
|
229
|
+
this.collectionStateForBackend(backend, storage.dir, scopedConfig.qmdCollection, {
|
|
230
|
+
autoCreate: options.autoCreateCollection,
|
|
231
|
+
failOpenMissingGuardedCollection: options.failOpenMissingGuardedCollection,
|
|
232
|
+
skipAutoCreate: filtersNestedNamespaces,
|
|
233
|
+
execution
|
|
234
|
+
}),
|
|
235
|
+
execution?.signal
|
|
236
|
+
).catch((error) => {
|
|
237
|
+
if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
return "unknown";
|
|
168
241
|
}) : "unknown";
|
|
169
242
|
return {
|
|
170
243
|
backend,
|
|
@@ -174,19 +247,43 @@ var NamespaceSearchRouter = class {
|
|
|
174
247
|
collectionState,
|
|
175
248
|
filtersNestedNamespaces
|
|
176
249
|
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const dispose = backend.dispose;
|
|
252
|
+
if (dispose) {
|
|
253
|
+
await Promise.resolve(dispose.call(backend)).catch(() => {
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
180
258
|
}
|
|
181
259
|
async collectionStateForBackend(backend, memoryDir, collection, options) {
|
|
182
|
-
if (options.skipAutoCreate) {
|
|
260
|
+
if (!options.autoCreate || options.skipAutoCreate) {
|
|
183
261
|
if (!backend.checkCollection) return "unknown";
|
|
184
262
|
const collectionState = await backend.checkCollection(collection, options.execution).catch(() => "unknown");
|
|
185
|
-
return collectionState === "missing" ? "unknown" : collectionState;
|
|
263
|
+
return options.failOpenMissingGuardedCollection && collectionState === "missing" ? "unknown" : collectionState;
|
|
186
264
|
}
|
|
187
265
|
return await backend.ensureCollection(memoryDir, collection, options.execution).catch(() => "unknown");
|
|
188
266
|
}
|
|
189
267
|
};
|
|
268
|
+
var NamespaceSearchAbortError = class extends Error {
|
|
269
|
+
constructor() {
|
|
270
|
+
super("operation aborted");
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
function awaitWithAbort(operation, signal) {
|
|
274
|
+
if (!signal) return operation;
|
|
275
|
+
if (signal.aborted) return Promise.reject(new NamespaceSearchAbortError());
|
|
276
|
+
return new Promise((resolve, reject) => {
|
|
277
|
+
const onAbort = () => {
|
|
278
|
+
signal.removeEventListener("abort", onAbort);
|
|
279
|
+
reject(new NamespaceSearchAbortError());
|
|
280
|
+
};
|
|
281
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
282
|
+
operation.then(resolve, reject).finally(() => {
|
|
283
|
+
signal.removeEventListener("abort", onAbort);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
}
|
|
190
287
|
function filterNamespaceSubtreeResults(record, results) {
|
|
191
288
|
if (!record.filtersNestedNamespaces) return results;
|
|
192
289
|
return results.filter(
|
|
@@ -201,6 +298,9 @@ function backendSearchLimit(record, maxResults) {
|
|
|
201
298
|
NESTED_NAMESPACE_FILTER_OVERFETCH_MIN
|
|
202
299
|
);
|
|
203
300
|
}
|
|
301
|
+
function daemonModeForBackend(backend) {
|
|
302
|
+
return "isDaemonMode" in backend && typeof backend.isDaemonMode === "function" ? backend.isDaemonMode() === true : null;
|
|
303
|
+
}
|
|
204
304
|
function pathIsInsideNamespaceSubtree(memoryDir, collection, resultPath) {
|
|
205
305
|
if (!resultPath) return false;
|
|
206
306
|
const normalizedResultPath = normalizeQmdResultPath(resultPath, collection);
|
|
@@ -257,4 +357,4 @@ export {
|
|
|
257
357
|
namespaceCollectionName,
|
|
258
358
|
NamespaceSearchRouter
|
|
259
359
|
};
|
|
260
|
-
//# sourceMappingURL=chunk-
|
|
360
|
+
//# sourceMappingURL=chunk-JVRPJ7D4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/namespaces/search.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { PluginConfig, QmdSearchResult } from \"../types.js\";\nimport type {\n SearchBackend,\n SearchExecutionOptions,\n SearchQueryOptions,\n} from \"../search/port.js\";\nimport { createSearchBackend } from \"../search/factory.js\";\nimport { namespaceIdentityToken, normalizeNamespaceIdentity } from \"./identity.js\";\n\nconst NESTED_NAMESPACE_FILTER_OVERFETCH_FACTOR = 4;\nconst NESTED_NAMESPACE_FILTER_OVERFETCH_MIN = 50;\n\nexport function namespaceCollectionName(\n baseCollection: string,\n namespace: string,\n options?: {\n defaultNamespace?: string;\n useLegacyDefaultCollection?: boolean;\n },\n): string {\n const trimmed = normalizeNamespaceIdentity(namespace);\n const defaultNamespace = normalizeNamespaceIdentity(options?.defaultNamespace ?? \"\") || \"default\";\n if (\n options?.useLegacyDefaultCollection === true &&\n trimmed === defaultNamespace\n ) {\n return baseCollection;\n }\n\n return `${baseCollection}--${namespaceIdentityToken(trimmed || defaultNamespace)}`;\n}\n\ntype StorageRouterLike = {\n storageFor(namespace: string): Promise<{ dir: string }>;\n};\n\ntype NamespaceBackendRecord = {\n backend: SearchBackend;\n collection: string;\n memoryDir: string;\n available: boolean;\n collectionState: CollectionState;\n filtersNestedNamespaces: boolean;\n};\n\nexport type CollectionState = \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n\nexport interface NamespaceSearchHealth {\n collection: string;\n memoryDir: string;\n available: boolean;\n collectionState: CollectionState;\n debugStatus: string;\n installedVersion: string | null;\n supportedVersion: string | null;\n supported: boolean | null;\n upgradeAvailable: boolean | null;\n doctorAvailable: boolean | null;\n daemonMode: boolean | null;\n}\n\ntype NamespaceScopedSearchConfig = PluginConfig & {\n hostEmbeddingProviderScope?: string;\n};\n\ntype BackendRecordOptions = {\n autoCreateCollection: boolean;\n abortAsUnavailable: boolean;\n failOpenMissingGuardedCollection: boolean;\n};\n\nexport class NamespaceSearchRouter {\n private readonly cache = new Map<string, Promise<NamespaceBackendRecord>>();\n\n constructor(\n private readonly config: PluginConfig,\n private readonly storageRouter: StorageRouterLike,\n private readonly createBackend: (config: PluginConfig) => SearchBackend = createSearchBackend,\n ) {}\n\n async collectionForNamespace(namespace: string): Promise<string> {\n return (await this.backendRecordFor(namespace)).collection;\n }\n\n async searchAcrossNamespaces(options: {\n query: string;\n namespaces: string[];\n maxResults?: number;\n mode?: \"search\" | \"hybrid\" | \"bm25\" | \"vector\";\n searchOptions?: SearchQueryOptions;\n execution?: SearchExecutionOptions;\n }): Promise<QmdSearchResult[]> {\n const query = options.query.trim();\n if (!query) return [];\n const maxResults = Math.max(0, Math.floor(options.maxResults ?? this.config.qmdMaxResults));\n if (maxResults === 0) return [];\n\n const method = options.mode ?? \"search\";\n const namespaces = Array.from(new Set(options.namespaces.map((value) => value.trim()).filter(Boolean)));\n if (namespaces.length === 0) return [];\n\n const resultsByNamespace = await Promise.all(\n namespaces.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") {\n return { namespace, results: [] as QmdSearchResult[] };\n }\n const backendLimit = backendSearchLimit(record, maxResults);\n let results: QmdSearchResult[];\n switch (method) {\n case \"hybrid\":\n results = await record.backend.hybridSearch(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n case \"bm25\":\n results = await record.backend.bm25Search(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n case \"vector\":\n results = await record.backend.vectorSearch(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n default:\n results = await record.backend.search(\n query,\n record.collection,\n backendLimit,\n options.searchOptions,\n options.execution,\n );\n break;\n }\n results = filterNamespaceSubtreeResults(record, results);\n return { namespace, results };\n }),\n );\n\n return mergeNamespaceSearchResults(resultsByNamespace, maxResults);\n }\n\n /**\n * Update all namespace backends.\n * Returns the number of backends for which an update was attempted\n * (i.e., available and collection present). Callers can treat 0 as a\n * signal that no backend was eligible — useful for success-verification in\n * startup-sync when namespacesEnabled is true.\n */\n async updateNamespaces(\n namespaces: string[],\n execution?: SearchExecutionOptions,\n ): Promise<number> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n const eligible = (await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n return record.available && record.collectionState !== \"missing\"\n ? record\n : null;\n }),\n )).filter((record): record is NamespaceBackendRecord => record !== null);\n\n const globalRecord = eligible.find((record) => record.backend.updatesAllCollections?.() === true);\n const scopedRecords = globalRecord\n ? eligible.filter((record) => record.backend.updatesAllCollections?.() !== true)\n : eligible;\n\n await Promise.all([\n globalRecord ? globalRecord.backend.update(execution) : Promise.resolve(),\n ...scopedRecords.map((record) => record.backend.update(execution)),\n ]);\n\n return (globalRecord ? 1 : 0) + scopedRecords.length;\n }\n\n async embedNamespaces(namespaces: string[]): Promise<void> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") return;\n await record.backend.embed();\n }),\n );\n }\n\n async ensureNamespaceCollection(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n const record = await this.backendRecordFor(namespace, execution);\n return record.collectionState;\n }\n\n async healthForNamespace(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceSearchHealth> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const record = await this.createBackendRecordFor(\n key,\n execution,\n {\n autoCreateCollection: false,\n abortAsUnavailable: true,\n failOpenMissingGuardedCollection: false,\n },\n );\n try {\n const liveRecord = await this.liveCachedRecordForHealth(key, record, execution);\n const diagnosticBackend = liveRecord?.backend ?? record.backend;\n const versionStatus =\n \"getVersionStatus\" in diagnosticBackend &&\n typeof diagnosticBackend.getVersionStatus === \"function\"\n ? diagnosticBackend.getVersionStatus()\n : null;\n const daemonMode = daemonModeForBackend(diagnosticBackend);\n const collectionState =\n liveRecord?.collectionState === \"missing\"\n ? \"missing\"\n : record.collectionState;\n\n return {\n collection: record.collection,\n memoryDir: record.memoryDir,\n available: liveRecord?.available ?? record.available,\n collectionState,\n debugStatus: diagnosticBackend.debugStatus(),\n installedVersion: versionStatus?.installedVersion ?? null,\n supportedVersion: versionStatus?.supportedVersion ?? null,\n supported: versionStatus?.supported ?? null,\n upgradeAvailable: versionStatus?.upgradeAvailable ?? null,\n doctorAvailable: versionStatus?.capabilities?.doctor ?? null,\n daemonMode,\n };\n } finally {\n const dispose = (record.backend as { dispose?: () => void | Promise<void> }).dispose;\n await dispose?.call(record.backend);\n }\n }\n\n private async liveCachedRecordForHealth(\n key: string,\n disposableRecord: NamespaceBackendRecord,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceBackendRecord | null> {\n const pending = this.cache.get(key);\n if (!pending) return null;\n const cachedRecord = await awaitWithAbort(pending, execution?.signal).catch(() => null);\n if (!cachedRecord) return null;\n if (cachedRecord.collection !== disposableRecord.collection) return null;\n if (cachedRecord.memoryDir !== disposableRecord.memoryDir) return null;\n return cachedRecord;\n }\n\n /** Clear cached backend records so the next access re-probes availability. */\n clearCache(): void {\n this.cache.clear();\n }\n\n /** Release any per-namespace backend handles held by cached records. */\n async dispose(): Promise<void> {\n const pendingRecords = Array.from(this.cache.values());\n this.cache.clear();\n const settled = await Promise.allSettled(pendingRecords);\n await Promise.allSettled(\n settled.flatMap((entry) => {\n if (entry.status !== \"fulfilled\") return [];\n const dispose = (entry.value.backend as { dispose?: () => void | Promise<void> }).dispose;\n return dispose ? [dispose.call(entry.value.backend)] : [];\n }),\n );\n }\n\n private async backendRecordFor(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceBackendRecord> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const existing = this.cache.get(key);\n if (existing) return await existing;\n\n const pending = this.createBackendRecordFor(key, execution, {\n autoCreateCollection: true,\n abortAsUnavailable: false,\n failOpenMissingGuardedCollection: true,\n }).catch((error) => {\n this.cache.delete(key);\n throw error;\n });\n\n this.cache.set(key, pending);\n return await pending;\n }\n\n private async createBackendRecordFor(\n namespace: string,\n execution: SearchExecutionOptions | undefined,\n options: BackendRecordOptions,\n ): Promise<NamespaceBackendRecord> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const storage = await this.storageRouter.storageFor(key);\n const useLegacyDefaultCollection =\n key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;\n const filtersNestedNamespaces =\n this.config.namespacesEnabled === true && useLegacyDefaultCollection;\n const rootHostEmbeddingScope =\n (this.config as NamespaceScopedSearchConfig).hostEmbeddingProviderScope ??\n this.config.memoryDir;\n const scopedConfig: NamespaceScopedSearchConfig = {\n ...this.config,\n memoryDir: storage.dir,\n hostEmbeddingProviderScope: rootHostEmbeddingScope,\n qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {\n defaultNamespace: this.config.defaultNamespace,\n useLegacyDefaultCollection,\n }),\n };\n\n const backend = this.createBackend(scopedConfig);\n try {\n const availabilityProbe =\n options.autoCreateCollection || typeof backend.checkAvailability !== \"function\"\n ? backend.probe()\n : backend.checkAvailability({ signal: execution?.signal });\n const available = await awaitWithAbort(availabilityProbe, execution?.signal).catch((error) => {\n if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {\n throw error;\n }\n return false;\n });\n const collectionState = available\n ? await awaitWithAbort(\n this.collectionStateForBackend(backend, storage.dir, scopedConfig.qmdCollection, {\n autoCreate: options.autoCreateCollection,\n failOpenMissingGuardedCollection: options.failOpenMissingGuardedCollection,\n skipAutoCreate: filtersNestedNamespaces,\n execution,\n }),\n execution?.signal,\n ).catch((error) => {\n if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {\n throw error;\n }\n return \"unknown\" as const;\n })\n : \"unknown\";\n return {\n backend,\n collection: scopedConfig.qmdCollection,\n memoryDir: storage.dir,\n available,\n collectionState,\n filtersNestedNamespaces,\n };\n } catch (error) {\n const dispose = (backend as { dispose?: () => void | Promise<void> }).dispose;\n if (dispose) {\n await Promise.resolve(dispose.call(backend)).catch(() => {});\n }\n throw error;\n }\n }\n\n private async collectionStateForBackend(\n backend: SearchBackend,\n memoryDir: string,\n collection: string,\n options: {\n autoCreate: boolean;\n failOpenMissingGuardedCollection: boolean;\n skipAutoCreate: boolean;\n execution?: SearchExecutionOptions;\n },\n ): Promise<CollectionState> {\n if (!options.autoCreate || options.skipAutoCreate) {\n if (!backend.checkCollection) return \"unknown\";\n const collectionState = await backend\n .checkCollection(collection, options.execution)\n .catch(() => \"unknown\" as const);\n return options.failOpenMissingGuardedCollection && collectionState === \"missing\"\n ? \"unknown\"\n : collectionState;\n }\n return await backend.ensureCollection(memoryDir, collection, options.execution).catch(() => \"unknown\" as const);\n }\n}\n\nclass NamespaceSearchAbortError extends Error {\n constructor() {\n super(\"operation aborted\");\n }\n}\n\nfunction awaitWithAbort<T>(operation: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return operation;\n if (signal.aborted) return Promise.reject(new NamespaceSearchAbortError());\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new NamespaceSearchAbortError());\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n operation.then(resolve, reject).finally(() => {\n signal.removeEventListener(\"abort\", onAbort);\n });\n });\n}\n\nfunction filterNamespaceSubtreeResults(\n record: NamespaceBackendRecord,\n results: QmdSearchResult[],\n): QmdSearchResult[] {\n if (!record.filtersNestedNamespaces) return results;\n return results.filter((result) =>\n !pathIsInsideNamespaceSubtree(record.memoryDir, record.collection, result.path)\n );\n}\n\nfunction backendSearchLimit(\n record: NamespaceBackendRecord,\n maxResults: number,\n): number {\n if (!record.filtersNestedNamespaces) return maxResults;\n return Math.max(\n maxResults,\n maxResults * NESTED_NAMESPACE_FILTER_OVERFETCH_FACTOR,\n NESTED_NAMESPACE_FILTER_OVERFETCH_MIN,\n );\n}\n\nfunction daemonModeForBackend(backend: SearchBackend): boolean | null {\n return \"isDaemonMode\" in backend && typeof backend.isDaemonMode === \"function\"\n ? backend.isDaemonMode() === true\n : null;\n}\n\nfunction pathIsInsideNamespaceSubtree(\n memoryDir: string,\n collection: string,\n resultPath: string | undefined,\n): boolean {\n if (!resultPath) return false;\n const normalizedResultPath = normalizeQmdResultPath(resultPath, collection);\n const memoryRoot = path.resolve(memoryDir);\n const namespacesRoot = path.join(memoryRoot, \"namespaces\");\n const candidate = path.isAbsolute(normalizedResultPath)\n ? path.normalize(normalizedResultPath)\n : path.resolve(memoryRoot, normalizedResultPath);\n const relative = path.relative(namespacesRoot, candidate);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction normalizeQmdResultPath(resultPath: string, collection: string): string {\n let value = resultPath.trim();\n if (value.startsWith(\"qmd://\")) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol === \"qmd:\" && parsed.hostname === collection) {\n value = decodeURIComponent(parsed.pathname.replace(/^\\/+/, \"\"));\n }\n } catch {\n const remainder = value.slice(\"qmd://\".length);\n const slashIndex = remainder.indexOf(\"/\");\n if (slashIndex !== -1) {\n value = remainder.slice(slashIndex + 1);\n }\n }\n }\n\n const collectionPrefix = `${collection}/`;\n if (value.startsWith(collectionPrefix)) {\n value = value.slice(collectionPrefix.length);\n }\n return value;\n}\n\nfunction mergeNamespaceSearchResults(\n lists: Array<{ namespace: string; results: QmdSearchResult[] }>,\n maxResults: number,\n): QmdSearchResult[] {\n const merged = new Map<string, QmdSearchResult>();\n\n for (const { namespace, results } of lists) {\n for (const result of results) {\n const key = `${namespace}\\0${result.path || result.docid}`;\n const existing = merged.get(key);\n if (!existing) {\n merged.set(key, result);\n continue;\n }\n if (result.score > existing.score) {\n merged.set(key, {\n ...result,\n snippet: existing.snippet || result.snippet || \"\",\n });\n }\n }\n }\n\n return [...merged.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-CINZGPSJ.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveEnsureCollectionArgs
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2DGQLOOM.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
13
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -245,4 +245,4 @@ function isMeilisearchIndexNotFoundError(err) {
|
|
|
245
245
|
export {
|
|
246
246
|
MeilisearchBackend
|
|
247
247
|
};
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
248
|
+
//# sourceMappingURL=chunk-JX2RINDR.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-D24OXEPB.js";
|
|
12
12
|
import {
|
|
13
13
|
EngramAccessInputError
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5V3TAB7D.js";
|
|
15
15
|
import {
|
|
16
16
|
projectTagProjectId
|
|
17
17
|
} from "./chunk-MMJANTJX.js";
|
|
@@ -3102,4 +3102,4 @@ ${body}`;
|
|
|
3102
3102
|
export {
|
|
3103
3103
|
EngramMcpServer
|
|
3104
3104
|
};
|
|
3105
|
-
//# sourceMappingURL=chunk-
|
|
3105
|
+
//# sourceMappingURL=chunk-MGGNV3H2.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveEnsureCollectionArgs
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2DGQLOOM.js";
|
|
4
4
|
import {
|
|
5
5
|
launchProcess
|
|
6
6
|
} from "./chunk-O75CRYGF.js";
|
|
@@ -941,6 +941,21 @@ var QmdClient = class _QmdClient {
|
|
|
941
941
|
}
|
|
942
942
|
return cliOk || this.daemonAvailable;
|
|
943
943
|
}
|
|
944
|
+
async checkAvailability(execution) {
|
|
945
|
+
const cliAvailable = await this.probeCli({
|
|
946
|
+
allowAutoUpgrade: false,
|
|
947
|
+
preserveStateOnFailure: true,
|
|
948
|
+
signal: execution?.signal
|
|
949
|
+
});
|
|
950
|
+
if (this.daemonAvailable && this.daemonSession?.isActive()) {
|
|
951
|
+
return true;
|
|
952
|
+
}
|
|
953
|
+
if (this.daemonAvailable) {
|
|
954
|
+
this.daemonAvailable = false;
|
|
955
|
+
this.lastDaemonCheckAtMs = 0;
|
|
956
|
+
}
|
|
957
|
+
return cliAvailable;
|
|
958
|
+
}
|
|
944
959
|
async probeDaemon() {
|
|
945
960
|
this.lastDaemonCheckAtMs = Date.now();
|
|
946
961
|
const normalizedPath = this.qmdPath.trim() || "qmd";
|
|
@@ -978,7 +993,24 @@ var QmdClient = class _QmdClient {
|
|
|
978
993
|
return false;
|
|
979
994
|
}
|
|
980
995
|
}
|
|
981
|
-
async probeCli() {
|
|
996
|
+
async probeCli(options = {}) {
|
|
997
|
+
const priorState = options.preserveStateOnFailure === true ? {
|
|
998
|
+
available: this.available,
|
|
999
|
+
qmdPath: this.qmdPath,
|
|
1000
|
+
qmdPathSource: this.qmdPathSource,
|
|
1001
|
+
cliVersion: this.cliVersion,
|
|
1002
|
+
lastCliProbeError: this.lastCliProbeError,
|
|
1003
|
+
qmdCapabilities: this.qmdCapabilities
|
|
1004
|
+
} : null;
|
|
1005
|
+
const restorePriorState = () => {
|
|
1006
|
+
if (!priorState) return;
|
|
1007
|
+
this.available = priorState.available;
|
|
1008
|
+
this.qmdPath = priorState.qmdPath;
|
|
1009
|
+
this.qmdPathSource = priorState.qmdPathSource;
|
|
1010
|
+
this.cliVersion = priorState.cliVersion;
|
|
1011
|
+
this.lastCliProbeError = priorState.lastCliProbeError;
|
|
1012
|
+
this.qmdCapabilities = priorState.qmdCapabilities;
|
|
1013
|
+
};
|
|
982
1014
|
let configuredProbeFailure = null;
|
|
983
1015
|
const markProbeFailure = (err) => {
|
|
984
1016
|
this.lastCliProbeError = err instanceof Error ? err.message : String(err);
|
|
@@ -996,11 +1028,13 @@ var QmdClient = class _QmdClient {
|
|
|
996
1028
|
this.cliVersion = parseQmdVersionOutput(result.stdout, result.stderr);
|
|
997
1029
|
this.qmdCapabilities = resolveQmdCapabilities(this.cliVersion);
|
|
998
1030
|
this.lastCliProbeError = null;
|
|
999
|
-
|
|
1031
|
+
if (options.allowAutoUpgrade !== false) {
|
|
1032
|
+
await this.maybeAutoUpgradeQmd();
|
|
1033
|
+
}
|
|
1000
1034
|
};
|
|
1001
1035
|
if (this.configuredQmdPath) {
|
|
1002
1036
|
try {
|
|
1003
|
-
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, this.configuredQmdPath,
|
|
1037
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, this.configuredQmdPath, options.signal, this.qmdRuntimeEnv);
|
|
1004
1038
|
await recordProbeSuccess(result, this.configuredQmdPath, "configured");
|
|
1005
1039
|
return true;
|
|
1006
1040
|
} catch (err) {
|
|
@@ -1012,14 +1046,14 @@ var QmdClient = class _QmdClient {
|
|
|
1012
1046
|
}
|
|
1013
1047
|
}
|
|
1014
1048
|
try {
|
|
1015
|
-
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, "qmd",
|
|
1049
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, "qmd", options.signal, this.qmdRuntimeEnv);
|
|
1016
1050
|
await recordProbeSuccess(result, "qmd", "auto-path");
|
|
1017
1051
|
return true;
|
|
1018
1052
|
} catch (err) {
|
|
1019
1053
|
markProbeFailure(err);
|
|
1020
1054
|
for (const fallbackPath of this.qmdFallbackPaths) {
|
|
1021
1055
|
try {
|
|
1022
|
-
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, fallbackPath,
|
|
1056
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, fallbackPath, options.signal, this.qmdRuntimeEnv);
|
|
1023
1057
|
await recordProbeSuccess(result, fallbackPath, "auto-fallback");
|
|
1024
1058
|
log.info(`QMD: found at ${fallbackPath}`);
|
|
1025
1059
|
return true;
|
|
@@ -1027,8 +1061,12 @@ var QmdClient = class _QmdClient {
|
|
|
1027
1061
|
markProbeFailure(fallbackErr);
|
|
1028
1062
|
}
|
|
1029
1063
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1064
|
+
if (priorState) {
|
|
1065
|
+
restorePriorState();
|
|
1066
|
+
} else {
|
|
1067
|
+
this.available = false;
|
|
1068
|
+
restoreConfiguredProbeFailure();
|
|
1069
|
+
}
|
|
1032
1070
|
return false;
|
|
1033
1071
|
}
|
|
1034
1072
|
}
|
|
@@ -2065,4 +2103,4 @@ export {
|
|
|
2065
2103
|
getQmdCommandName,
|
|
2066
2104
|
QmdClient
|
|
2067
2105
|
};
|
|
2068
|
-
//# sourceMappingURL=chunk-
|
|
2106
|
+
//# sourceMappingURL=chunk-PYWNNF2I.js.map
|