@customize-agent/knowledge 4.0.1 → 4.0.2

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 (33) hide show
  1. package/dist/chunking/bge-tokenizer.d.ts +10 -0
  2. package/dist/chunking/bge-tokenizer.js +68 -0
  3. package/dist/chunking/text-chunker.d.ts +10 -0
  4. package/dist/chunking/text-chunker.js +158 -53
  5. package/dist/classification/classifier.js +0 -1
  6. package/dist/core/index-state-store.d.ts +47 -0
  7. package/dist/core/index-state-store.js +184 -50
  8. package/dist/core/knowledge-base-manager.d.ts +24 -2
  9. package/dist/core/knowledge-base-manager.js +195 -51
  10. package/dist/core/multi-project-manager.d.ts +2 -0
  11. package/dist/core/multi-project-manager.js +13 -2
  12. package/dist/embedding/embedding-provider.d.ts +22 -0
  13. package/dist/embedding/embedding-provider.js +116 -2
  14. package/dist/extraction/content-extractor.d.ts +30 -2
  15. package/dist/extraction/content-extractor.js +514 -115
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +2 -2
  18. package/dist/search/federation-search.d.ts +1 -0
  19. package/dist/search/federation-search.js +1 -0
  20. package/dist/vector/hnsw-vector-store.d.ts +20 -0
  21. package/dist/vector/hnsw-vector-store.js +107 -0
  22. package/dist/vector/types.d.ts +2 -0
  23. package/dist/vector/vector-indexer.d.ts +2 -0
  24. package/dist/vector/vector-indexer.js +13 -1
  25. package/models/bge-small-zh-v1.5/config.json +31 -0
  26. package/models/bge-small-zh-v1.5/onnx/model_quantized.onnx +0 -0
  27. package/models/bge-small-zh-v1.5/special_tokens_map.json +7 -0
  28. package/models/bge-small-zh-v1.5/tokenizer.json +21278 -0
  29. package/models/bge-small-zh-v1.5/tokenizer_config.json +15 -0
  30. package/package.json +11 -4
  31. package/scripts/install-hnsw.cjs +47 -0
  32. package/dist/vector/sqlite-vec-store.d.ts +0 -38
  33. package/dist/vector/sqlite-vec-store.js +0 -203
@@ -2,6 +2,7 @@ import * as crypto from 'node:crypto';
2
2
  import * as fs from 'node:fs';
3
3
  import * as os from 'node:os';
4
4
  import * as path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
5
6
  export class HashEmbeddingProvider {
6
7
  dimensions;
7
8
  model = 'hash-embedding-local';
@@ -79,6 +80,114 @@ export class OpenAICompatibleEmbeddingProvider {
79
80
  return (payload.data ?? []).map(item => item.embedding ?? []);
80
81
  }
81
82
  }
83
+ function resolveBundledBgeModelPath() {
84
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
85
+ const candidates = [
86
+ process.env.CUSTOMIZE_BGE_MODEL_PATH,
87
+ process.env.KB_BGE_MODEL_PATH,
88
+ path.resolve(process.cwd(), 'models', 'bge-small-zh-v1.5'),
89
+ path.resolve(process.cwd(), 'packages', 'knowledge', 'models', 'bge-small-zh-v1.5'),
90
+ path.resolve(currentDir, '..', '..', 'models', 'bge-small-zh-v1.5'),
91
+ ].filter(Boolean);
92
+ return candidates.find(candidate => fs.existsSync(path.join(candidate, 'config.json')) && fs.existsSync(path.join(candidate, 'tokenizer.json')));
93
+ }
94
+ export class LocalTransformersEmbeddingProvider {
95
+ model;
96
+ dimensions;
97
+ modelPath;
98
+ static pipelines = new Map();
99
+ constructor(options = {}) {
100
+ this.model = options.model?.trim() || 'BAAI/bge-small-zh-v1.5';
101
+ this.dimensions = options.dimensions ?? 512;
102
+ this.modelPath = options.modelPath || resolveBundledBgeModelPath();
103
+ }
104
+ async embedDocuments(texts) {
105
+ return this.embed(texts);
106
+ }
107
+ async embedQuery(text) {
108
+ return (await this.embed([text]))[0] ?? [];
109
+ }
110
+ async embed(input) {
111
+ const extractor = await this.getPipeline();
112
+ const output = await extractor(input, { pooling: 'mean', normalize: true });
113
+ const vectors = this.parseVectors(output, input.length);
114
+ return vectors.map(vector => this.resizeVector(vector));
115
+ }
116
+ getPipeline() {
117
+ const existing = LocalTransformersEmbeddingProvider.pipelines.get(this.model);
118
+ if (existing)
119
+ return existing;
120
+ const created = this.createPipeline();
121
+ LocalTransformersEmbeddingProvider.pipelines.set(this.model, created);
122
+ return created;
123
+ }
124
+ async createPipeline() {
125
+ const modelPath = this.modelPath;
126
+ if (!modelPath) {
127
+ throw new Error('本地 bge-small-zh-v1.5 模型资源缺失:请将模型文件放到 packages/knowledge/models/bge-small-zh-v1.5,或通过 CUSTOMIZE_BGE_MODEL_PATH 指定本地模型目录。');
128
+ }
129
+ const dynamicImport = new Function('specifier', 'return import(specifier)');
130
+ const mod = await dynamicImport('@huggingface/transformers').catch(error => {
131
+ const message = error instanceof Error ? error.message : String(error);
132
+ throw new Error(`本地语义模型运行依赖 @huggingface/transformers 未安装或无法解析:${message}`);
133
+ });
134
+ if (!mod.pipeline)
135
+ throw new Error('Transformers.js pipeline is unavailable');
136
+ if (mod.env) {
137
+ mod.env.allowRemoteModels = false;
138
+ mod.env.allowLocalModels = true;
139
+ mod.env.localModelPath = path.dirname(modelPath);
140
+ }
141
+ return mod.pipeline('feature-extraction', modelPath, { dtype: 'q8' });
142
+ }
143
+ parseVectors(output, count) {
144
+ if (this.isTensorLike(output)) {
145
+ const dims = output.dims;
146
+ const data = Array.from(output.data, Number);
147
+ if (dims.length === 2)
148
+ return this.splitFlatVectors(data, dims[0] ?? count, dims[1] ?? this.dimensions);
149
+ if (dims.length === 3) {
150
+ const batch = dims[0] ?? count;
151
+ const tokens = dims[1] ?? 1;
152
+ const width = dims[2] ?? this.dimensions;
153
+ return Array.from({ length: batch }, (_, batchIndex) => {
154
+ const vector = Array.from({ length: width }, () => 0);
155
+ for (let tokenIndex = 0; tokenIndex < tokens; tokenIndex++) {
156
+ const offset = batchIndex * tokens * width + tokenIndex * width;
157
+ for (let i = 0; i < width; i++)
158
+ vector[i] = (vector[i] ?? 0) + (data[offset + i] ?? 0);
159
+ }
160
+ return this.normalize(vector.map(value => value / Math.max(1, tokens)));
161
+ });
162
+ }
163
+ }
164
+ if (Array.isArray(output)) {
165
+ const first = output[0];
166
+ if (Array.isArray(first) && typeof first[0] === 'number')
167
+ return output;
168
+ if (typeof first === 'number')
169
+ return [output];
170
+ }
171
+ throw new Error('Unsupported Transformers embedding output');
172
+ }
173
+ isTensorLike(value) {
174
+ return typeof value === 'object' && value !== null && 'data' in value && 'dims' in value && Array.isArray(value.dims);
175
+ }
176
+ splitFlatVectors(data, count, width) {
177
+ return Array.from({ length: count }, (_, index) => this.normalize(data.slice(index * width, (index + 1) * width)));
178
+ }
179
+ resizeVector(vector) {
180
+ if (vector.length === this.dimensions)
181
+ return vector;
182
+ if (vector.length > this.dimensions)
183
+ return this.normalize(vector.slice(0, this.dimensions));
184
+ return this.normalize([...vector, ...Array.from({ length: this.dimensions - vector.length }, () => 0)]);
185
+ }
186
+ normalize(vector) {
187
+ const norm = Math.sqrt(vector.reduce((sum, value) => sum + value * value, 0));
188
+ return norm > 0 ? vector.map(value => value / norm) : vector;
189
+ }
190
+ }
82
191
  function readStoredEmbeddingConfig() {
83
192
  try {
84
193
  const configPath = path.join(os.homedir(), '.customize-agent', 'config.json');
@@ -93,7 +202,7 @@ function readStoredEmbeddingConfig() {
93
202
  }
94
203
  export function createEmbeddingProviderFromEnvironment() {
95
204
  const stored = readStoredEmbeddingConfig();
96
- const provider = process.env.CUSTOMIZE_EMBEDDING_PROVIDER ?? process.env.KB_EMBEDDING_PROVIDER ?? stored?.provider;
205
+ const provider = process.env.CUSTOMIZE_EMBEDDING_PROVIDER ?? process.env.KB_EMBEDDING_PROVIDER ?? stored?.provider ?? 'transformers-local';
97
206
  if (provider === 'openai-compatible') {
98
207
  const baseUrl = process.env.CUSTOMIZE_EMBEDDING_BASE_URL ?? process.env.KB_EMBEDDING_BASE_URL ?? stored?.baseUrl;
99
208
  const model = process.env.CUSTOMIZE_EMBEDDING_MODEL ?? process.env.KB_EMBEDDING_MODEL ?? stored?.model;
@@ -108,5 +217,10 @@ export function createEmbeddingProviderFromEnvironment() {
108
217
  });
109
218
  }
110
219
  }
111
- return new HashEmbeddingProvider();
220
+ const rawDimensions = process.env.CUSTOMIZE_EMBEDDING_DIMENSIONS ?? process.env.KB_EMBEDDING_DIMENSIONS;
221
+ const dimensions = Number(rawDimensions ?? (stored?.provider === 'transformers-local' ? stored.dimensions : undefined) ?? 512);
222
+ return new LocalTransformersEmbeddingProvider({
223
+ model: process.env.CUSTOMIZE_EMBEDDING_MODEL ?? process.env.KB_EMBEDDING_MODEL ?? (stored?.provider === 'transformers-local' ? stored.model : undefined) ?? 'BAAI/bge-small-zh-v1.5',
224
+ dimensions: Number.isFinite(dimensions) ? dimensions : 512,
225
+ });
112
226
  }
@@ -17,6 +17,10 @@ export declare class ContentExtractor {
17
17
  private textScore;
18
18
  private extractCad;
19
19
  private extractDxf;
20
+ private buildCadSemanticNodes;
21
+ private extractDxfTextAnnotations;
22
+ private findNearestCadAnnotation;
23
+ private inferCadEntityType;
20
24
  private tryConvertDwgWithBundledWasm;
21
25
  private tryConvertDwgToDxf;
22
26
  private extractCadMesh;
@@ -25,26 +29,50 @@ export declare class ContentExtractor {
25
29
  private extractBinaryStrings;
26
30
  private extractData;
27
31
  private extractDiagram;
32
+ private extractDrawioGraph;
33
+ private extractExcalidrawGraph;
34
+ private isPointInside;
35
+ private parseXmlAttributes;
28
36
  private parseDelimitedLine;
37
+ private toMarkdownTable;
29
38
  private extractDelimitedText;
30
39
  private extractOfficeDocument;
31
40
  private extractRtf;
32
41
  private extractLegacyWordDocument;
33
42
  private extractLegacyOfficeBinary;
43
+ private findMergedCellValue;
34
44
  private extractSpreadsheet;
45
+ private extractDocxStyleTreeMarkdown;
46
+ private docxHeadingLevel;
35
47
  private extractOfficeZip;
36
- private extractArchive;
37
48
  private extractRasterImage;
49
+ private tryPaddleOcrLayout;
50
+ private parseOcrJson;
51
+ private formatOcrRegions;
52
+ private classifyOcrRegion;
53
+ private formatBoundingBox;
38
54
  private validateRasterImage;
39
55
  private extractPdf;
40
- private pdfOcrPageLimit;
41
56
  private extractScannedPdfOcr;
42
57
  private extractPdfText;
58
+ private toPdfTextItem;
59
+ private layoutPdfTextItems;
60
+ private groupPdfItemsIntoRows;
61
+ private detectPdfColumnSplit;
62
+ private rowsToPdfMarkdownWithTables;
63
+ private splitLikelyTableRow;
64
+ private pdfRowToMarkdown;
65
+ private toMarkdownDocument;
66
+ private normalizeMarkdownHeadings;
43
67
  private extractSvg;
68
+ private extractSvgSemanticNodes;
44
69
  private isTextReadable;
45
70
  private looksTextFile;
46
71
  private matchAll;
47
72
  private stripXml;
48
73
  private flattenJson;
74
+ private atomicJsonObjects;
75
+ private flattenYamlByIndent;
76
+ private flattenXmlPaths;
49
77
  private metadataOnlyText;
50
78
  }