@kinqs/brainrouter-mcp-server 0.3.4 → 0.3.6

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.
Files changed (65) hide show
  1. package/.env.example +121 -71
  2. package/README.md +88 -15
  3. package/dist/__tests__/cognitive-extractor.test.js +112 -0
  4. package/dist/__tests__/crypto.test.js +8 -1
  5. package/dist/__tests__/working-memory.test.js +67 -0
  6. package/dist/env-loader.js +47 -0
  7. package/dist/index.d.ts +2 -1
  8. package/dist/index.js +12 -1
  9. package/dist/init.d.ts +1 -0
  10. package/dist/init.js +64 -0
  11. package/dist/memory/engine.js +21 -1
  12. package/dist/memory/pipeline/cognitive-extractor.js +19 -1
  13. package/dist/memory/recall.d.ts +3 -1
  14. package/dist/memory/recall.js +48 -3
  15. package/dist/memory/store/relevance-judge.d.ts +51 -0
  16. package/dist/memory/store/relevance-judge.js +196 -0
  17. package/dist/memory/working/canvas.js +11 -0
  18. package/package.json +2 -2
  19. package/dist/memory/config.d.ts +0 -2
  20. package/dist/memory/config.js +0 -3
  21. package/dist/memory/pipeline/l1-contradiction.d.ts +0 -7
  22. package/dist/memory/pipeline/l1-contradiction.js +0 -66
  23. package/dist/memory/pipeline/l1-dedup.d.ts +0 -23
  24. package/dist/memory/pipeline/l1-dedup.js +0 -39
  25. package/dist/memory/pipeline/l1-extractor.d.ts +0 -21
  26. package/dist/memory/pipeline/l1-extractor.js +0 -180
  27. package/dist/memory/pipeline/l2-direction-shift.d.ts +0 -10
  28. package/dist/memory/pipeline/l2-direction-shift.js +0 -27
  29. package/dist/memory/pipeline/l2-scene.d.ts +0 -15
  30. package/dist/memory/pipeline/l2-scene.js +0 -140
  31. package/dist/memory/pipeline/l3-distiller.d.ts +0 -15
  32. package/dist/memory/pipeline/l3-distiller.js +0 -40
  33. package/dist/memory/pipeline/task-queue.d.ts +0 -54
  34. package/dist/memory/pipeline/task-queue.js +0 -117
  35. package/dist/memory/prompts/graph-extraction-batch.d.ts +0 -14
  36. package/dist/memory/prompts/graph-extraction-batch.js +0 -54
  37. package/dist/memory/prompts/l1-contradiction-batch.d.ts +0 -16
  38. package/dist/memory/prompts/l1-contradiction-batch.js +0 -47
  39. package/dist/memory/prompts/l1-contradiction.d.ts +0 -1
  40. package/dist/memory/prompts/l1-contradiction.js +0 -25
  41. package/dist/memory/prompts/l1-extraction.d.ts +0 -10
  42. package/dist/memory/prompts/l1-extraction.js +0 -114
  43. package/dist/memory/prompts/l2-direction-shift.d.ts +0 -5
  44. package/dist/memory/prompts/l2-direction-shift.js +0 -32
  45. package/dist/memory/prompts/l2-scene-cluster.d.ts +0 -2
  46. package/dist/memory/prompts/l2-scene-cluster.js +0 -33
  47. package/dist/memory/prompts/l2-scene.d.ts +0 -7
  48. package/dist/memory/prompts/l2-scene.js +0 -40
  49. package/dist/memory/prompts/l3-persona.d.ts +0 -6
  50. package/dist/memory/prompts/l3-persona.js +0 -60
  51. package/dist/memory/store/types.d.ts +0 -101
  52. package/dist/memory/types.d.ts +0 -207
  53. package/dist/memory/types.js +0 -7
  54. package/dist/memory/validation.d.ts +0 -441
  55. package/dist/memory/validation.js +0 -129
  56. package/dist/tools/agent_memory_tools.d.ts +0 -485
  57. package/dist/tools/agent_memory_tools.js +0 -793
  58. package/dist/tools/get_doc.d.ts +0 -21
  59. package/dist/tools/get_doc.js +0 -24
  60. package/dist/tools/list_docs.d.ts +0 -15
  61. package/dist/tools/list_docs.js +0 -16
  62. package/dist/tools/update_doc.d.ts +0 -24
  63. package/dist/tools/update_doc.js +0 -35
  64. /package/dist/__tests__/{agent_mode.test.d.ts → cognitive-extractor.test.d.ts} +0 -0
  65. /package/dist/{memory/store/types.js → env-loader.d.ts} +0 -0
@@ -1,441 +0,0 @@
1
- import { z } from "zod";
2
- import type { SqliteMemoryStore } from "./store/sqlite.js";
3
- export declare const MemoryTypeSchema: z.ZodEnum<["persona", "episodic", "instruction", "skill_context"]>;
4
- export declare const L1MemoryItemSchema: z.ZodObject<{
5
- content: z.ZodString;
6
- type: z.ZodEnum<["persona", "episodic", "instruction", "skill_context"]>;
7
- priority: z.ZodDefault<z.ZodNumber>;
8
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
9
- metadata: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
10
- }, "strip", z.ZodTypeAny, {
11
- type: "persona" | "episodic" | "instruction" | "skill_context";
12
- content: string;
13
- skillTag: string;
14
- priority: number;
15
- metadata: Record<string, any>;
16
- }, {
17
- type: "persona" | "episodic" | "instruction" | "skill_context";
18
- content: string;
19
- skillTag?: string | undefined;
20
- priority?: number | undefined;
21
- metadata?: Record<string, any> | undefined;
22
- }>;
23
- export declare const L1SceneGroupSchema: z.ZodObject<{
24
- sceneName: z.ZodString;
25
- memories: z.ZodArray<z.ZodObject<{
26
- content: z.ZodString;
27
- type: z.ZodEnum<["persona", "episodic", "instruction", "skill_context"]>;
28
- priority: z.ZodDefault<z.ZodNumber>;
29
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
30
- metadata: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
31
- }, "strip", z.ZodTypeAny, {
32
- type: "persona" | "episodic" | "instruction" | "skill_context";
33
- content: string;
34
- skillTag: string;
35
- priority: number;
36
- metadata: Record<string, any>;
37
- }, {
38
- type: "persona" | "episodic" | "instruction" | "skill_context";
39
- content: string;
40
- skillTag?: string | undefined;
41
- priority?: number | undefined;
42
- metadata?: Record<string, any> | undefined;
43
- }>, "many">;
44
- }, "strip", z.ZodTypeAny, {
45
- sceneName: string;
46
- memories: {
47
- type: "persona" | "episodic" | "instruction" | "skill_context";
48
- content: string;
49
- skillTag: string;
50
- priority: number;
51
- metadata: Record<string, any>;
52
- }[];
53
- }, {
54
- sceneName: string;
55
- memories: {
56
- type: "persona" | "episodic" | "instruction" | "skill_context";
57
- content: string;
58
- skillTag?: string | undefined;
59
- priority?: number | undefined;
60
- metadata?: Record<string, any> | undefined;
61
- }[];
62
- }>;
63
- export declare const L1CommitPayloadSchema: z.ZodObject<{
64
- userId: z.ZodString;
65
- sessionKey: z.ZodString;
66
- sessionId: z.ZodDefault<z.ZodOptional<z.ZodString>>;
67
- sourceL0Ids: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
68
- scenes: z.ZodArray<z.ZodObject<{
69
- sceneName: z.ZodString;
70
- memories: z.ZodArray<z.ZodObject<{
71
- content: z.ZodString;
72
- type: z.ZodEnum<["persona", "episodic", "instruction", "skill_context"]>;
73
- priority: z.ZodDefault<z.ZodNumber>;
74
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
75
- metadata: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
76
- }, "strip", z.ZodTypeAny, {
77
- type: "persona" | "episodic" | "instruction" | "skill_context";
78
- content: string;
79
- skillTag: string;
80
- priority: number;
81
- metadata: Record<string, any>;
82
- }, {
83
- type: "persona" | "episodic" | "instruction" | "skill_context";
84
- content: string;
85
- skillTag?: string | undefined;
86
- priority?: number | undefined;
87
- metadata?: Record<string, any> | undefined;
88
- }>, "many">;
89
- }, "strip", z.ZodTypeAny, {
90
- sceneName: string;
91
- memories: {
92
- type: "persona" | "episodic" | "instruction" | "skill_context";
93
- content: string;
94
- skillTag: string;
95
- priority: number;
96
- metadata: Record<string, any>;
97
- }[];
98
- }, {
99
- sceneName: string;
100
- memories: {
101
- type: "persona" | "episodic" | "instruction" | "skill_context";
102
- content: string;
103
- skillTag?: string | undefined;
104
- priority?: number | undefined;
105
- metadata?: Record<string, any> | undefined;
106
- }[];
107
- }>, "many">;
108
- }, "strip", z.ZodTypeAny, {
109
- userId: string;
110
- sessionKey: string;
111
- sessionId: string;
112
- sourceL0Ids: string[];
113
- scenes: {
114
- sceneName: string;
115
- memories: {
116
- type: "persona" | "episodic" | "instruction" | "skill_context";
117
- content: string;
118
- skillTag: string;
119
- priority: number;
120
- metadata: Record<string, any>;
121
- }[];
122
- }[];
123
- }, {
124
- userId: string;
125
- sessionKey: string;
126
- scenes: {
127
- sceneName: string;
128
- memories: {
129
- type: "persona" | "episodic" | "instruction" | "skill_context";
130
- content: string;
131
- skillTag?: string | undefined;
132
- priority?: number | undefined;
133
- metadata?: Record<string, any> | undefined;
134
- }[];
135
- }[];
136
- sessionId?: string | undefined;
137
- sourceL0Ids?: string[] | undefined;
138
- }>;
139
- export declare const ContradictionDecisionItemSchema: z.ZodObject<{
140
- newRecordId: z.ZodString;
141
- existingRecordId: z.ZodString;
142
- decision: z.ZodEnum<["no_conflict", "temporal_update", "genuine_conflict"]>;
143
- reason: z.ZodOptional<z.ZodString>;
144
- confidence: z.ZodDefault<z.ZodNumber>;
145
- }, "strip", z.ZodTypeAny, {
146
- confidence: number;
147
- newRecordId: string;
148
- existingRecordId: string;
149
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
150
- reason?: string | undefined;
151
- }, {
152
- newRecordId: string;
153
- existingRecordId: string;
154
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
155
- confidence?: number | undefined;
156
- reason?: string | undefined;
157
- }>;
158
- export declare const ContradictionDecisionCommitSchema: z.ZodObject<{
159
- userId: z.ZodString;
160
- decisions: z.ZodArray<z.ZodObject<{
161
- newRecordId: z.ZodString;
162
- existingRecordId: z.ZodString;
163
- decision: z.ZodEnum<["no_conflict", "temporal_update", "genuine_conflict"]>;
164
- reason: z.ZodOptional<z.ZodString>;
165
- confidence: z.ZodDefault<z.ZodNumber>;
166
- }, "strip", z.ZodTypeAny, {
167
- confidence: number;
168
- newRecordId: string;
169
- existingRecordId: string;
170
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
171
- reason?: string | undefined;
172
- }, {
173
- newRecordId: string;
174
- existingRecordId: string;
175
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
176
- confidence?: number | undefined;
177
- reason?: string | undefined;
178
- }>, "many">;
179
- }, "strip", z.ZodTypeAny, {
180
- userId: string;
181
- decisions: {
182
- confidence: number;
183
- newRecordId: string;
184
- existingRecordId: string;
185
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
186
- reason?: string | undefined;
187
- }[];
188
- }, {
189
- userId: string;
190
- decisions: {
191
- newRecordId: string;
192
- existingRecordId: string;
193
- decision: "temporal_update" | "genuine_conflict" | "no_conflict";
194
- confidence?: number | undefined;
195
- reason?: string | undefined;
196
- }[];
197
- }>;
198
- export declare const GraphEntityItemSchema: z.ZodObject<{
199
- entity: z.ZodString;
200
- type: z.ZodDefault<z.ZodString>;
201
- confidence: z.ZodDefault<z.ZodNumber>;
202
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
203
- sourceRecordId: z.ZodOptional<z.ZodString>;
204
- }, "strip", z.ZodTypeAny, {
205
- type: string;
206
- entity: string;
207
- skillTag: string;
208
- confidence: number;
209
- sourceRecordId?: string | undefined;
210
- }, {
211
- entity: string;
212
- type?: string | undefined;
213
- skillTag?: string | undefined;
214
- confidence?: number | undefined;
215
- sourceRecordId?: string | undefined;
216
- }>;
217
- export declare const GraphRelationItemSchema: z.ZodObject<{
218
- from: z.ZodString;
219
- to: z.ZodString;
220
- relation: z.ZodDefault<z.ZodString>;
221
- confidence: z.ZodDefault<z.ZodNumber>;
222
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
223
- sourceRecordId: z.ZodOptional<z.ZodString>;
224
- }, "strip", z.ZodTypeAny, {
225
- skillTag: string;
226
- confidence: number;
227
- from: string;
228
- to: string;
229
- relation: string;
230
- sourceRecordId?: string | undefined;
231
- }, {
232
- from: string;
233
- to: string;
234
- skillTag?: string | undefined;
235
- confidence?: number | undefined;
236
- sourceRecordId?: string | undefined;
237
- relation?: string | undefined;
238
- }>;
239
- export declare const GraphCommitSchema: z.ZodObject<{
240
- userId: z.ZodString;
241
- sourceRecordId: z.ZodOptional<z.ZodString>;
242
- entities: z.ZodDefault<z.ZodArray<z.ZodObject<{
243
- entity: z.ZodString;
244
- type: z.ZodDefault<z.ZodString>;
245
- confidence: z.ZodDefault<z.ZodNumber>;
246
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
247
- sourceRecordId: z.ZodOptional<z.ZodString>;
248
- }, "strip", z.ZodTypeAny, {
249
- type: string;
250
- entity: string;
251
- skillTag: string;
252
- confidence: number;
253
- sourceRecordId?: string | undefined;
254
- }, {
255
- entity: string;
256
- type?: string | undefined;
257
- skillTag?: string | undefined;
258
- confidence?: number | undefined;
259
- sourceRecordId?: string | undefined;
260
- }>, "many">>;
261
- relations: z.ZodDefault<z.ZodArray<z.ZodObject<{
262
- from: z.ZodString;
263
- to: z.ZodString;
264
- relation: z.ZodDefault<z.ZodString>;
265
- confidence: z.ZodDefault<z.ZodNumber>;
266
- skillTag: z.ZodDefault<z.ZodOptional<z.ZodString>>;
267
- sourceRecordId: z.ZodOptional<z.ZodString>;
268
- }, "strip", z.ZodTypeAny, {
269
- skillTag: string;
270
- confidence: number;
271
- from: string;
272
- to: string;
273
- relation: string;
274
- sourceRecordId?: string | undefined;
275
- }, {
276
- from: string;
277
- to: string;
278
- skillTag?: string | undefined;
279
- confidence?: number | undefined;
280
- sourceRecordId?: string | undefined;
281
- relation?: string | undefined;
282
- }>, "many">>;
283
- }, "strip", z.ZodTypeAny, {
284
- userId: string;
285
- entities: {
286
- type: string;
287
- entity: string;
288
- skillTag: string;
289
- confidence: number;
290
- sourceRecordId?: string | undefined;
291
- }[];
292
- relations: {
293
- skillTag: string;
294
- confidence: number;
295
- from: string;
296
- to: string;
297
- relation: string;
298
- sourceRecordId?: string | undefined;
299
- }[];
300
- sourceRecordId?: string | undefined;
301
- }, {
302
- userId: string;
303
- sourceRecordId?: string | undefined;
304
- entities?: {
305
- entity: string;
306
- type?: string | undefined;
307
- skillTag?: string | undefined;
308
- confidence?: number | undefined;
309
- sourceRecordId?: string | undefined;
310
- }[] | undefined;
311
- relations?: {
312
- from: string;
313
- to: string;
314
- skillTag?: string | undefined;
315
- confidence?: number | undefined;
316
- sourceRecordId?: string | undefined;
317
- relation?: string | undefined;
318
- }[] | undefined;
319
- }>;
320
- export declare const L2RenameItemSchema: z.ZodObject<{
321
- oldName: z.ZodString;
322
- newName: z.ZodString;
323
- }, "strip", z.ZodTypeAny, {
324
- oldName: string;
325
- newName: string;
326
- }, {
327
- oldName: string;
328
- newName: string;
329
- }>;
330
- export declare const L2SceneItemSchema: z.ZodObject<{
331
- sceneName: z.ZodString;
332
- summaryMd: z.ZodString;
333
- heatScore: z.ZodOptional<z.ZodNumber>;
334
- }, "strip", z.ZodTypeAny, {
335
- sceneName: string;
336
- summaryMd: string;
337
- heatScore?: number | undefined;
338
- }, {
339
- sceneName: string;
340
- summaryMd: string;
341
- heatScore?: number | undefined;
342
- }>;
343
- export declare const L2MergeItemSchema: z.ZodObject<{
344
- sceneIds: z.ZodArray<z.ZodString, "many">;
345
- mergedSummaryMd: z.ZodString;
346
- }, "strip", z.ZodTypeAny, {
347
- sceneIds: string[];
348
- mergedSummaryMd: string;
349
- }, {
350
- sceneIds: string[];
351
- mergedSummaryMd: string;
352
- }>;
353
- export declare const L2CommitSchema: z.ZodObject<{
354
- userId: z.ZodString;
355
- renames: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
356
- oldName: z.ZodString;
357
- newName: z.ZodString;
358
- }, "strip", z.ZodTypeAny, {
359
- oldName: string;
360
- newName: string;
361
- }, {
362
- oldName: string;
363
- newName: string;
364
- }>, "many">>>;
365
- scenes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
366
- sceneName: z.ZodString;
367
- summaryMd: z.ZodString;
368
- heatScore: z.ZodOptional<z.ZodNumber>;
369
- }, "strip", z.ZodTypeAny, {
370
- sceneName: string;
371
- summaryMd: string;
372
- heatScore?: number | undefined;
373
- }, {
374
- sceneName: string;
375
- summaryMd: string;
376
- heatScore?: number | undefined;
377
- }>, "many">>>;
378
- merges: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
379
- sceneIds: z.ZodArray<z.ZodString, "many">;
380
- mergedSummaryMd: z.ZodString;
381
- }, "strip", z.ZodTypeAny, {
382
- sceneIds: string[];
383
- mergedSummaryMd: string;
384
- }, {
385
- sceneIds: string[];
386
- mergedSummaryMd: string;
387
- }>, "many">>>;
388
- }, "strip", z.ZodTypeAny, {
389
- userId: string;
390
- scenes: {
391
- sceneName: string;
392
- summaryMd: string;
393
- heatScore?: number | undefined;
394
- }[];
395
- renames: {
396
- oldName: string;
397
- newName: string;
398
- }[];
399
- merges: {
400
- sceneIds: string[];
401
- mergedSummaryMd: string;
402
- }[];
403
- }, {
404
- userId: string;
405
- scenes?: {
406
- sceneName: string;
407
- summaryMd: string;
408
- heatScore?: number | undefined;
409
- }[] | undefined;
410
- renames?: {
411
- oldName: string;
412
- newName: string;
413
- }[] | undefined;
414
- merges?: {
415
- sceneIds: string[];
416
- mergedSummaryMd: string;
417
- }[] | undefined;
418
- }>;
419
- export declare const L3CommitSchema: z.ZodObject<{
420
- userId: z.ZodString;
421
- personaMd: z.ZodString;
422
- }, "strip", z.ZodTypeAny, {
423
- userId: string;
424
- personaMd: string;
425
- }, {
426
- userId: string;
427
- personaMd: string;
428
- }>;
429
- export declare function normalizeSceneName(name: string): string;
430
- export declare function normalizeEntityName(name: string): string;
431
- export declare function normalizeSkillTag(tag: string): string;
432
- export declare function normalizeMemoryContent(content: string): string;
433
- /**
434
- * Ensures multi-tenant isolation by checking that all referenced L1 record IDs
435
- * belong strictly to the provided userId. Throws an error if ownership is violated.
436
- */
437
- export declare function validateL1RecordOwnership(store: SqliteMemoryStore, userId: string, recordIds: string[]): void;
438
- /**
439
- * Checks if a specific L0 record belongs to the user.
440
- */
441
- export declare function validateL0RecordOwnership(store: SqliteMemoryStore, userId: string, recordIds: string[]): void;
@@ -1,129 +0,0 @@
1
- import { z } from "zod";
2
- // ============================
3
- // Shared Zod Schemas
4
- // ============================
5
- export const MemoryTypeSchema = z.enum(["persona", "episodic", "instruction", "skill_context"]);
6
- export const L1MemoryItemSchema = z.object({
7
- content: z.string().min(1, "Memory content cannot be empty"),
8
- type: MemoryTypeSchema,
9
- priority: z.number().int().min(0).max(100).default(50),
10
- skillTag: z.string().optional().default(""),
11
- metadata: z.record(z.any()).optional().default({}),
12
- });
13
- export const L1SceneGroupSchema = z.object({
14
- sceneName: z.string().min(1, "Scene name cannot be empty"),
15
- memories: z.array(L1MemoryItemSchema).min(1, "Scene must contain at least one memory"),
16
- });
17
- export const L1CommitPayloadSchema = z.object({
18
- userId: z.string().min(1, "userId is required"),
19
- sessionKey: z.string().min(1, "sessionKey is required"),
20
- sessionId: z.string().optional().default(""),
21
- sourceL0Ids: z.array(z.string()).optional().default([]),
22
- scenes: z.array(L1SceneGroupSchema).min(1, "At least one scene group is required"),
23
- });
24
- export const ContradictionDecisionItemSchema = z.object({
25
- newRecordId: z.string().min(1, "newRecordId is required"),
26
- existingRecordId: z.string().min(1, "existingRecordId is required"),
27
- decision: z.enum(["no_conflict", "temporal_update", "genuine_conflict"]),
28
- reason: z.string().optional(),
29
- confidence: z.number().min(0).max(1).default(1.0),
30
- });
31
- export const ContradictionDecisionCommitSchema = z.object({
32
- userId: z.string().min(1, "userId is required"),
33
- decisions: z.array(ContradictionDecisionItemSchema).min(1, "At least one decision is required"),
34
- });
35
- export const GraphEntityItemSchema = z.object({
36
- entity: z.string().min(1, "Entity name cannot be empty"),
37
- type: z.string().default("concept"),
38
- confidence: z.number().min(0).max(1).default(1.0),
39
- skillTag: z.string().optional().default(""),
40
- sourceRecordId: z.string().optional(),
41
- });
42
- export const GraphRelationItemSchema = z.object({
43
- from: z.string().min(1, "from entity name is required"),
44
- to: z.string().min(1, "to entity name is required"),
45
- relation: z.string().default("relates_to"),
46
- confidence: z.number().min(0).max(1).default(1.0),
47
- skillTag: z.string().optional().default(""),
48
- sourceRecordId: z.string().optional(),
49
- });
50
- export const GraphCommitSchema = z.object({
51
- userId: z.string().min(1, "userId is required"),
52
- sourceRecordId: z.string().optional(),
53
- entities: z.array(GraphEntityItemSchema).default([]),
54
- relations: z.array(GraphRelationItemSchema).default([]),
55
- });
56
- export const L2RenameItemSchema = z.object({
57
- oldName: z.string().min(1),
58
- newName: z.string().min(1),
59
- });
60
- export const L2SceneItemSchema = z.object({
61
- sceneName: z.string().min(1),
62
- summaryMd: z.string().min(1),
63
- heatScore: z.number().min(0).max(100).optional(),
64
- });
65
- export const L2MergeItemSchema = z.object({
66
- sceneIds: z.array(z.string()).min(2, "At least two scene IDs are required to merge"),
67
- mergedSummaryMd: z.string().min(1),
68
- });
69
- export const L2CommitSchema = z.object({
70
- userId: z.string().min(1, "userId is required"),
71
- renames: z.array(L2RenameItemSchema).optional().default([]),
72
- scenes: z.array(L2SceneItemSchema).optional().default([]),
73
- merges: z.array(L2MergeItemSchema).optional().default([]),
74
- });
75
- export const L3CommitSchema = z.object({
76
- userId: z.string().min(1, "userId is required"),
77
- personaMd: z.string().min(1, "personaMd cannot be empty"),
78
- });
79
- // ============================
80
- // Normalization Helpers
81
- // ============================
82
- export function normalizeSceneName(name) {
83
- const trimmed = name.trim();
84
- return trimmed === "" ? "general" : trimmed;
85
- }
86
- export function normalizeEntityName(name) {
87
- const trimmed = name.trim();
88
- return trimmed === "" ? "unknown" : trimmed;
89
- }
90
- export function normalizeSkillTag(tag) {
91
- return tag.trim().toLowerCase();
92
- }
93
- export function normalizeMemoryContent(content) {
94
- return content.trim();
95
- }
96
- // ============================
97
- // Ownership & Tenant Isolation Validation
98
- // ============================
99
- /**
100
- * Ensures multi-tenant isolation by checking that all referenced L1 record IDs
101
- * belong strictly to the provided userId. Throws an error if ownership is violated.
102
- */
103
- export function validateL1RecordOwnership(store, userId, recordIds) {
104
- if (recordIds.length === 0)
105
- return;
106
- const placeholders = recordIds.map(() => "?").join(",");
107
- const stmt = store.db.prepare(`SELECT record_id, user_id FROM l1_records WHERE record_id IN (${placeholders})`);
108
- const rows = stmt.all(...recordIds);
109
- for (const row of rows) {
110
- if (row.user_id !== userId) {
111
- throw new Error(`[Tenant Isolation Violation] Record ${row.record_id} is owned by user ${row.user_id}, but requested by ${userId}`);
112
- }
113
- }
114
- }
115
- /**
116
- * Checks if a specific L0 record belongs to the user.
117
- */
118
- export function validateL0RecordOwnership(store, userId, recordIds) {
119
- if (recordIds.length === 0)
120
- return;
121
- const placeholders = recordIds.map(() => "?").join(",");
122
- const stmt = store.db.prepare(`SELECT record_id, user_id FROM l0_conversations WHERE record_id IN (${placeholders})`);
123
- const rows = stmt.all(...recordIds);
124
- for (const row of rows) {
125
- if (row.user_id !== userId) {
126
- throw new Error(`[Tenant Isolation Violation] L0 Message ${row.record_id} belongs to user ${row.user_id}, but requested by ${userId}`);
127
- }
128
- }
129
- }