@magda/semantic-indexer-framework 5.2.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 (64) hide show
  1. package/dist/MinioClient.d.ts +7 -0
  2. package/dist/MinioClient.js +37 -0
  3. package/dist/MinioClient.js.map +1 -0
  4. package/dist/SkipError.d.ts +1 -0
  5. package/dist/SkipError.js +1 -0
  6. package/dist/SkipError.js.map +1 -0
  7. package/dist/chunker.d.ts +32 -0
  8. package/dist/chunker.js +84 -0
  9. package/dist/chunker.js.map +1 -0
  10. package/dist/commonYargs.d.ts +43 -0
  11. package/dist/commonYargs.js +61 -0
  12. package/dist/commonYargs.js.map +1 -0
  13. package/dist/createEmbeddingText.d.ts +18 -0
  14. package/dist/createEmbeddingText.js +1 -0
  15. package/dist/createEmbeddingText.js.map +1 -0
  16. package/dist/helpers.d.ts +1 -0
  17. package/dist/helpers.js +10 -0
  18. package/dist/helpers.js.map +1 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.js +4 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/indexEmbeddingText.d.ts +22 -0
  23. package/dist/indexEmbeddingText.js +216 -0
  24. package/dist/indexEmbeddingText.js.map +1 -0
  25. package/dist/indexSchema.d.ts +105 -0
  26. package/dist/indexSchema.js +98 -0
  27. package/dist/indexSchema.js.map +1 -0
  28. package/dist/onRecordFoundRegistryRecord.d.ts +7 -0
  29. package/dist/onRecordFoundRegistryRecord.js +47 -0
  30. package/dist/onRecordFoundRegistryRecord.js.map +1 -0
  31. package/dist/onRecordFoundStorageObject.d.ts +9 -0
  32. package/dist/onRecordFoundStorageObject.js +145 -0
  33. package/dist/onRecordFoundStorageObject.js.map +1 -0
  34. package/dist/semanticIndexer.d.ts +2 -0
  35. package/dist/semanticIndexer.js +86 -0
  36. package/dist/semanticIndexer.js.map +1 -0
  37. package/dist/semanticIndexerOptions.d.ts +19 -0
  38. package/dist/semanticIndexerOptions.js +26 -0
  39. package/dist/semanticIndexerOptions.js.map +1 -0
  40. package/dist/test/BaseSemanticIndexerTest.d.ts +41 -0
  41. package/dist/test/BaseSemanticIndexerTest.js +167 -0
  42. package/dist/test/BaseSemanticIndexerTest.js.map +1 -0
  43. package/dist/test/chunker.spec.d.ts +1 -0
  44. package/dist/test/chunker.spec.js +154 -0
  45. package/dist/test/chunker.spec.js.map +1 -0
  46. package/dist/test/embeddingApiClient.spec.d.ts +1 -0
  47. package/dist/test/embeddingApiClient.spec.js +43 -0
  48. package/dist/test/embeddingApiClient.spec.js.map +1 -0
  49. package/dist/test/helpers.d.ts +4 -0
  50. package/dist/test/helpers.js +34 -0
  51. package/dist/test/helpers.js.map +1 -0
  52. package/dist/test/indexEmbeddingText.spec.d.ts +1 -0
  53. package/dist/test/indexEmbeddingText.spec.js +238 -0
  54. package/dist/test/indexEmbeddingText.spec.js.map +1 -0
  55. package/dist/test/mockEmbeddingApi.d.ts +1 -0
  56. package/dist/test/mockEmbeddingApi.js +25 -0
  57. package/dist/test/mockEmbeddingApi.js.map +1 -0
  58. package/dist/test/onRecordFoundRegistryRecord.spec.d.ts +1 -0
  59. package/dist/test/onRecordFoundRegistryRecord.spec.js +155 -0
  60. package/dist/test/onRecordFoundRegistryRecord.spec.js.map +1 -0
  61. package/dist/test/onRecordFoundStorageObject.spec.d.ts +1 -0
  62. package/dist/test/onRecordFoundStorageObject.spec.js +490 -0
  63. package/dist/test/onRecordFoundStorageObject.spec.js.map +1 -0
  64. package/package.json +78 -0
@@ -0,0 +1,7 @@
1
+ import { MinioConfig } from "./commonYargs.js";
2
+ export declare class MinioClient {
3
+ private client;
4
+ private config;
5
+ constructor(config: MinioConfig, accessKey: string, secretKey: string);
6
+ downloadFile(url: string): Promise<string>;
7
+ }
@@ -0,0 +1,37 @@
1
+ import * as Minio from "minio";
2
+ import urijs from "urijs";
3
+ import { tmpdir } from "os";
4
+ import { v4 as uuidv4 } from "uuid";
5
+ import { join } from "path";
6
+ import { deleteTempFile } from "./helpers.js";
7
+ export class MinioClient {
8
+ client;
9
+ config;
10
+ constructor(config, accessKey, secretKey) {
11
+ this.client = new Minio.Client({
12
+ endPoint: config.endPoint,
13
+ port: config.port,
14
+ accessKey: accessKey,
15
+ secretKey: secretKey,
16
+ useSSL: config.useSSL,
17
+ region: config.region
18
+ });
19
+ this.config = config;
20
+ }
21
+ async downloadFile(url) {
22
+ const uri = urijs(url);
23
+ const [datasetId, distributionId, fileName] = uri.segmentCoded();
24
+ const objectName = `${datasetId}/${distributionId}/${fileName}`;
25
+ const tempDir = tmpdir();
26
+ const tempFileName = `${uuidv4()}`;
27
+ const tempFilePath = join(tempDir, tempFileName);
28
+ try {
29
+ await this.client.fGetObject(this.config.defaultDatasetBucket, objectName, tempFilePath);
30
+ return tempFilePath;
31
+ }
32
+ catch (err) {
33
+ await deleteTempFile(tempFilePath);
34
+ throw err;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MinioClient.js","sourceRoot":"","sources":["../src/MinioClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,OAAO,WAAW;IACZ,MAAM,CAAe;IACrB,MAAM,CAAc;IAE5B,YAAY,MAAmB,EAAE,SAAiB,EAAE,SAAiB;QACjE,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC;YAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACxB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAEjE,MAAM,UAAU,GAAG,GAAG,SAAS,IAAI,cAAc,IAAI,QAAQ,EAAE,CAAC;QAEhE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,GAAG,MAAM,EAAE,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAEjD,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CACxB,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAChC,UAAU,EACV,YAAY,CACf,CAAC;YACF,OAAO,YAAY,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,cAAc,CAAC,YAAY,CAAC,CAAC;YACnC,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1 @@
1
+ export declare class SkipError extends Error {}
@@ -0,0 +1 @@
1
+ export class SkipError extends Error {}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkipError.js","sourceRoot":"","sources":["../src/SkipError.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAU,SAAQ,KAAK;CAAG"}
@@ -0,0 +1,32 @@
1
+ export interface ChunkResult {
2
+ text: string;
3
+ position: number;
4
+ length: number;
5
+ overlap: number;
6
+ }
7
+ export type ChunkStrategyType = (text: string) => Promise<ChunkResult[]>;
8
+ export interface ChunkStrategy {
9
+ chunk: ChunkStrategyType;
10
+ }
11
+ export declare class Chunker {
12
+ private strategy;
13
+ constructor(strategy: ChunkStrategy);
14
+ chunk(text: string): Promise<ChunkResult[]>;
15
+ }
16
+ export declare class UserDefinedChunkStrategy implements ChunkStrategy {
17
+ private chunkFunction;
18
+ constructor(chunkFunction: ChunkStrategyType);
19
+ chunk(text: string): Promise<ChunkResult[]>;
20
+ }
21
+ export declare class RecursiveChunkStrategy {
22
+ private chunkSize;
23
+ private overlap;
24
+ constructor(chunkSize: number, overlap: number);
25
+ chunk(text: string): Promise<ChunkResult[]>;
26
+ }
27
+ export declare class FixedLengthChunkStrategy implements ChunkStrategy {
28
+ private chunkSize;
29
+ private overlap;
30
+ constructor(chunkSize: number, overlap: number);
31
+ chunk(text: string): Promise<ChunkResult[]>;
32
+ }
@@ -0,0 +1,84 @@
1
+ import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
2
+ export class Chunker {
3
+ strategy;
4
+ constructor(strategy) {
5
+ this.strategy = strategy;
6
+ }
7
+ async chunk(text) {
8
+ return this.strategy.chunk(text);
9
+ }
10
+ }
11
+ export class UserDefinedChunkStrategy {
12
+ chunkFunction;
13
+ constructor(chunkFunction) {
14
+ this.chunkFunction = chunkFunction;
15
+ }
16
+ async chunk(text) {
17
+ return this.chunkFunction(text);
18
+ }
19
+ }
20
+ export class RecursiveChunkStrategy {
21
+ chunkSize;
22
+ overlap;
23
+ constructor(chunkSize, overlap) {
24
+ if (overlap >= chunkSize)
25
+ throw new Error("overlap must be < chunkSize");
26
+ this.chunkSize = chunkSize * 4;
27
+ this.overlap = overlap * 4;
28
+ }
29
+ async chunk(text) {
30
+ if (!text) {
31
+ return [];
32
+ }
33
+ if (text.length <= this.chunkSize) {
34
+ return [
35
+ {
36
+ text: text,
37
+ position: 0,
38
+ length: text.length,
39
+ overlap: 0
40
+ }];
41
+
42
+ }
43
+ const splitter = new RecursiveCharacterTextSplitter({
44
+ chunkSize: this.chunkSize,
45
+ chunkOverlap: this.overlap,
46
+ keepSeparator: true,
47
+ stripWhitespace: false
48
+ });
49
+ const chunks = await splitter.splitTextWithMetadata(text);
50
+ for (let i = 1; i < chunks.length; i++) {
51
+ if (chunks[i].overlap === 0 && chunks[i].text.trim() === "") {
52
+ chunks[i - 1].text = chunks[i - 1].text + chunks[i].text;
53
+ chunks[i - 1].length = chunks[i - 1].length + chunks[i].length;
54
+ chunks.splice(i, 1);
55
+ i--;
56
+ }
57
+ }
58
+ return chunks;
59
+ }
60
+ }
61
+ export class FixedLengthChunkStrategy {
62
+ chunkSize;
63
+ overlap;
64
+ constructor(chunkSize, overlap) {
65
+ this.chunkSize = chunkSize;
66
+ this.overlap = overlap;
67
+ if (this.overlap >= this.chunkSize / 2) {
68
+ throw new Error("overlap must be less than half of chunk size");
69
+ }
70
+ }
71
+ async chunk(text) {
72
+ const chunks = [];
73
+ for (let i = 0; i < text.length - this.overlap; i += this.chunkSize - this.overlap) {
74
+ const chunkText = text.slice(i, i + this.chunkSize);
75
+ chunks.push({
76
+ text: chunkText,
77
+ position: i,
78
+ length: chunkText.length,
79
+ overlap: this.overlap
80
+ });
81
+ }
82
+ return chunks;
83
+ }
84
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAe1E,MAAM,OAAO,OAAO;IACR,QAAQ,CAAgB;IAChC,YAAY,QAAuB;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;CACJ;AAED,MAAM,OAAO,wBAAwB;IACzB,aAAa,CAAoB;IAEzC,YAAY,aAAgC;QACxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACJ;AAED,MAAM,OAAO,sBAAsB;IACvB,SAAS,CAAC;IACV,OAAO,CAAC;IAEhB,YAAY,SAAiB,EAAE,OAAe;QAC1C,IAAI,OAAO,IAAI,SAAS;YACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,OAAO;gBACH;oBACI,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,CAAC;oBACX,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,CAAC;iBACb;aACJ,CAAC;QACN,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,8BAA8B,CAAC;YAChD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,YAAY,EAAE,IAAI,CAAC,OAAO;YAC1B,aAAa,EAAE,IAAI;YACnB,eAAe,EAAE,KAAK;SACzB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC1D,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzD,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC/D,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,CAAC,EAAE,CAAC;YACR,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAED,MAAM,OAAO,wBAAwB;IACzB,SAAS,CAAS;IAClB,OAAO,CAAS;IAExB,YAAY,SAAiB,EAAE,OAAe;QAC1C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACpE,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,KACI,IAAI,CAAC,GAAG,CAAC,EACT,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAC9B,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,EACpC,CAAC;YACC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,OAAO,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC,CAAC;QACP,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
@@ -0,0 +1,43 @@
1
+ import { MinionArguments } from "@magda/minion-framework/dist/commonYargs.js";
2
+ export interface SemanticIndexerConfig {
3
+ numberOfShards: number;
4
+ numberOfReplicas: number;
5
+ indexName: string;
6
+ indexVersion: number;
7
+ chunkSizeLimit: number;
8
+ overlap: number;
9
+ bulkEmbeddingsSize: number;
10
+ bulkIndexSize: number;
11
+ fullIndexName?: string;
12
+ knnVectorFieldConfig: {
13
+ mode: string;
14
+ dimension: number;
15
+ spaceType: string;
16
+ efConstruction: number;
17
+ efSearch: number;
18
+ m: number;
19
+ encoder?: {
20
+ name: string;
21
+ type: string;
22
+ clip: boolean;
23
+ };
24
+ compressionLevel?: string;
25
+ };
26
+ }
27
+ export interface MinioConfig {
28
+ endPoint: string;
29
+ port: number;
30
+ useSSL: boolean;
31
+ region: string;
32
+ defaultDatasetBucket: string;
33
+ }
34
+ export interface SemanticIndexerArguments extends MinionArguments {
35
+ opensearchApiURL: string;
36
+ embeddingApiURL: string;
37
+ semanticIndexerConfig: SemanticIndexerConfig;
38
+ minioConfig: MinioConfig;
39
+ minioAccessKey: string;
40
+ minioSecretKey: string;
41
+ registryReadonlyURL: string;
42
+ }
43
+ export declare function commonYargs(defaultPort: number, defaultInternalUrl: string): SemanticIndexerArguments;
@@ -0,0 +1,61 @@
1
+ import commonMinionYargs from "@magda/minion-framework/dist/commonYargs.js";
2
+ import { require } from "@magda/esm-utils";
3
+ export function commonYargs(defaultPort, defaultInternalUrl) {
4
+ let argv = commonMinionYargs(defaultPort, defaultInternalUrl, (y) => y.
5
+ option("semanticIndexerConfig", {
6
+ describe: "Semantic indexer configuration json",
7
+ type: "string",
8
+ coerce: (path) => {
9
+ if (!path) {
10
+ throw new Error("Semantic indexer configuration not found");
11
+ }
12
+ const config = path && require(path);
13
+ return config;
14
+ },
15
+ default: process.env.SEMANTIC_INDEXER_CONFIG_PATH || null
16
+ }).
17
+ option("minioConfig", {
18
+ describe: "Minio configuration json",
19
+ type: "string",
20
+ coerce: (path) => {
21
+ if (!path) {
22
+ throw new Error("Minio configuration not found");
23
+ }
24
+ const config = path && require(path);
25
+ return config;
26
+ },
27
+ default: process.env.MINIO_CONFIG_PATH || null
28
+ }).
29
+ option("minioAccessKey", {
30
+ describe: "The access key to your minio server.",
31
+ type: "string",
32
+ demand: true,
33
+ default: process.env.MINIO_ACCESS_KEY || ""
34
+ }).
35
+ option("minioSecretKey", {
36
+ describe: "The secret key to your minio server.",
37
+ type: "string",
38
+ demand: true,
39
+ default: process.env.MINIO_SECRET_KEY || ""
40
+ }).
41
+ option("opensearchApiURL", {
42
+ describe: "The URL of the OpenSearch API.",
43
+ type: "string",
44
+ default: process.env.OPENSEARCH_API_URL ||
45
+ "http://localhost:9200"
46
+ }).
47
+ option("embeddingApiURL", {
48
+ describe: "The URL of the embedding API.",
49
+ type: "string",
50
+ default: process.env.EMBEDDING_API_URL || "http://localhost:3000"
51
+ }).
52
+ option("registryReadonlyURL", {
53
+ describe: "The URL of the registry readonly API.",
54
+ type: "string",
55
+ default: process.env.REGISTRY_READ_ONLY_URL ||
56
+ "http://localhost:6101/v0"
57
+ }));
58
+ const { indexName, indexVersion } = argv.semanticIndexerConfig;
59
+ argv.semanticIndexerConfig.fullIndexName = `${indexName}-v${indexVersion}`;
60
+ return argv;
61
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commonYargs.js","sourceRoot":"","sources":["../src/commonYargs.ts"],"names":[],"mappings":"AACA,OAAO,iBAEN,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA8C3C,MAAM,UAAU,WAAW,CACvB,WAAmB,EACnB,kBAA0B;IAE1B,IAAI,IAAI,GAAG,iBAAiB,CACxB,WAAW,EACX,kBAAkB,EAClB,CAAC,CAA8B,EAAE,EAAE,CAC/B,CAAC;SACI,MAAM,CAAC,uBAAuB,EAAE;QAC7B,QAAQ,EAAE,qCAAqC;QAC/C,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,CAAC,IAAY,EAAyB,EAAE;YAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,MAAM,IAAI,KAAK,CACX,0CAA0C,CAC7C,CAAC;YACN,CAAC;YACD,MAAM,MAAM,GACR,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,IAAI;KAC5D,CAAC;SACD,MAAM,CAAC,aAAa,EAAE;QACnB,QAAQ,EAAE,0BAA0B;QACpC,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,CAAC,IAAY,EAAe,EAAE;YAClC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,MAAM,GAAgB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI;KACjD,CAAC;SACD,MAAM,CAAC,gBAAgB,EAAE;QACtB,QAAQ,EAAE,sCAAsC;QAChD,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;KAC9C,CAAC;SACD,MAAM,CAAC,gBAAgB,EAAE;QACtB,QAAQ,EAAE,sCAAsC;QAChD,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;KAC9C,CAAC;SACD,MAAM,CAAC,kBAAkB,EAAE;QACxB,QAAQ,EAAE,gCAAgC;QAC1C,IAAI,EAAE,QAAQ;QACd,OAAO,EACH,OAAO,CAAC,GAAG,CAAC,kBAAkB;YAC9B,uBAAuB;KAC9B,CAAC;SACD,MAAM,CAAC,iBAAiB,EAAE;QACvB,QAAQ,EAAE,+BAA+B;QACzC,IAAI,EAAE,QAAQ;QACd,OAAO,EACH,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,uBAAuB;KAC/D,CAAC;SACD,MAAM,CAAC,qBAAqB,EAAE;QAC3B,QAAQ,EAAE,uCAAuC;QACjD,IAAI,EAAE,QAAQ;QACd,OAAO,EACH,OAAO,CAAC,GAAG,CAAC,sBAAsB;YAClC,0BAA0B;KACjC,CAAC,CACb,CAAC;IAEF,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC/D,IAAI,CAAC,qBAAqB,CAAC,aAAa,GAAG,GAAG,SAAS,KAAK,YAAY,EAAE,CAAC;IAC3E,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Record } from "@magda/typescript-common/dist/generated/registry/api.js";
2
+ import Registry from "@magda/typescript-common/dist/registry/AuthorizedRegistryClient.js";
3
+ export type EmbeddingText = {
4
+ text: string;
5
+ subObjects?: Array<{
6
+ subObjectId?: string;
7
+ subObjectType?: string;
8
+ text: string;
9
+ }>;
10
+ };
11
+ export type CreateEmbeddingTextParams = {
12
+ record: Record;
13
+ format: string | null;
14
+ filePath: string | null;
15
+ url: string | null;
16
+ readonlyRegistry: Registry;
17
+ };
18
+ export type CreateEmbeddingText = (params: CreateEmbeddingTextParams) => Promise<EmbeddingText>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createEmbeddingText.js","sourceRoot":"","sources":["../src/createEmbeddingText.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export declare function deleteTempFile(filePath: string): Promise<void>;
@@ -0,0 +1,10 @@
1
+ import fs from "fs";
2
+ export async function deleteTempFile(filePath) {
3
+ if (fs.existsSync(filePath)) {
4
+ fs.unlink(filePath, (err) => {
5
+ if (err) {
6
+ console.error("Error deleting file");
7
+ }
8
+ });
9
+ }
10
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,IAAI,GAAG,EAAE,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { default as SemanticIndexerOptions } from "./semanticIndexerOptions.js";
2
+ export { commonYargs } from "./commonYargs.js";
3
+ export { ItemType } from "./indexSchema.js";
4
+ export { CreateEmbeddingText, CreateEmbeddingTextParams, EmbeddingText } from "./createEmbeddingText.js";
5
+ export { ChunkStrategyType, ChunkResult } from "./chunker.js";
6
+ export { indexEmbeddingText } from "./indexEmbeddingText.js";
7
+ import semanticIndexer from "./semanticIndexer.js";
8
+ export default semanticIndexer;
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { commonYargs } from "./commonYargs.js";
2
+ export { indexEmbeddingText } from "./indexEmbeddingText.js";
3
+ import semanticIndexer from "./semanticIndexer.js";
4
+ export default semanticIndexer;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAW/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,eAAe,MAAM,sBAAsB,CAAC;AACnD,eAAe,eAAe,CAAC"}
@@ -0,0 +1,22 @@
1
+ import EmbeddingApiClient from "@magda/typescript-common/dist/EmbeddingApiClient.js";
2
+ import OpensearchApiClient from "@magda/typescript-common/dist/OpensearchApiClient.js";
3
+ import { Chunker } from "./chunker.js";
4
+ import { EmbeddingText } from "./createEmbeddingText.js";
5
+ import SemanticIndexerOptions from "./semanticIndexerOptions.js";
6
+ interface Metadata {
7
+ recordId: string;
8
+ parentRecordId?: string;
9
+ aspectId?: string;
10
+ fileFormat?: string;
11
+ subObjectId?: string;
12
+ subObjectType?: string;
13
+ }
14
+ export declare function indexEmbeddingText({ options, chunker, embeddingApiClient, opensearchApiClient, embeddingText, metadata
15
+
16
+
17
+
18
+
19
+
20
+
21
+ }: {options: SemanticIndexerOptions;chunker: Chunker;embeddingApiClient: EmbeddingApiClient;opensearchApiClient: OpensearchApiClient;embeddingText: EmbeddingText;metadata: Metadata;}): Promise<void>;
22
+ export {};
@@ -0,0 +1,216 @@
1
+ import { SkipError } from "./SkipError.js";
2
+ import { buildSemanticIndexDocument } from "./indexSchema.js";
3
+ import { v4 as uuidv4 } from "uuid";
4
+ import { Readable, Transform, Writable } from "stream";
5
+ import { pipeline } from "stream/promises";
6
+ import retry from "@magda/typescript-common/dist/retry.js";
7
+ class BuildDocumentTransform extends Transform {
8
+ params;
9
+ buffer = [];
10
+ constructor(params) {
11
+ super({ objectMode: true });
12
+ this.params = params;
13
+ }
14
+ async processBuffer() {
15
+ let embeddings;
16
+ try {
17
+ embeddings = await this.params.embeddingApiClient.get(this.buffer.map((c) => c.text));
18
+ }
19
+ catch (error) {
20
+ throw new SkipError(`Failed to get embeddings: ${error.message}`);
21
+ }
22
+ const documents = this.buffer.map((chunk, i) => buildSemanticIndexDocument({
23
+ recordId: this.params.metadata.recordId,
24
+ parentRecordId: this.params.metadata.parentRecordId,
25
+ aspectId: this.params.metadata.aspectId,
26
+ fileFormat: this.params.metadata.fileFormat,
27
+ subObjectId: this.params.metadata.subObjectId,
28
+ subObjectType: this.params.metadata.subObjectType,
29
+ itemType: this.params.options.itemType,
30
+ index_text_chunk: chunk.text,
31
+ embedding: embeddings[i],
32
+ only_one_index_text_chunk: this.params.totalChunks === 1,
33
+ index_text_chunk_length: chunk.length,
34
+ index_text_chunk_position: chunk.position,
35
+ index_text_chunk_overlap: chunk.overlap,
36
+ indexerId: this.params.options.id,
37
+ createTime: this.params.indexingStartTime,
38
+ updateTime: this.params.indexingStartTime
39
+ }));
40
+ for (let i = 0; i < documents.length; i++) {
41
+ this.push(documents[i]);
42
+ }
43
+ this.buffer = [];
44
+ }
45
+ async _transform(chunk, encoding, callback) {
46
+ this.buffer.push(chunk);
47
+ if (this.buffer.length >= this.params.bulkEmbeddingsSize) {
48
+ try {
49
+ await this.processBuffer();
50
+ callback();
51
+ }
52
+ catch (error) {
53
+ callback(error);
54
+ }
55
+ } else
56
+ {
57
+ callback();
58
+ }
59
+ }
60
+ async _flush(callback) {
61
+ if (this.buffer.length > 0) {
62
+ try {
63
+ await this.processBuffer();
64
+ callback();
65
+ }
66
+ catch (error) {
67
+ callback(error);
68
+ }
69
+ } else
70
+ {
71
+ callback();
72
+ }
73
+ }
74
+ }
75
+ class OpenSearchIndexStream extends Writable {
76
+ opensearchApiClient;
77
+ indexName;
78
+ bulkSize;
79
+ buffer;
80
+ constructor(opensearchApiClient, indexName, bulkSize) {
81
+ super({ objectMode: true });
82
+ this.opensearchApiClient = opensearchApiClient;
83
+ this.indexName = indexName;
84
+ this.bulkSize = bulkSize;
85
+ this.buffer = [];
86
+ }
87
+ async processBuffer() {
88
+ try {
89
+ await this.opensearchApiClient.bulkIndexDocument(this.indexName, this.buffer);
90
+ this.buffer = [];
91
+ }
92
+ catch (error) {
93
+ throw new SkipError(`Failed to index documents: ${error.message}`);
94
+ }
95
+ }
96
+ async _write(chunk, encoding, callback) {
97
+ this.buffer.push(chunk);
98
+ if (this.buffer.length >= this.bulkSize) {
99
+ try {
100
+ await this.processBuffer();
101
+ callback();
102
+ }
103
+ catch (error) {
104
+ callback(error);
105
+ }
106
+ } else
107
+ {
108
+ callback();
109
+ }
110
+ }
111
+ async _final(callback) {
112
+ if (this.buffer.length > 0) {
113
+ try {
114
+ await this.processBuffer();
115
+ callback();
116
+ }
117
+ catch (error) {
118
+ callback(error);
119
+ }
120
+ } else
121
+ {
122
+ callback();
123
+ }
124
+ }
125
+ }
126
+ export async function indexEmbeddingText({ options, chunker, embeddingApiClient, opensearchApiClient, embeddingText, metadata }) {
127
+ if (!embeddingText.text && !embeddingText.subObjects) {
128
+ throw new SkipError("No text or subObjects found to index.");
129
+ }
130
+ const textsToProcess = [];
131
+ if (embeddingText.text) {
132
+ textsToProcess.push({
133
+ text: embeddingText.text,
134
+ metadata: { ...metadata }
135
+ });
136
+ }
137
+ if (embeddingText.subObjects) {
138
+ for (const sub of embeddingText.subObjects) {
139
+ textsToProcess.push({
140
+ text: sub.text,
141
+ metadata: {
142
+ ...metadata,
143
+ subObjectId: sub.subObjectId || uuidv4(),
144
+ subObjectType: sub.subObjectType
145
+ }
146
+ });
147
+ }
148
+ }
149
+ await Promise.all(textsToProcess.map((item) => processSingleText({
150
+ options,
151
+ chunker,
152
+ embeddingApiClient,
153
+ opensearchApiClient,
154
+ metadata: item.metadata,
155
+ text: item.text
156
+ })));
157
+ }
158
+ async function processSingleText({ options, chunker, embeddingApiClient, opensearchApiClient, metadata, text }) {
159
+ const semanticIndexerConfig = options.argv.semanticIndexerConfig;
160
+ const bulkEmbeddingsSize = semanticIndexerConfig.bulkEmbeddingsSize || 50;
161
+ const bulkIndexSize = semanticIndexerConfig.bulkIndexSize || 1;
162
+ const indexName = semanticIndexerConfig.fullIndexName;
163
+ const chunks = await chunker.chunk(text);
164
+ if (!chunks || chunks.length === 0) {
165
+ throw new SkipError("No chunks generated from text.");
166
+ }
167
+ const indexingStartTime = new Date().toISOString();
168
+ const textChunkStream = Readable.from(chunks, { objectMode: true });
169
+ const buildDocumentTransform = new BuildDocumentTransform({
170
+ options,
171
+ embeddingApiClient,
172
+ bulkEmbeddingsSize,
173
+ totalChunks: chunks.length,
174
+ text,
175
+ metadata,
176
+ indexingStartTime
177
+ });
178
+ const openSearchStream = new OpenSearchIndexStream(opensearchApiClient, indexName, bulkIndexSize);
179
+ try {
180
+ await pipeline(textChunkStream, buildDocumentTransform, openSearchStream);
181
+ await deleteOldDocuments(opensearchApiClient, indexName, options.id, metadata.recordId, indexingStartTime, options.timeout || "1m", 3);
182
+ }
183
+ catch (error) {
184
+ throw new SkipError(`Failed to index documents: ${error.message}`);
185
+ }
186
+ }
187
+ async function deleteOldDocuments(opensearchApiClient, indexName, indexerId, recordId, beforeTimestamp, timeout, retries) {
188
+ const deleteQuery = {
189
+ bool: {
190
+ filter: [
191
+ { term: { indexerId: indexerId } },
192
+ { term: { recordId: recordId } },
193
+ { range: { createTime: { lt: beforeTimestamp } } }]
194
+
195
+ }
196
+ };
197
+ await retry(async () => {
198
+ const result = await opensearchApiClient.deleteByQuery({
199
+ index: indexName,
200
+ body: { query: deleteQuery },
201
+ wait_for_completion: true,
202
+ conflicts: "proceed",
203
+ timeout: timeout
204
+ });
205
+ const responseBody = result.body;
206
+ if (responseBody.version_conflicts !== 0) {
207
+ throw new Error(`${responseBody.version_conflicts} version conflicts`);
208
+ }
209
+ if (responseBody.timed_out) {
210
+ throw new Error(`timed out`);
211
+ }
212
+ return;
213
+ }, 1, retries, (error, left) => {
214
+ console.warn(`Failed to delete old documents: ${error.message}. remaining retries: ${left}`);
215
+ });
216
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexEmbeddingText.js","sourceRoot":"","sources":["../src/indexEmbeddingText.ts"],"names":[],"mappings":"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"}