@remnic/core 9.3.634 → 9.3.635
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 +24 -24
- package/dist/access-http.d.ts +1 -1
- package/dist/access-http.js +22 -3
- package/dist/access-mcp.d.ts +1 -1
- package/dist/access-mcp.js +21 -2
- package/dist/access-schema.d.ts +34 -34
- package/dist/{access-service-C9_EpVHd.d.ts → access-service-GVOE5U3C.d.ts} +3 -0
- package/dist/access-service.d.ts +1 -1
- package/dist/access-service.js +20 -1
- package/dist/{chunk-2ROPI5OE.js → chunk-6GC5SGFE.js} +4 -4
- package/dist/{chunk-6GDHLVJC.js → chunk-AV5ZEH4M.js} +4 -4
- package/dist/{chunk-32U3N7H5.js → chunk-BK35NOJL.js} +3 -3
- package/dist/{chunk-TZVQQTG4.js → chunk-DEDTFRH2.js} +6 -6
- package/dist/{chunk-5PT5I6JQ.js → chunk-JYFO32V4.js} +7 -7
- package/dist/{chunk-ZJR7VG5L.js → chunk-LASA46TQ.js} +2 -2
- package/dist/{chunk-XG4NAWAV.js → chunk-NFNQ7TWF.js} +3 -3
- package/dist/{chunk-XG4NAWAV.js.map → chunk-NFNQ7TWF.js.map} +1 -1
- package/dist/{chunk-YRMKDTKF.js → chunk-RAGXUVQW.js} +3 -3
- package/dist/{chunk-EWLQPEO6.js → chunk-RN7MUWON.js} +4 -4
- package/dist/{chunk-WR64DQFE.js → chunk-SQZ42MKH.js} +4 -4
- package/dist/{chunk-WLZBVYC6.js → chunk-TFICNXXU.js} +28 -28
- package/dist/{chunk-IFVFQRZ2.js → chunk-VTH5SKQW.js} +2 -2
- package/dist/{chunk-DOBJH4I6.js → chunk-XM6M6DHG.js} +78 -10
- package/dist/chunk-XM6M6DHG.js.map +1 -0
- package/dist/{chunk-VTR3MNYF.js → chunk-YCX45GOQ.js} +4 -4
- package/dist/{cli-CuVEQWKr.d.ts → cli-B-fHk59D.d.ts} +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +26 -26
- package/dist/direct-answer-wiring.js +2 -2
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +41 -41
- package/dist/mcp-memory-inspector-app.d.ts +1 -1
- package/dist/namespaces/migrate.js +8 -8
- package/dist/namespaces/search.js +6 -6
- package/dist/operator-toolkit.js +19 -19
- package/dist/orchestrator.js +23 -23
- package/dist/qmd.js +2 -2
- package/dist/retrieval-agents.js +2 -2
- package/dist/schemas.d.ts +64 -64
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.js +5 -5
- package/dist/search/index.js +5 -5
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.js +1 -1
- package/dist/search/orama-backend.js +1 -1
- package/dist/shared-context/manager.d.ts +2 -2
- package/dist/transfer/types.d.ts +12 -12
- package/package.json +1 -1
- package/src/access-mcp.ts +1 -1
- package/src/access-service-namespace.test.ts +312 -0
- package/src/access-service.ts +97 -11
- package/dist/chunk-DOBJH4I6.js.map +0 -1
- /package/dist/{chunk-2ROPI5OE.js.map → chunk-6GC5SGFE.js.map} +0 -0
- /package/dist/{chunk-6GDHLVJC.js.map → chunk-AV5ZEH4M.js.map} +0 -0
- /package/dist/{chunk-32U3N7H5.js.map → chunk-BK35NOJL.js.map} +0 -0
- /package/dist/{chunk-TZVQQTG4.js.map → chunk-DEDTFRH2.js.map} +0 -0
- /package/dist/{chunk-5PT5I6JQ.js.map → chunk-JYFO32V4.js.map} +0 -0
- /package/dist/{chunk-ZJR7VG5L.js.map → chunk-LASA46TQ.js.map} +0 -0
- /package/dist/{chunk-YRMKDTKF.js.map → chunk-RAGXUVQW.js.map} +0 -0
- /package/dist/{chunk-EWLQPEO6.js.map → chunk-RN7MUWON.js.map} +0 -0
- /package/dist/{chunk-WR64DQFE.js.map → chunk-SQZ42MKH.js.map} +0 -0
- /package/dist/{chunk-WLZBVYC6.js.map → chunk-TFICNXXU.js.map} +0 -0
- /package/dist/{chunk-IFVFQRZ2.js.map → chunk-VTH5SKQW.js.map} +0 -0
- /package/dist/{chunk-VTR3MNYF.js.map → chunk-YCX45GOQ.js.map} +0 -0
package/dist/search/index.js
CHANGED
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
createConversationIndexRuntime,
|
|
3
3
|
createConversationSearchBackend,
|
|
4
4
|
createSearchBackend
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-RAGXUVQW.js";
|
|
6
6
|
import {
|
|
7
7
|
RemoteSearchBackend
|
|
8
8
|
} from "../chunk-JOASJWQR.js";
|
|
9
9
|
import {
|
|
10
10
|
EmbedHelper
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-RN7MUWON.js";
|
|
12
12
|
import {
|
|
13
13
|
LanceDbBackend
|
|
14
14
|
} from "../chunk-3MAONBX3.js";
|
|
@@ -29,14 +29,14 @@ import "../chunk-Q6YIJGXJ.js";
|
|
|
29
29
|
import "../chunk-ORFGK3XI.js";
|
|
30
30
|
import "../chunk-OIF36KGD.js";
|
|
31
31
|
import "../chunk-7DTASS5T.js";
|
|
32
|
-
import "../chunk-
|
|
32
|
+
import "../chunk-DEDTFRH2.js";
|
|
33
33
|
import "../chunk-FAV25DUZ.js";
|
|
34
|
-
import "../chunk-3ONXXHQO.js";
|
|
35
|
-
import "../chunk-PVGDJXVK.js";
|
|
36
34
|
import "../chunk-NNVTUXEB.js";
|
|
35
|
+
import "../chunk-3ONXXHQO.js";
|
|
37
36
|
import "../chunk-CPPS65WS.js";
|
|
38
37
|
import "../chunk-JUC24CTX.js";
|
|
39
38
|
import "../chunk-2ODBA7MQ.js";
|
|
39
|
+
import "../chunk-PVGDJXVK.js";
|
|
40
40
|
import "../chunk-PZ5AY32C.js";
|
|
41
41
|
export {
|
|
42
42
|
EmbedHelper,
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
import "../chunk-Q4CAQGKQ.js";
|
|
5
5
|
import "../chunk-CINZGPSJ.js";
|
|
6
6
|
import "../chunk-FAV25DUZ.js";
|
|
7
|
-
import "../chunk-PVGDJXVK.js";
|
|
8
7
|
import "../chunk-2ODBA7MQ.js";
|
|
8
|
+
import "../chunk-PVGDJXVK.js";
|
|
9
9
|
import "../chunk-PZ5AY32C.js";
|
|
10
10
|
export {
|
|
11
11
|
LanceDbBackend
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
import "../chunk-Q4CAQGKQ.js";
|
|
5
5
|
import "../chunk-CINZGPSJ.js";
|
|
6
6
|
import "../chunk-FAV25DUZ.js";
|
|
7
|
-
import "../chunk-PVGDJXVK.js";
|
|
8
7
|
import "../chunk-2ODBA7MQ.js";
|
|
8
|
+
import "../chunk-PVGDJXVK.js";
|
|
9
9
|
import "../chunk-PZ5AY32C.js";
|
|
10
10
|
export {
|
|
11
11
|
MeilisearchBackend
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
import "../chunk-Q4CAQGKQ.js";
|
|
6
6
|
import "../chunk-CINZGPSJ.js";
|
|
7
7
|
import "../chunk-FAV25DUZ.js";
|
|
8
|
-
import "../chunk-PVGDJXVK.js";
|
|
9
8
|
import "../chunk-2ODBA7MQ.js";
|
|
9
|
+
import "../chunk-PVGDJXVK.js";
|
|
10
10
|
import "../chunk-PZ5AY32C.js";
|
|
11
11
|
export {
|
|
12
12
|
OramaBackend,
|
|
@@ -22,9 +22,9 @@ declare const SharedFeedbackEntrySchema: z.ZodObject<{
|
|
|
22
22
|
date: string;
|
|
23
23
|
agent: string;
|
|
24
24
|
reason: string;
|
|
25
|
-
confidence?: number | undefined;
|
|
26
25
|
workflow?: string | undefined;
|
|
27
26
|
tags?: string[] | undefined;
|
|
27
|
+
confidence?: number | undefined;
|
|
28
28
|
severity?: "high" | "low" | "medium" | undefined;
|
|
29
29
|
outcome?: string | undefined;
|
|
30
30
|
refs?: string[] | undefined;
|
|
@@ -36,9 +36,9 @@ declare const SharedFeedbackEntrySchema: z.ZodObject<{
|
|
|
36
36
|
date: string;
|
|
37
37
|
agent: string;
|
|
38
38
|
reason: string;
|
|
39
|
-
confidence?: number | undefined;
|
|
40
39
|
workflow?: string | undefined;
|
|
41
40
|
tags?: string[] | undefined;
|
|
41
|
+
confidence?: number | undefined;
|
|
42
42
|
severity?: "high" | "low" | "medium" | undefined;
|
|
43
43
|
outcome?: string | undefined;
|
|
44
44
|
refs?: string[] | undefined;
|
package/dist/transfer/types.d.ts
CHANGED
|
@@ -313,13 +313,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
|
|
|
313
313
|
peerProfiles: boolean;
|
|
314
314
|
}>;
|
|
315
315
|
}, "strip", z.ZodTypeAny, {
|
|
316
|
+
schemaVersion: string;
|
|
316
317
|
includes: {
|
|
317
318
|
procedural: boolean;
|
|
318
319
|
taxonomy: boolean;
|
|
319
320
|
identityAnchors: boolean;
|
|
320
321
|
peerProfiles: boolean;
|
|
321
322
|
};
|
|
322
|
-
schemaVersion: string;
|
|
323
323
|
id: string;
|
|
324
324
|
description: string;
|
|
325
325
|
version: string;
|
|
@@ -334,13 +334,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
|
|
|
334
334
|
directAnswerEnabled: boolean;
|
|
335
335
|
};
|
|
336
336
|
}, {
|
|
337
|
+
schemaVersion: string;
|
|
337
338
|
includes: {
|
|
338
339
|
procedural: boolean;
|
|
339
340
|
taxonomy: boolean;
|
|
340
341
|
identityAnchors: boolean;
|
|
341
342
|
peerProfiles: boolean;
|
|
342
343
|
};
|
|
343
|
-
schemaVersion: string;
|
|
344
344
|
id: string;
|
|
345
345
|
description: string;
|
|
346
346
|
version: string;
|
|
@@ -464,13 +464,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
464
464
|
peerProfiles: boolean;
|
|
465
465
|
}>;
|
|
466
466
|
}, "strip", z.ZodTypeAny, {
|
|
467
|
+
schemaVersion: string;
|
|
467
468
|
includes: {
|
|
468
469
|
procedural: boolean;
|
|
469
470
|
taxonomy: boolean;
|
|
470
471
|
identityAnchors: boolean;
|
|
471
472
|
peerProfiles: boolean;
|
|
472
473
|
};
|
|
473
|
-
schemaVersion: string;
|
|
474
474
|
id: string;
|
|
475
475
|
description: string;
|
|
476
476
|
version: string;
|
|
@@ -485,13 +485,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
485
485
|
directAnswerEnabled: boolean;
|
|
486
486
|
};
|
|
487
487
|
}, {
|
|
488
|
+
schemaVersion: string;
|
|
488
489
|
includes: {
|
|
489
490
|
procedural: boolean;
|
|
490
491
|
taxonomy: boolean;
|
|
491
492
|
identityAnchors: boolean;
|
|
492
493
|
peerProfiles: boolean;
|
|
493
494
|
};
|
|
494
|
-
schemaVersion: string;
|
|
495
495
|
id: string;
|
|
496
496
|
description: string;
|
|
497
497
|
version: string;
|
|
@@ -518,13 +518,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
518
518
|
pluginVersion: string;
|
|
519
519
|
includesTranscripts: boolean;
|
|
520
520
|
capsule: {
|
|
521
|
+
schemaVersion: string;
|
|
521
522
|
includes: {
|
|
522
523
|
procedural: boolean;
|
|
523
524
|
taxonomy: boolean;
|
|
524
525
|
identityAnchors: boolean;
|
|
525
526
|
peerProfiles: boolean;
|
|
526
527
|
};
|
|
527
|
-
schemaVersion: string;
|
|
528
528
|
id: string;
|
|
529
529
|
description: string;
|
|
530
530
|
version: string;
|
|
@@ -551,13 +551,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
551
551
|
pluginVersion: string;
|
|
552
552
|
includesTranscripts: boolean;
|
|
553
553
|
capsule: {
|
|
554
|
+
schemaVersion: string;
|
|
554
555
|
includes: {
|
|
555
556
|
procedural: boolean;
|
|
556
557
|
taxonomy: boolean;
|
|
557
558
|
identityAnchors: boolean;
|
|
558
559
|
peerProfiles: boolean;
|
|
559
560
|
};
|
|
560
|
-
schemaVersion: string;
|
|
561
561
|
id: string;
|
|
562
562
|
description: string;
|
|
563
563
|
version: string;
|
|
@@ -683,13 +683,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
683
683
|
peerProfiles: boolean;
|
|
684
684
|
}>;
|
|
685
685
|
}, "strip", z.ZodTypeAny, {
|
|
686
|
+
schemaVersion: string;
|
|
686
687
|
includes: {
|
|
687
688
|
procedural: boolean;
|
|
688
689
|
taxonomy: boolean;
|
|
689
690
|
identityAnchors: boolean;
|
|
690
691
|
peerProfiles: boolean;
|
|
691
692
|
};
|
|
692
|
-
schemaVersion: string;
|
|
693
693
|
id: string;
|
|
694
694
|
description: string;
|
|
695
695
|
version: string;
|
|
@@ -704,13 +704,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
704
704
|
directAnswerEnabled: boolean;
|
|
705
705
|
};
|
|
706
706
|
}, {
|
|
707
|
+
schemaVersion: string;
|
|
707
708
|
includes: {
|
|
708
709
|
procedural: boolean;
|
|
709
710
|
taxonomy: boolean;
|
|
710
711
|
identityAnchors: boolean;
|
|
711
712
|
peerProfiles: boolean;
|
|
712
713
|
};
|
|
713
|
-
schemaVersion: string;
|
|
714
714
|
id: string;
|
|
715
715
|
description: string;
|
|
716
716
|
version: string;
|
|
@@ -737,13 +737,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
737
737
|
pluginVersion: string;
|
|
738
738
|
includesTranscripts: boolean;
|
|
739
739
|
capsule: {
|
|
740
|
+
schemaVersion: string;
|
|
740
741
|
includes: {
|
|
741
742
|
procedural: boolean;
|
|
742
743
|
taxonomy: boolean;
|
|
743
744
|
identityAnchors: boolean;
|
|
744
745
|
peerProfiles: boolean;
|
|
745
746
|
};
|
|
746
|
-
schemaVersion: string;
|
|
747
747
|
id: string;
|
|
748
748
|
description: string;
|
|
749
749
|
version: string;
|
|
@@ -770,13 +770,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
770
770
|
pluginVersion: string;
|
|
771
771
|
includesTranscripts: boolean;
|
|
772
772
|
capsule: {
|
|
773
|
+
schemaVersion: string;
|
|
773
774
|
includes: {
|
|
774
775
|
procedural: boolean;
|
|
775
776
|
taxonomy: boolean;
|
|
776
777
|
identityAnchors: boolean;
|
|
777
778
|
peerProfiles: boolean;
|
|
778
779
|
};
|
|
779
|
-
schemaVersion: string;
|
|
780
780
|
id: string;
|
|
781
781
|
description: string;
|
|
782
782
|
version: string;
|
|
@@ -815,13 +815,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
815
815
|
pluginVersion: string;
|
|
816
816
|
includesTranscripts: boolean;
|
|
817
817
|
capsule: {
|
|
818
|
+
schemaVersion: string;
|
|
818
819
|
includes: {
|
|
819
820
|
procedural: boolean;
|
|
820
821
|
taxonomy: boolean;
|
|
821
822
|
identityAnchors: boolean;
|
|
822
823
|
peerProfiles: boolean;
|
|
823
824
|
};
|
|
824
|
-
schemaVersion: string;
|
|
825
825
|
id: string;
|
|
826
826
|
description: string;
|
|
827
827
|
version: string;
|
|
@@ -854,13 +854,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
854
854
|
pluginVersion: string;
|
|
855
855
|
includesTranscripts: boolean;
|
|
856
856
|
capsule: {
|
|
857
|
+
schemaVersion: string;
|
|
857
858
|
includes: {
|
|
858
859
|
procedural: boolean;
|
|
859
860
|
taxonomy: boolean;
|
|
860
861
|
identityAnchors: boolean;
|
|
861
862
|
peerProfiles: boolean;
|
|
862
863
|
};
|
|
863
|
-
schemaVersion: string;
|
|
864
864
|
id: string;
|
|
865
865
|
description: string;
|
|
866
866
|
version: string;
|
package/package.json
CHANGED
package/src/access-mcp.ts
CHANGED
|
@@ -1433,7 +1433,7 @@ export class EngramMcpServer {
|
|
|
1433
1433
|
query: { type: "string" },
|
|
1434
1434
|
namespace: { type: "string" },
|
|
1435
1435
|
maxResults: { type: "number" },
|
|
1436
|
-
collection: { type: "string", description: "QMD collection
|
|
1436
|
+
collection: { type: "string", description: "QMD collection. With namespaces enabled, omitted, base, and 'global' searches stay scoped to readable namespaces; namespace-derived collections require matching namespace access." },
|
|
1437
1437
|
},
|
|
1438
1438
|
required: ["query"],
|
|
1439
1439
|
additionalProperties: false,
|
|
@@ -6,6 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import test from "node:test";
|
|
7
7
|
|
|
8
8
|
import { EngramAccessInputError, EngramAccessService } from "./access-service.js";
|
|
9
|
+
import { namespaceCollectionName } from "./namespaces/search.js";
|
|
9
10
|
import type { StorageManager } from "./storage.js";
|
|
10
11
|
import type { PluginConfig } from "./types.js";
|
|
11
12
|
|
|
@@ -25,6 +26,8 @@ function makeConfig(): PluginConfig {
|
|
|
25
26
|
daySum: { enabled: false },
|
|
26
27
|
searchBackend: "orama",
|
|
27
28
|
qmd: { enabled: false },
|
|
29
|
+
qmdCollection: "test-memory",
|
|
30
|
+
qmdMaxResults: 10,
|
|
28
31
|
nativeKnowledge: { enabled: false },
|
|
29
32
|
recall: { budget: {} },
|
|
30
33
|
consolidation: { enabled: false },
|
|
@@ -50,14 +53,35 @@ function makeService(): {
|
|
|
50
53
|
(service as unknown as {
|
|
51
54
|
orchestrator: {
|
|
52
55
|
config: PluginConfig;
|
|
56
|
+
qmd: {
|
|
57
|
+
search(query: string, collection?: string, maxResults?: number): Promise<unknown[]>;
|
|
58
|
+
searchGlobal(query: string, maxResults?: number): Promise<unknown[]>;
|
|
59
|
+
};
|
|
53
60
|
getStorage(namespace: string): Promise<StorageManager>;
|
|
61
|
+
searchAcrossNamespaces(params: {
|
|
62
|
+
query: string;
|
|
63
|
+
namespaces?: string[];
|
|
64
|
+
maxResults?: number;
|
|
65
|
+
mode?: string;
|
|
66
|
+
}): Promise<unknown[]>;
|
|
54
67
|
};
|
|
55
68
|
}).orchestrator = {
|
|
56
69
|
config: makeConfig(),
|
|
70
|
+
qmd: {
|
|
71
|
+
async search() {
|
|
72
|
+
throw new Error("qmd.search should not run in namespace mode");
|
|
73
|
+
},
|
|
74
|
+
async searchGlobal() {
|
|
75
|
+
throw new Error("qmd.searchGlobal should not run in namespace mode");
|
|
76
|
+
},
|
|
77
|
+
},
|
|
57
78
|
async getStorage(namespace: string): Promise<StorageManager> {
|
|
58
79
|
getStorageCalls.push(namespace);
|
|
59
80
|
return storage;
|
|
60
81
|
},
|
|
82
|
+
async searchAcrossNamespaces() {
|
|
83
|
+
return [];
|
|
84
|
+
},
|
|
61
85
|
};
|
|
62
86
|
|
|
63
87
|
return { service, storage, getStorageCalls };
|
|
@@ -126,6 +150,294 @@ test("memoryBrowse resolves namespace storage for read principals", async () =>
|
|
|
126
150
|
assert.deepEqual(getStorageCalls, ["team"]);
|
|
127
151
|
});
|
|
128
152
|
|
|
153
|
+
test("memorySearch without an explicit namespace uses readable recall namespaces", async () => {
|
|
154
|
+
const { service } = makeService();
|
|
155
|
+
let searchParams: unknown;
|
|
156
|
+
(service as unknown as {
|
|
157
|
+
orchestrator: {
|
|
158
|
+
searchAcrossNamespaces(params: unknown): Promise<Array<{ path: string; score: number; snippet: string }>>;
|
|
159
|
+
};
|
|
160
|
+
}).orchestrator.searchAcrossNamespaces = async (params) => {
|
|
161
|
+
searchParams = params;
|
|
162
|
+
return [{ path: "default/facts/a.md", score: 0.7, snippet: "matched" }];
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const result = await service.memorySearch({
|
|
166
|
+
query: "deployment notes",
|
|
167
|
+
maxResults: 3,
|
|
168
|
+
principal: "reader",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
assert.deepEqual(searchParams, {
|
|
172
|
+
query: "deployment notes",
|
|
173
|
+
namespaces: ["default", "shared"],
|
|
174
|
+
maxResults: 3,
|
|
175
|
+
mode: "search",
|
|
176
|
+
});
|
|
177
|
+
assert.equal(result.count, 1);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("memorySearch with an explicit namespace searches only that readable namespace", async () => {
|
|
181
|
+
const { service } = makeService();
|
|
182
|
+
let searchParams: unknown;
|
|
183
|
+
(service as unknown as {
|
|
184
|
+
orchestrator: {
|
|
185
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
186
|
+
};
|
|
187
|
+
}).orchestrator.searchAcrossNamespaces = async (params) => {
|
|
188
|
+
searchParams = params;
|
|
189
|
+
return [];
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
await service.memorySearch({
|
|
193
|
+
query: "release note",
|
|
194
|
+
namespace: "team",
|
|
195
|
+
maxResults: 2,
|
|
196
|
+
principal: "reader",
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
assert.deepEqual(searchParams, {
|
|
200
|
+
query: "release note",
|
|
201
|
+
namespaces: ["team"],
|
|
202
|
+
maxResults: 2,
|
|
203
|
+
mode: "search",
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test("memorySearch rejects unreadable namespaces before collection routing", async () => {
|
|
208
|
+
const { service } = makeService();
|
|
209
|
+
let searchCalls = 0;
|
|
210
|
+
(service as unknown as {
|
|
211
|
+
orchestrator: {
|
|
212
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
213
|
+
};
|
|
214
|
+
}).orchestrator.searchAcrossNamespaces = async () => {
|
|
215
|
+
searchCalls += 1;
|
|
216
|
+
return [];
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
await assert.rejects(
|
|
220
|
+
() =>
|
|
221
|
+
service.memorySearch({
|
|
222
|
+
query: "release note",
|
|
223
|
+
namespace: "team",
|
|
224
|
+
collection: namespaceCollectionName("test-memory", "team", {
|
|
225
|
+
defaultNamespace: "default",
|
|
226
|
+
useLegacyDefaultCollection: false,
|
|
227
|
+
}),
|
|
228
|
+
principal: "stranger",
|
|
229
|
+
}),
|
|
230
|
+
/namespace is not readable: team/,
|
|
231
|
+
);
|
|
232
|
+
assert.equal(searchCalls, 0);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("memorySearch rejects empty collection names", async () => {
|
|
236
|
+
const { service } = makeService();
|
|
237
|
+
let searchCalls = 0;
|
|
238
|
+
(service as unknown as {
|
|
239
|
+
orchestrator: {
|
|
240
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
241
|
+
};
|
|
242
|
+
}).orchestrator.searchAcrossNamespaces = async () => {
|
|
243
|
+
searchCalls += 1;
|
|
244
|
+
return [];
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
await assert.rejects(
|
|
248
|
+
() =>
|
|
249
|
+
service.memorySearch({
|
|
250
|
+
query: "deployment notes",
|
|
251
|
+
collection: " ",
|
|
252
|
+
principal: "reader",
|
|
253
|
+
}),
|
|
254
|
+
/collection must be a non-empty string/,
|
|
255
|
+
);
|
|
256
|
+
assert.equal(searchCalls, 0);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("memorySearch treats global collection as ACL-scoped when namespaces are enabled", async () => {
|
|
260
|
+
const { service } = makeService();
|
|
261
|
+
let globalSearchCalls = 0;
|
|
262
|
+
let searchParams: unknown;
|
|
263
|
+
(service as unknown as {
|
|
264
|
+
orchestrator: {
|
|
265
|
+
qmd: {
|
|
266
|
+
searchGlobal(query: string, maxResults?: number): Promise<unknown[]>;
|
|
267
|
+
};
|
|
268
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
269
|
+
};
|
|
270
|
+
}).orchestrator.qmd.searchGlobal = async () => {
|
|
271
|
+
globalSearchCalls += 1;
|
|
272
|
+
return [];
|
|
273
|
+
};
|
|
274
|
+
(service as unknown as {
|
|
275
|
+
orchestrator: {
|
|
276
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
277
|
+
};
|
|
278
|
+
}).orchestrator.searchAcrossNamespaces = async (params) => {
|
|
279
|
+
searchParams = params;
|
|
280
|
+
return [];
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
await service.memorySearch({
|
|
284
|
+
query: "runbook",
|
|
285
|
+
collection: "global",
|
|
286
|
+
principal: "reader",
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
assert.equal(globalSearchCalls, 0);
|
|
290
|
+
assert.deepEqual(searchParams, {
|
|
291
|
+
query: "runbook",
|
|
292
|
+
namespaces: ["default", "shared"],
|
|
293
|
+
maxResults: undefined,
|
|
294
|
+
mode: "search",
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("memorySearch accepts a namespace-scoped collection for the requested namespace", async () => {
|
|
299
|
+
const { service } = makeService();
|
|
300
|
+
let searchParams: unknown;
|
|
301
|
+
(service as unknown as {
|
|
302
|
+
orchestrator: {
|
|
303
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
304
|
+
};
|
|
305
|
+
}).orchestrator.searchAcrossNamespaces = async (params) => {
|
|
306
|
+
searchParams = params;
|
|
307
|
+
return [];
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
await service.memorySearch({
|
|
311
|
+
query: "release note",
|
|
312
|
+
namespace: "team",
|
|
313
|
+
collection: namespaceCollectionName("test-memory", "team", {
|
|
314
|
+
defaultNamespace: "default",
|
|
315
|
+
useLegacyDefaultCollection: false,
|
|
316
|
+
}),
|
|
317
|
+
principal: "reader",
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
assert.deepEqual(searchParams, {
|
|
321
|
+
query: "release note",
|
|
322
|
+
namespaces: ["team"],
|
|
323
|
+
maxResults: undefined,
|
|
324
|
+
mode: "search",
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test("memorySearch accepts a readable namespace-scoped collection without duplicate namespace", async () => {
|
|
329
|
+
const { service } = makeService();
|
|
330
|
+
let searchParams: unknown;
|
|
331
|
+
(service as unknown as {
|
|
332
|
+
orchestrator: {
|
|
333
|
+
searchAcrossNamespaces(params: unknown): Promise<unknown[]>;
|
|
334
|
+
};
|
|
335
|
+
}).orchestrator.searchAcrossNamespaces = async (params) => {
|
|
336
|
+
searchParams = params;
|
|
337
|
+
return [];
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
await service.memorySearch({
|
|
341
|
+
query: "release note",
|
|
342
|
+
collection: namespaceCollectionName("test-memory", "team", {
|
|
343
|
+
defaultNamespace: "default",
|
|
344
|
+
useLegacyDefaultCollection: false,
|
|
345
|
+
}),
|
|
346
|
+
principal: "reader",
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
assert.deepEqual(searchParams, {
|
|
350
|
+
query: "release note",
|
|
351
|
+
namespaces: ["team"],
|
|
352
|
+
maxResults: undefined,
|
|
353
|
+
mode: "search",
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("memorySearch rejects arbitrary custom collections when namespaces are enabled", async () => {
|
|
358
|
+
const { service } = makeService();
|
|
359
|
+
let qmdSearchCalls = 0;
|
|
360
|
+
(service as unknown as {
|
|
361
|
+
orchestrator: {
|
|
362
|
+
qmd: {
|
|
363
|
+
search(query: string, collection?: string, maxResults?: number): Promise<unknown[]>;
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
}).orchestrator.qmd.search = async () => {
|
|
367
|
+
qmdSearchCalls += 1;
|
|
368
|
+
return [];
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
await assert.rejects(
|
|
372
|
+
() =>
|
|
373
|
+
service.memorySearch({
|
|
374
|
+
query: "deployment notes",
|
|
375
|
+
collection: "custom-collection",
|
|
376
|
+
principal: "reader",
|
|
377
|
+
}),
|
|
378
|
+
/collection is not namespace-scoped for the requested principal/,
|
|
379
|
+
);
|
|
380
|
+
assert.equal(qmdSearchCalls, 0);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test("memorySearch honors custom collections when namespaces are disabled", async () => {
|
|
384
|
+
const { service } = makeService();
|
|
385
|
+
(service as unknown as { orchestrator: { config: PluginConfig } }).orchestrator.config = {
|
|
386
|
+
...makeConfig(),
|
|
387
|
+
namespacesEnabled: false,
|
|
388
|
+
};
|
|
389
|
+
let qmdSearchArgs: unknown[] | undefined;
|
|
390
|
+
(service as unknown as {
|
|
391
|
+
orchestrator: {
|
|
392
|
+
qmd: {
|
|
393
|
+
search(query: string, collection?: string, maxResults?: number): Promise<unknown[]>;
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
}).orchestrator.qmd.search = async (...args) => {
|
|
397
|
+
qmdSearchArgs = args;
|
|
398
|
+
return [{ path: "facts/a.md", score: 0.5, snippet: "matched" }];
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const result = await service.memorySearch({
|
|
402
|
+
query: "deployment notes",
|
|
403
|
+
collection: "custom-collection",
|
|
404
|
+
maxResults: 4,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
assert.deepEqual(qmdSearchArgs, ["deployment notes", "custom-collection", 4]);
|
|
408
|
+
assert.equal(result.count, 1);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test("memorySearch rejects unsupported namespaces when namespaces are disabled", async () => {
|
|
412
|
+
const { service } = makeService();
|
|
413
|
+
(service as unknown as { orchestrator: { config: PluginConfig } }).orchestrator.config = {
|
|
414
|
+
...makeConfig(),
|
|
415
|
+
namespacesEnabled: false,
|
|
416
|
+
};
|
|
417
|
+
let qmdSearchCalls = 0;
|
|
418
|
+
(service as unknown as {
|
|
419
|
+
orchestrator: {
|
|
420
|
+
qmd: {
|
|
421
|
+
search(query: string, collection?: string, maxResults?: number): Promise<unknown[]>;
|
|
422
|
+
};
|
|
423
|
+
};
|
|
424
|
+
}).orchestrator.qmd.search = async () => {
|
|
425
|
+
qmdSearchCalls += 1;
|
|
426
|
+
return [];
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
await assert.rejects(
|
|
430
|
+
() =>
|
|
431
|
+
service.memorySearch({
|
|
432
|
+
query: "deployment notes",
|
|
433
|
+
namespace: "team",
|
|
434
|
+
collection: "custom-collection",
|
|
435
|
+
}),
|
|
436
|
+
/unsupported namespace: team/,
|
|
437
|
+
);
|
|
438
|
+
assert.equal(qmdSearchCalls, 0);
|
|
439
|
+
});
|
|
440
|
+
|
|
129
441
|
test("offlineSyncFiles reports invalid requested paths as input errors", async () => {
|
|
130
442
|
const { service } = makeService();
|
|
131
443
|
(service as unknown as {
|