@carlonicora/nestjs-neo4jsonapi 1.104.0 → 1.106.0

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 (128) hide show
  1. package/dist/agents/graph.creator/services/graph.creator.service.d.ts +1 -1
  2. package/dist/agents/graph.creator/services/graph.creator.service.d.ts.map +1 -1
  3. package/dist/agents/graph.creator/services/graph.creator.service.js +14 -0
  4. package/dist/agents/graph.creator/services/graph.creator.service.js.map +1 -1
  5. package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
  6. package/dist/bootstrap/app.module.factory.js +1 -0
  7. package/dist/bootstrap/app.module.factory.js.map +1 -1
  8. package/dist/bootstrap/bootstrap.options.d.ts +3 -0
  9. package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
  10. package/dist/common/interfaces/agents/graph.creator.interface.d.ts +4 -0
  11. package/dist/common/interfaces/agents/graph.creator.interface.d.ts.map +1 -1
  12. package/dist/common/repositories/ai-source-query.provider.d.ts +19 -0
  13. package/dist/common/repositories/ai-source-query.provider.d.ts.map +1 -0
  14. package/dist/common/repositories/ai-source-query.provider.js +5 -0
  15. package/dist/common/repositories/ai-source-query.provider.js.map +1 -0
  16. package/dist/common/repositories/default.ai-source-query.provider.d.ts +19 -0
  17. package/dist/common/repositories/default.ai-source-query.provider.d.ts.map +1 -0
  18. package/dist/common/repositories/default.ai-source-query.provider.js +36 -0
  19. package/dist/common/repositories/default.ai-source-query.provider.js.map +1 -0
  20. package/dist/common/repositories/index.d.ts +2 -0
  21. package/dist/common/repositories/index.d.ts.map +1 -1
  22. package/dist/common/repositories/index.js +2 -0
  23. package/dist/common/repositories/index.js.map +1 -1
  24. package/dist/common/types/data.limits.d.ts +2 -2
  25. package/dist/common/types/data.limits.d.ts.map +1 -1
  26. package/dist/config/base.config.d.ts.map +1 -1
  27. package/dist/config/base.config.js +5 -0
  28. package/dist/config/base.config.js.map +1 -1
  29. package/dist/config/interfaces/base.config.interface.d.ts +4 -0
  30. package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
  31. package/dist/config/interfaces/config.chunker.interface.d.ts +10 -0
  32. package/dist/config/interfaces/config.chunker.interface.d.ts.map +1 -0
  33. package/dist/config/interfaces/config.chunker.interface.js +3 -0
  34. package/dist/config/interfaces/config.chunker.interface.js.map +1 -0
  35. package/dist/config/interfaces/config.embedding.context.interface.d.ts +18 -0
  36. package/dist/config/interfaces/config.embedding.context.interface.d.ts.map +1 -0
  37. package/dist/config/interfaces/config.embedding.context.interface.js +3 -0
  38. package/dist/config/interfaces/config.embedding.context.interface.js.map +1 -0
  39. package/dist/config/interfaces/index.d.ts +2 -0
  40. package/dist/config/interfaces/index.d.ts.map +1 -1
  41. package/dist/config/interfaces/index.js +2 -0
  42. package/dist/config/interfaces/index.js.map +1 -1
  43. package/dist/core/core.module.d.ts +4 -0
  44. package/dist/core/core.module.d.ts.map +1 -1
  45. package/dist/core/core.module.js +7 -2
  46. package/dist/core/core.module.js.map +1 -1
  47. package/dist/core/llm/services/model.service.d.ts.map +1 -1
  48. package/dist/core/llm/services/model.service.js +18 -34
  49. package/dist/core/llm/services/model.service.js.map +1 -1
  50. package/dist/foundations/atomicfact/repositories/atomicfact.repository.d.ts +3 -8
  51. package/dist/foundations/atomicfact/repositories/atomicfact.repository.d.ts.map +1 -1
  52. package/dist/foundations/atomicfact/repositories/atomicfact.repository.js +19 -46
  53. package/dist/foundations/atomicfact/repositories/atomicfact.repository.js.map +1 -1
  54. package/dist/foundations/chunk/chunk.module.d.ts +6 -3
  55. package/dist/foundations/chunk/chunk.module.d.ts.map +1 -1
  56. package/dist/foundations/chunk/chunk.module.js +25 -5
  57. package/dist/foundations/chunk/chunk.module.js.map +1 -1
  58. package/dist/foundations/chunk/controllers/chunk.controller.d.ts +19 -1
  59. package/dist/foundations/chunk/controllers/chunk.controller.d.ts.map +1 -1
  60. package/dist/foundations/chunk/controllers/chunk.controller.js +59 -2
  61. package/dist/foundations/chunk/controllers/chunk.controller.js.map +1 -1
  62. package/dist/foundations/chunk/entities/chunk.entity.d.ts +8 -0
  63. package/dist/foundations/chunk/entities/chunk.entity.d.ts.map +1 -1
  64. package/dist/foundations/chunk/entities/chunk.entity.js +20 -0
  65. package/dist/foundations/chunk/entities/chunk.entity.js.map +1 -1
  66. package/dist/foundations/chunk/processors/chunk.embedding.processor.d.ts +21 -0
  67. package/dist/foundations/chunk/processors/chunk.embedding.processor.d.ts.map +1 -0
  68. package/dist/foundations/chunk/processors/chunk.embedding.processor.js +98 -0
  69. package/dist/foundations/chunk/processors/chunk.embedding.processor.js.map +1 -0
  70. package/dist/foundations/chunk/repositories/chunk.repository.d.ts +36 -8
  71. package/dist/foundations/chunk/repositories/chunk.repository.d.ts.map +1 -1
  72. package/dist/foundations/chunk/repositories/chunk.repository.js +184 -50
  73. package/dist/foundations/chunk/repositories/chunk.repository.js.map +1 -1
  74. package/dist/foundations/chunk/services/chunk.service.d.ts +9 -0
  75. package/dist/foundations/chunk/services/chunk.service.d.ts.map +1 -1
  76. package/dist/foundations/chunk/services/chunk.service.js +87 -0
  77. package/dist/foundations/chunk/services/chunk.service.js.map +1 -1
  78. package/dist/foundations/chunk/services/embedding-context.d.ts +19 -0
  79. package/dist/foundations/chunk/services/embedding-context.d.ts.map +1 -0
  80. package/dist/foundations/chunk/services/embedding-context.js +27 -0
  81. package/dist/foundations/chunk/services/embedding-context.js.map +1 -0
  82. package/dist/foundations/chunk/services/reciprocal-rank-fusion.d.ts +2 -0
  83. package/dist/foundations/chunk/services/reciprocal-rank-fusion.d.ts.map +1 -0
  84. package/dist/foundations/chunk/services/reciprocal-rank-fusion.js +13 -0
  85. package/dist/foundations/chunk/services/reciprocal-rank-fusion.js.map +1 -0
  86. package/dist/foundations/chunker/chunker.module.d.ts.map +1 -1
  87. package/dist/foundations/chunker/chunker.module.js +2 -0
  88. package/dist/foundations/chunker/chunker.module.js.map +1 -1
  89. package/dist/foundations/chunker/services/chunker.service.d.ts +20 -12
  90. package/dist/foundations/chunker/services/chunker.service.d.ts.map +1 -1
  91. package/dist/foundations/chunker/services/chunker.service.js +160 -157
  92. package/dist/foundations/chunker/services/chunker.service.js.map +1 -1
  93. package/dist/foundations/chunker/services/types/markdownchunking.service.d.ts +17 -0
  94. package/dist/foundations/chunker/services/types/markdownchunking.service.d.ts.map +1 -0
  95. package/dist/foundations/chunker/services/types/markdownchunking.service.js +124 -0
  96. package/dist/foundations/chunker/services/types/markdownchunking.service.js.map +1 -0
  97. package/dist/foundations/chunker/services/types/pdf.service.d.ts +4 -0
  98. package/dist/foundations/chunker/services/types/pdf.service.d.ts.map +1 -1
  99. package/dist/foundations/chunker/services/types/pdf.service.js +14 -4
  100. package/dist/foundations/chunker/services/types/pdf.service.js.map +1 -1
  101. package/dist/foundations/keyconcept/controllers/keyconcept.controller.d.ts +15 -0
  102. package/dist/foundations/keyconcept/controllers/keyconcept.controller.d.ts.map +1 -0
  103. package/dist/foundations/keyconcept/controllers/keyconcept.controller.js +56 -0
  104. package/dist/foundations/keyconcept/controllers/keyconcept.controller.js.map +1 -0
  105. package/dist/foundations/keyconcept/index.d.ts +2 -0
  106. package/dist/foundations/keyconcept/index.d.ts.map +1 -1
  107. package/dist/foundations/keyconcept/index.js +5 -1
  108. package/dist/foundations/keyconcept/index.js.map +1 -1
  109. package/dist/foundations/keyconcept/keyconcept.module.d.ts.map +1 -1
  110. package/dist/foundations/keyconcept/keyconcept.module.js +7 -2
  111. package/dist/foundations/keyconcept/keyconcept.module.js.map +1 -1
  112. package/dist/foundations/keyconcept/processors/keyconcept.embedding.processor.d.ts +22 -0
  113. package/dist/foundations/keyconcept/processors/keyconcept.embedding.processor.d.ts.map +1 -0
  114. package/dist/foundations/keyconcept/processors/keyconcept.embedding.processor.js +98 -0
  115. package/dist/foundations/keyconcept/processors/keyconcept.embedding.processor.js.map +1 -0
  116. package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts +9 -15
  117. package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts.map +1 -1
  118. package/dist/foundations/keyconcept/repositories/keyconcept.repository.js +65 -99
  119. package/dist/foundations/keyconcept/repositories/keyconcept.repository.js.map +1 -1
  120. package/dist/foundations/s3/index.d.ts +8 -2
  121. package/dist/foundations/s3/index.d.ts.map +1 -1
  122. package/dist/foundations/s3/index.js +22 -5
  123. package/dist/foundations/s3/index.js.map +1 -1
  124. package/dist/foundations/s3/services/s3.service.d.ts +11 -1
  125. package/dist/foundations/s3/services/s3.service.d.ts.map +1 -1
  126. package/dist/foundations/s3/services/s3.service.js +70 -21
  127. package/dist/foundations/s3/services/s3.service.js.map +1 -1
  128. package/package.json +1 -1
@@ -1,5 +1,9 @@
1
1
  import { Entity } from "../../../common";
2
2
  import { PolymorphicDiscriminatorData } from "../../../common/interfaces/entity.schema.interface";
3
+ export interface ChunkDate {
4
+ date: string;
5
+ description: string;
6
+ }
3
7
  export type Chunk = Entity & {
4
8
  content: string;
5
9
  position?: number;
@@ -9,6 +13,10 @@ export type Chunk = Entity & {
9
13
  aiStatus?: string;
10
14
  embedding?: number[];
11
15
  source?: unknown;
16
+ heading?: string;
17
+ /** Stored on the node as a JSON string; exposed here parsed via a computed field. */
18
+ dates?: ChunkDate[];
19
+ propagatedDates?: ChunkDate[];
12
20
  };
13
21
  export declare const ChunkDescriptor: import("../../../common").EntityDescriptor<Chunk, {
14
22
  source: {
@@ -1 +1 @@
1
- {"version":3,"file":"chunk.entity.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunk/entities/chunk.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oDAAoD,CAAC;AAKlG,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;kCAkCE,4BAA4B;;;EAUxD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,OAAO,eAAe,CAAC"}
1
+ {"version":3,"file":"chunk.entity.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunk/entities/chunk.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oDAAoD,CAAC;AAKlG,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;CAC/B,CAAC;AAgBF,eAAO,MAAM,eAAe;;;;;;;;;;kCAwCE,4BAA4B;;;EAUxD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,OAAO,eAAe,CAAC"}
@@ -5,6 +5,21 @@ const common_1 = require("../../../common");
5
5
  const registry_1 = require("../../../common/registries/registry");
6
6
  const s3_1 = require("../../s3");
7
7
  const chunk_meta_1 = require("./chunk.meta");
8
+ /** Parse a `dates` / `propagatedDates` value that is persisted as a JSON-string blob. */
9
+ const parseChunkDates = (raw) => {
10
+ if (Array.isArray(raw))
11
+ return raw;
12
+ if (typeof raw === "string" && raw.trim()) {
13
+ try {
14
+ const parsed = JSON.parse(raw);
15
+ return Array.isArray(parsed) ? parsed : [];
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ return [];
22
+ };
8
23
  exports.ChunkDescriptor = (0, common_1.defineEntity)()({
9
24
  ...chunk_meta_1.chunkMeta,
10
25
  injectServices: [s3_1.S3Service],
@@ -14,6 +29,7 @@ exports.ChunkDescriptor = (0, common_1.defineEntity)()({
14
29
  nodeId: { type: "string", meta: true },
15
30
  nodeType: { type: "string", meta: true },
16
31
  aiStatus: { type: "string" },
32
+ heading: { type: "string" },
17
33
  embedding: { type: "number[]", excludeFromJsonApi: true },
18
34
  imagePath: {
19
35
  type: "string",
@@ -27,6 +43,10 @@ exports.ChunkDescriptor = (0, common_1.defineEntity)()({
27
43
  },
28
44
  },
29
45
  },
46
+ computed: {
47
+ dates: { compute: (params) => parseChunkDates(params.data?.dates) },
48
+ propagatedDates: { compute: (params) => parseChunkDates(params.data?.propagatedDates) },
49
+ },
30
50
  relationships: {
31
51
  source: {
32
52
  model: chunk_meta_1.chunkMeta, // overridden per-row by polymorphic discriminator
@@ -1 +1 @@
1
- {"version":3,"file":"chunk.entity.js","sourceRoot":"","sources":["../../../../src/foundations/chunk/entities/chunk.entity.ts"],"names":[],"mappings":";;;AAAA,4CAAuD;AAEvD,kEAAoE;AACpE,iCAAqC;AACrC,6CAAyC;AAa5B,QAAA,eAAe,GAAG,IAAA,qBAAY,GAAS,CAAC;IACnD,GAAG,sBAAS;IAEZ,cAAc,EAAE,CAAC,cAAS,CAAC;IAE3B,MAAM,EAAE;QACN,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC3C,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;QACtC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;QACxC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,SAAS,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,IAAI,EAAE;QACzD,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gBAClC,IAAI,CAAC,IAAI,CAAC,SAAS;oBAAE,OAAO,SAAS,CAAC;gBACtC,OAAO,MAAM,QAAQ,CAAC,SAAS,CAAC,iBAAiB,CAAC;oBAChD,GAAG,EAAE,IAAI,CAAC,SAAS;oBACnB,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;iBACtB,CAAC,CAAC;YACL,CAAC;SACF;KACF;IAED,aAAa,EAAE;QACb,MAAM,EAAE;YACN,KAAK,EAAE,sBAAS,EAAE,kDAAkD;YACpE,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,WAAW;YACzB,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE;gBACX,UAAU,EAAE,EAAE;gBACd,aAAa,EAAE,CAAC,IAAkC,EAAE,EAAE;oBACpD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;wBAChC,MAAM,KAAK,GAAG,wBAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;wBAClD,IAAI,KAAK;4BAAE,OAAO,KAAK,CAAC;oBAC1B,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACzG,CAAC;aACF;SACF;KACF;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"chunk.entity.js","sourceRoot":"","sources":["../../../../src/foundations/chunk/entities/chunk.entity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { WorkerHost } from "@nestjs/bullmq";
2
+ import { ConfigService } from "@nestjs/config";
3
+ import { Job } from "bullmq";
4
+ import { ClsService } from "nestjs-cls";
5
+ import { BaseConfigInterface } from "../../../config/interfaces/base.config.interface";
6
+ import { EmbedderService } from "../../../core";
7
+ import { ChunkRepository } from "../repositories/chunk.repository";
8
+ export declare class ChunkEmbeddingProcessor extends WorkerHost {
9
+ private readonly clsService;
10
+ private readonly chunkRepository;
11
+ private readonly embedderService;
12
+ private readonly rebuildChunksJobName;
13
+ constructor(clsService: ClsService, chunkRepository: ChunkRepository, embedderService: EmbedderService, configService: ConfigService<BaseConfigInterface>);
14
+ onActive(job: Job): void;
15
+ onError(job: Job): void;
16
+ onCompleted(job: Job): void;
17
+ process(job: Job): Promise<{
18
+ processed: number;
19
+ }>;
20
+ }
21
+ //# sourceMappingURL=chunk.embedding.processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.embedding.processor.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunk/processors/chunk.embedding.processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAInE,qBACa,uBAAwB,SAAQ,UAAU;IAInD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IALlC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;gBAG3B,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,EACjD,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC;IAQnD,QAAQ,CAAC,GAAG,EAAE,GAAG;IAKjB,OAAO,CAAC,GAAG,EAAE,GAAG;IAKhB,WAAW,CAAC,GAAG,EAAE,GAAG;IAId,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CA0CxD"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ChunkEmbeddingProcessor = void 0;
13
+ const bullmq_1 = require("@nestjs/bullmq");
14
+ const config_1 = require("@nestjs/config");
15
+ const bullmq_2 = require("bullmq");
16
+ const nestjs_cls_1 = require("nestjs-cls");
17
+ const core_1 = require("../../../core");
18
+ const chunk_repository_1 = require("../repositories/chunk.repository");
19
+ const EMBEDDING_CHUNKS_QUEUE = "embedding-chunks";
20
+ let ChunkEmbeddingProcessor = class ChunkEmbeddingProcessor extends bullmq_1.WorkerHost {
21
+ constructor(clsService, chunkRepository, embedderService, configService) {
22
+ super();
23
+ this.clsService = clsService;
24
+ this.chunkRepository = chunkRepository;
25
+ this.embedderService = embedderService;
26
+ this.rebuildChunksJobName =
27
+ configService.get("jobNames", { infer: true })?.process?.rebuild_chunks ?? "embedding:rebuild_chunks";
28
+ }
29
+ onActive(job) {
30
+ console.log(`Processing ${job.name} job`);
31
+ }
32
+ onError(job) {
33
+ console.error(`Error processing ${job.name} job (ID: ${job.id}). Reason: ${job.failedReason}`);
34
+ }
35
+ onCompleted(job) {
36
+ console.log(`Completed ${job.name} job (ID: ${job.id})`);
37
+ }
38
+ async process(job) {
39
+ if (job.name !== this.rebuildChunksJobName) {
40
+ throw new Error(`Job ${job.name} not handled by ChunkEmbeddingProcessor`);
41
+ }
42
+ return await this.clsService.run(async () => {
43
+ this.clsService.set("companyId", job.data.companyId);
44
+ this.clsService.set("userId", job.data.userId);
45
+ this.clsService.set("isAutomatedJob", true);
46
+ // 1. Recreate vector index with new dimensions
47
+ await this.chunkRepository.recreateVectorIndex();
48
+ // 2. Get all chunks
49
+ const allChunks = await this.chunkRepository.findAllChunks();
50
+ const chunksWithContent = allChunks.filter((c) => c.content);
51
+ // 3. Process in batches
52
+ const batchSize = 100;
53
+ let processed = 0;
54
+ for (let i = 0; i < chunksWithContent.length; i += batchSize) {
55
+ const batch = chunksWithContent.slice(i, i + batchSize);
56
+ const texts = batch.map((c) => c.content);
57
+ const embeddings = await this.embedderService.vectoriseTextBatch(texts);
58
+ for (let j = 0; j < batch.length; j++) {
59
+ await this.chunkRepository.updateEmbedding({
60
+ chunkId: batch[j].id,
61
+ embedding: embeddings[j],
62
+ });
63
+ processed++;
64
+ }
65
+ const progress = Math.round((processed / chunksWithContent.length) * 100);
66
+ await job.updateProgress(progress);
67
+ }
68
+ return { processed };
69
+ });
70
+ }
71
+ };
72
+ exports.ChunkEmbeddingProcessor = ChunkEmbeddingProcessor;
73
+ __decorate([
74
+ (0, bullmq_1.OnWorkerEvent)("active"),
75
+ __metadata("design:type", Function),
76
+ __metadata("design:paramtypes", [bullmq_2.Job]),
77
+ __metadata("design:returntype", void 0)
78
+ ], ChunkEmbeddingProcessor.prototype, "onActive", null);
79
+ __decorate([
80
+ (0, bullmq_1.OnWorkerEvent)("failed"),
81
+ __metadata("design:type", Function),
82
+ __metadata("design:paramtypes", [bullmq_2.Job]),
83
+ __metadata("design:returntype", void 0)
84
+ ], ChunkEmbeddingProcessor.prototype, "onError", null);
85
+ __decorate([
86
+ (0, bullmq_1.OnWorkerEvent)("completed"),
87
+ __metadata("design:type", Function),
88
+ __metadata("design:paramtypes", [bullmq_2.Job]),
89
+ __metadata("design:returntype", void 0)
90
+ ], ChunkEmbeddingProcessor.prototype, "onCompleted", null);
91
+ exports.ChunkEmbeddingProcessor = ChunkEmbeddingProcessor = __decorate([
92
+ (0, bullmq_1.Processor)(EMBEDDING_CHUNKS_QUEUE, { concurrency: 1, lockDuration: 1000 * 60 * 30 }),
93
+ __metadata("design:paramtypes", [nestjs_cls_1.ClsService,
94
+ chunk_repository_1.ChunkRepository,
95
+ core_1.EmbedderService,
96
+ config_1.ConfigService])
97
+ ], ChunkEmbeddingProcessor);
98
+ //# sourceMappingURL=chunk.embedding.processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.embedding.processor.js","sourceRoot":"","sources":["../../../../src/foundations/chunk/processors/chunk.embedding.processor.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { OnModuleInit } from "@nestjs/common";
2
2
  import { ClsService } from "nestjs-cls";
3
3
  import { AiStatus } from "../../../common/enums/ai.status";
4
+ import { AiSourceQueryProvider } from "../../../common/repositories/ai-source-query.provider";
4
5
  import { DataLimits } from "../../../common/types/data.limits";
5
6
  import { EmbedderService } from "../../../core";
6
7
  import { ModelService } from "../../../core/llm/services/model.service";
@@ -13,19 +14,24 @@ export declare class ChunkRepository implements OnModuleInit {
13
14
  private readonly embedderService;
14
15
  private readonly clsService;
15
16
  private readonly securityService;
16
- constructor(neo4j: Neo4jService, modelService: ModelService, embedderService: EmbedderService, clsService: ClsService, securityService: SecurityService);
17
+ private readonly aiSourceQuery;
18
+ constructor(neo4j: Neo4jService, modelService: ModelService, embedderService: EmbedderService, clsService: ClsService, securityService: SecurityService, aiSourceQuery: AiSourceQueryProvider);
17
19
  onModuleInit(): Promise<void>;
20
+ recreateVectorIndex(): Promise<void>;
21
+ findAllChunks(): Promise<Chunk[]>;
22
+ updateEmbedding(params: {
23
+ chunkId: string;
24
+ embedding: number[];
25
+ }): Promise<void>;
18
26
  findPotentialChunks(params: {
19
27
  question: string;
20
28
  dataLimits: DataLimits;
21
29
  }): Promise<Chunk[]>;
22
- /**
23
- * Help-content retrieval. Intentionally bypasses company filtering — `(data:HowTo)`
24
- * nodes are global and have no `BELONGS_TO Company` edge. Only callable from inside
25
- * this repository; `findPotentialChunks` dispatches here based on
26
- * `dataLimits.howToMode` / `dataLimits.limitToHowToId`.
27
- */
28
- private findPotentialChunksFromHowTos;
30
+ private findChunksByIdsOrdered;
31
+ findParentName(params: {
32
+ id: string;
33
+ nodeType: string;
34
+ }): Promise<string | undefined>;
29
35
  findSubsequentChunkId(params: {
30
36
  chunkId: string;
31
37
  }): Promise<Chunk>;
@@ -45,6 +51,7 @@ export declare class ChunkRepository implements OnModuleInit {
45
51
  nodeType: string;
46
52
  previousChunkId?: string;
47
53
  content: string;
54
+ heading?: string;
48
55
  imagePath?: string;
49
56
  position: number;
50
57
  }): Promise<void>;
@@ -52,6 +59,19 @@ export declare class ChunkRepository implements OnModuleInit {
52
59
  id: string;
53
60
  aiStatus: AiStatus;
54
61
  }): Promise<void>;
62
+ updateDates(params: {
63
+ chunkId: string;
64
+ dates: string;
65
+ }): Promise<void>;
66
+ enrichContentAndEmbedBatch(items: {
67
+ chunkId: string;
68
+ enrichedContent: string;
69
+ propagatedDates?: string;
70
+ }[]): Promise<void>;
71
+ markChunksCompleted(params: {
72
+ id: string;
73
+ nodeType: string;
74
+ }): Promise<void>;
55
75
  getChunksInProgress(params: {
56
76
  id: string;
57
77
  nodeType: string;
@@ -68,6 +88,14 @@ export declare class ChunkRepository implements OnModuleInit {
68
88
  id: string;
69
89
  nodeType: string;
70
90
  }): Promise<void>;
91
+ findChunkNeighbors(params: {
92
+ chunkIds: string[];
93
+ window: number;
94
+ }): Promise<{
95
+ chunkId: string;
96
+ before: string[];
97
+ after: string[];
98
+ }[]>;
71
99
  findChunkByContentIdAndType(params: {
72
100
  id: string;
73
101
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"chunk.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunk/repositories/chunk.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACnF,OAAO,EAAE,KAAK,EAAmB,MAAM,mCAAmC,CAAC;AAE3E,qBACa,eAAgB,YAAW,YAAY;IAEhD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAJf,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe;IAG7C,YAAY;IAmBZ,mBAAmB,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAkCjG;;;;;OAKG;YACW,6BAA6B;IA+BrC,qBAAqB,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAgBlE,mBAAmB,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAgBhE,aAAa,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAgB1D,UAAU,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAiBtE,WAAW,CAAC,MAAM,EAAE;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDX,YAAY,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBvE,mBAAmB,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAkB/E,sBAAsB,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvF,YAAY,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3D,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYzC,sBAAsB,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/E,2BAA2B,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;CAe1F"}
1
+ {"version":3,"file":"chunk.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunk/repositories/chunk.repository.ts"],"names":[],"mappings":"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"}
@@ -8,24 +8,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.ChunkRepository = void 0;
13
16
  const common_1 = require("@nestjs/common");
14
17
  const nestjs_cls_1 = require("nestjs-cls");
15
18
  const ai_status_1 = require("../../../common/enums/ai.status");
16
- const ai_source_query_1 = require("../../../common/repositories/ai.source.query");
19
+ const ai_source_query_provider_1 = require("../../../common/repositories/ai-source-query.provider");
17
20
  const core_1 = require("../../../core");
18
21
  const model_service_1 = require("../../../core/llm/services/model.service");
19
22
  const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
20
23
  const security_service_1 = require("../../../core/security/services/security.service");
21
24
  const chunk_entity_1 = require("../../chunk/entities/chunk.entity");
25
+ const chunk_meta_1 = require("../entities/chunk.meta");
26
+ const reciprocal_rank_fusion_1 = require("../services/reciprocal-rank-fusion");
22
27
  let ChunkRepository = class ChunkRepository {
23
- constructor(neo4j, modelService, embedderService, clsService, securityService) {
28
+ constructor(neo4j, modelService, embedderService, clsService, securityService, aiSourceQuery) {
24
29
  this.neo4j = neo4j;
25
30
  this.modelService = modelService;
26
31
  this.embedderService = embedderService;
27
32
  this.clsService = clsService;
28
33
  this.securityService = securityService;
34
+ this.aiSourceQuery = aiSourceQuery;
29
35
  }
30
36
  async onModuleInit() {
31
37
  await this.neo4j.writeOne({
@@ -43,68 +49,120 @@ let ChunkRepository = class ChunkRepository {
43
49
  }};
44
50
  `,
45
51
  });
52
+ await this.neo4j.writeOne({
53
+ query: `CREATE FULLTEXT INDEX chunk_content_search IF NOT EXISTS FOR (chunk:Chunk) ON EACH [chunk.content]`,
54
+ });
55
+ }
56
+ async recreateVectorIndex() {
57
+ await this.neo4j.writeOne({
58
+ query: `DROP INDEX chunks IF EXISTS`,
59
+ });
60
+ const dimensions = this.modelService.getEmbedderDimensions();
61
+ await this.neo4j.writeOne({
62
+ query: `
63
+ CREATE VECTOR INDEX chunks IF NOT EXISTS
64
+ FOR (chunk:Chunk)
65
+ ON chunk.embedding
66
+ OPTIONS { indexConfig: {
67
+ \`vector.dimensions\`: ${dimensions},
68
+ \`vector.similarity_function\`: 'cosine'
69
+ }};
70
+ `,
71
+ });
72
+ }
73
+ async findAllChunks() {
74
+ const query = this.neo4j.initQuery({ serialiser: chunk_entity_1.ChunkDescriptor.model, fetchAll: true });
75
+ query.query = `
76
+ MATCH (${chunk_meta_1.chunkMeta.nodeName}:${chunk_meta_1.chunkMeta.labelName})
77
+ RETURN ${chunk_meta_1.chunkMeta.nodeName}
78
+ `;
79
+ return this.neo4j.readMany(query);
80
+ }
81
+ async updateEmbedding(params) {
82
+ await this.neo4j.writeOne({
83
+ query: `
84
+ MATCH (chunk:Chunk {id: $chunkId})
85
+ SET chunk.embedding = $embedding, chunk.updatedAt = datetime()
86
+ `,
87
+ queryParams: {
88
+ chunkId: params.chunkId,
89
+ embedding: params.embedding,
90
+ },
91
+ });
46
92
  }
47
93
  async findPotentialChunks(params) {
48
- // SECURITY: HowTo retrieval intentionally bypasses company filtering.
49
- // Dispatch to the private method so the bypass is visible and quarantined here.
50
- if (params.dataLimits.howToMode || params.dataLimits.limitToHowToId) {
51
- return this.findPotentialChunksFromHowTos(params);
52
- }
53
- const query = this.neo4j.initQuery({ serialiser: chunk_entity_1.ChunkDescriptor.model });
54
94
  const queryEmbedding = await this.embedderService.vectoriseText({ text: params.question });
55
- query.queryParams = { ...query.queryParams, queryEmbedding };
56
- query.query = `
57
- MATCH (data)-[:BELONGS_TO]->(company)
58
- ${(0, ai_source_query_1.aiSourceQuery)({
95
+ // Lucene special-character escape so user questions can't break the fulltext query.
96
+ const term = params.question.replace(/([+\-!(){}\[\]^"~*?:\\\/]|&&|\|\|)/g, "\\$1");
97
+ // The access-scoped id-set both retrieval branches are filtered to.
98
+ const scope = this.aiSourceQuery.build({
99
+ dataLimits: params.dataLimits,
59
100
  currentUserId: this.clsService.get("userId"),
60
101
  securityService: this.securityService,
61
- dataLimits: params.dataLimits,
62
102
  returnsData: true,
63
- })}
103
+ });
104
+ const scopeQuery = this.neo4j.initQuery();
105
+ scopeQuery.queryParams = { ...scopeQuery.queryParams, ...scope.params };
106
+ scopeQuery.query += `
107
+ ${scope.cypher}
64
108
  MATCH (chunk:Chunk)<-[:HAS_CHUNK]-(data)
65
- WITH COLLECT(DISTINCT chunk.id) AS chunkIds
66
-
109
+ RETURN COLLECT(DISTINCT chunk.id) AS chunkIds
110
+ `;
111
+ const scopeResult = await this.neo4j.read(scopeQuery.query, scopeQuery.queryParams);
112
+ const chunkIds = scopeResult.records[0]?.get("chunkIds") ?? [];
113
+ if (chunkIds.length === 0)
114
+ return [];
115
+ const vectorResult = await this.neo4j.read(`
67
116
  CALL db.index.vector.queryNodes('chunks', 1000, $queryEmbedding)
68
117
  YIELD node AS candidateChunk, score
69
- WHERE candidateChunk.id IN chunkIds
70
-
71
- RETURN candidateChunk AS chunk, score
118
+ WHERE candidateChunk.id IN $chunkIds
119
+ RETURN candidateChunk.id AS id
72
120
  ORDER BY score DESC
73
- LIMIT 20
74
- `;
75
- return this.neo4j.readMany(query);
121
+ LIMIT 50
122
+ `, { queryEmbedding, chunkIds });
123
+ const vectorIds = vectorResult.records.map((record) => record.get("id"));
124
+ let lexicalIds = [];
125
+ if (term.trim()) {
126
+ const lexicalResult = await this.neo4j.read(`
127
+ CALL db.index.fulltext.queryNodes('chunk_content_search', $term)
128
+ YIELD node, score
129
+ WHERE node.id IN $chunkIds
130
+ RETURN node.id AS id
131
+ ORDER BY score DESC
132
+ LIMIT 50
133
+ `, { term, chunkIds });
134
+ lexicalIds = lexicalResult.records.map((record) => record.get("id"));
135
+ }
136
+ const fusedIds = (0, reciprocal_rank_fusion_1.reciprocalRankFusion)([vectorIds, lexicalIds]).slice(0, 20);
137
+ return this.findChunksByIdsOrdered(fusedIds);
76
138
  }
77
- /**
78
- * Help-content retrieval. Intentionally bypasses company filtering — `(data:HowTo)`
79
- * nodes are global and have no `BELONGS_TO Company` edge. Only callable from inside
80
- * this repository; `findPotentialChunks` dispatches here based on
81
- * `dataLimits.howToMode` / `dataLimits.limitToHowToId`.
82
- */
83
- async findPotentialChunksFromHowTos(params) {
139
+ async findChunksByIdsOrdered(ids) {
140
+ if (ids.length === 0)
141
+ return [];
84
142
  const query = this.neo4j.initQuery({ serialiser: chunk_entity_1.ChunkDescriptor.model });
85
- const queryEmbedding = await this.embedderService.vectoriseText({ text: params.question });
86
143
  query.queryParams = {
87
144
  ...query.queryParams,
88
- queryEmbedding,
89
- ...(params.dataLimits.limitToHowToId ? { limitToHowToId: params.dataLimits.limitToHowToId } : {}),
145
+ ids,
90
146
  };
91
- const limitClause = params.dataLimits.limitToHowToId ? `WHERE data.id = $limitToHowToId` : "";
147
+ query.query += `
148
+ MATCH (chunk:Chunk)
149
+ WHERE chunk.id IN $ids
150
+ RETURN chunk
151
+ `;
152
+ const chunks = await this.neo4j.readMany(query);
153
+ const byId = new Map(chunks.map((chunk) => [chunk.id, chunk]));
154
+ return ids.map((id) => byId.get(id)).filter((chunk) => chunk !== undefined);
155
+ }
156
+ async findParentName(params) {
157
+ const query = this.neo4j.initQuery();
158
+ query.queryParams = { ...query.queryParams, id: params.id };
92
159
  query.query = `
93
- MATCH (data:HowTo)
94
- ${limitClause}
95
- WITH data
96
- MATCH (chunk:Chunk)<-[:HAS_CHUNK]-(data)
97
- WITH COLLECT(DISTINCT chunk.id) AS chunkIds
98
-
99
- CALL db.index.vector.queryNodes('chunks', 1000, $queryEmbedding)
100
- YIELD node AS candidateChunk, score
101
- WHERE candidateChunk.id IN chunkIds
102
-
103
- RETURN candidateChunk AS chunk, score
104
- ORDER BY score DESC
105
- LIMIT 20
106
- `;
107
- return this.neo4j.readMany(query);
160
+ MATCH (n:${params.nodeType} {id: $id})
161
+ RETURN coalesce(n.name, n.title, n.subject, n.number) AS name
162
+ `;
163
+ const result = await this.neo4j.read(query.query, query.queryParams);
164
+ const name = result.records[0]?.get("name");
165
+ return typeof name === "string" && name.trim() ? name : undefined;
108
166
  }
109
167
  async findSubsequentChunkId(params) {
110
168
  const query = this.neo4j.initQuery({ serialiser: chunk_entity_1.ChunkDescriptor.model });
@@ -162,6 +220,7 @@ let ChunkRepository = class ChunkRepository {
162
220
  ...query.queryParams,
163
221
  id: params.id,
164
222
  content: params.content,
223
+ heading: params.heading ?? null,
165
224
  position: params.position,
166
225
  vector: vector,
167
226
  imagePath: params.imagePath,
@@ -175,7 +234,8 @@ let ChunkRepository = class ChunkRepository {
175
234
  OPTIONAL MATCH (nodeType)-[:BELONGS_TO]->(company)
176
235
  CREATE (chunk:Chunk {
177
236
  id: $id,
178
- content: $content,
237
+ content: $content,
238
+ heading: $heading,
179
239
  ${params.imagePath ? "imagePath: $imagePath," : ""}
180
240
  embedding: $vector,
181
241
  position: $position,
@@ -210,6 +270,56 @@ let ChunkRepository = class ChunkRepository {
210
270
  `;
211
271
  await this.neo4j.writeOne(query);
212
272
  }
273
+ async updateDates(params) {
274
+ const query = this.neo4j.initQuery();
275
+ query.queryParams = {
276
+ ...query.queryParams,
277
+ chunkId: params.chunkId,
278
+ dates: params.dates,
279
+ };
280
+ query.query = `
281
+ MATCH (chunk:Chunk {id: $chunkId})
282
+ SET chunk.dates = $dates, chunk.updatedAt = datetime()
283
+ `;
284
+ await this.neo4j.writeOne(query);
285
+ }
286
+ async enrichContentAndEmbedBatch(items) {
287
+ if (items.length === 0)
288
+ return;
289
+ // One Azure round-trip for the whole set — per-call latency dominates batch size, so
290
+ // embedding chunks individually (vectoriseText per chunk) is far slower than batching.
291
+ // RateLimitedEmbedder.embedDocuments splits internally if the batch exceeds maxBatchTokens.
292
+ const vectors = await this.embedderService.vectoriseTextBatch(items.map((item) => item.enrichedContent));
293
+ const rows = items.map((item, index) => ({
294
+ chunkId: item.chunkId,
295
+ enrichedContent: item.enrichedContent,
296
+ vector: vectors[index],
297
+ propagatedDates: item.propagatedDates ?? null,
298
+ }));
299
+ const query = this.neo4j.initQuery();
300
+ query.queryParams = {
301
+ ...query.queryParams,
302
+ rows,
303
+ };
304
+ query.query = `
305
+ UNWIND $rows AS row
306
+ MATCH (chunk:Chunk {id: row.chunkId})
307
+ SET chunk.content = row.enrichedContent,
308
+ chunk.embedding = row.vector,
309
+ chunk.updatedAt = datetime(),
310
+ chunk.propagatedDates = row.propagatedDates
311
+ `;
312
+ await this.neo4j.writeOne(query);
313
+ }
314
+ async markChunksCompleted(params) {
315
+ const query = this.neo4j.initQuery();
316
+ query.queryParams = { ...query.queryParams, id: params.id, aiStatus: ai_status_1.AiStatus.Completed };
317
+ query.query += `
318
+ MATCH (nodeType:${params.nodeType} {id: $id})-[:HAS_CHUNK]->(chunk:Chunk)
319
+ SET chunk.aiStatus = $aiStatus, chunk.updatedAt = datetime()
320
+ `;
321
+ await this.neo4j.writeOne(query);
322
+ }
213
323
  async getChunksInProgress(params) {
214
324
  const query = this.neo4j.initQuery({ serialiser: chunk_entity_1.ChunkDescriptor.model });
215
325
  query.queryParams = {
@@ -268,6 +378,29 @@ let ChunkRepository = class ChunkRepository {
268
378
  `;
269
379
  await this.neo4j.writeOne(query);
270
380
  }
381
+ async findChunkNeighbors(params) {
382
+ if (params.chunkIds.length === 0)
383
+ return [];
384
+ const query = this.neo4j.initQuery();
385
+ query.queryParams = { ...query.queryParams, chunkIds: params.chunkIds, window: params.window };
386
+ query.query = `
387
+ UNWIND $chunkIds AS cid
388
+ MATCH (c:Chunk {id: cid})
389
+ OPTIONAL MATCH pBefore = (b:Chunk)-[:NEXT*1..]->(c)
390
+ WITH cid, c, b, length(pBefore) AS beforeDist ORDER BY beforeDist ASC
391
+ WITH cid, c, [x IN collect(b) WHERE x IS NOT NULL][0..$window] AS befores
392
+ OPTIONAL MATCH pAfter = (c)-[:NEXT*1..]->(a:Chunk)
393
+ WITH cid, befores, a, length(pAfter) AS afterDist ORDER BY afterDist ASC
394
+ WITH cid, befores, [x IN collect(a) WHERE x IS NOT NULL][0..$window] AS afters
395
+ RETURN cid AS chunkId, [x IN befores | x.content] AS before, [x IN afters | x.content] AS after
396
+ `;
397
+ const result = await this.neo4j.read(query.query, query.queryParams);
398
+ return result.records.map((r) => ({
399
+ chunkId: r.get("chunkId"),
400
+ before: r.get("before") ?? [],
401
+ after: r.get("after") ?? [],
402
+ }));
403
+ }
271
404
  async findChunkByContentIdAndType(params) {
272
405
  const query = this.neo4j.initQuery({ fetchAll: true, serialiser: chunk_entity_1.ChunkDescriptor.model });
273
406
  query.queryParams = {
@@ -284,10 +417,11 @@ let ChunkRepository = class ChunkRepository {
284
417
  exports.ChunkRepository = ChunkRepository;
285
418
  exports.ChunkRepository = ChunkRepository = __decorate([
286
419
  (0, common_1.Injectable)(),
420
+ __param(5, (0, common_1.Inject)(ai_source_query_provider_1.AI_SOURCE_QUERY)),
287
421
  __metadata("design:paramtypes", [neo4j_service_1.Neo4jService,
288
422
  model_service_1.ModelService,
289
423
  core_1.EmbedderService,
290
424
  nestjs_cls_1.ClsService,
291
- security_service_1.SecurityService])
425
+ security_service_1.SecurityService, Object])
292
426
  ], ChunkRepository);
293
427
  //# sourceMappingURL=chunk.repository.js.map