@customize-agent/knowledge 3.0.1 → 3.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.
@@ -90,6 +90,13 @@ export declare class KnowledgeBaseManager {
90
90
  uploadFile(fileName: string, content: Buffer, targetRelativePath?: string, onProgress?: (progress: KnowledgeIndexProgress) => void, options?: {
91
91
  vectorMode?: 'sync' | 'defer';
92
92
  }): Promise<DiffResult>;
93
+ uploadFiles(files: Array<{
94
+ fileName: string;
95
+ content: Buffer;
96
+ targetRelativePath?: string;
97
+ }>, onProgress?: (progress: KnowledgeIndexProgress) => void, options?: {
98
+ vectorMode?: 'sync' | 'defer';
99
+ }): Promise<DiffResult>;
93
100
  listFailedFiles(): DiffResult['skippedFiles'];
94
101
  removeFile(relativePath: string): Promise<void>;
95
102
  tagFile(relativePath: string, tags: string[]): void;
@@ -368,11 +368,16 @@ export class KnowledgeBaseManager {
368
368
  return targetRelativePath ?? this.defaultUploadRelativePath(fileName);
369
369
  }
370
370
  async uploadFile(fileName, content, targetRelativePath, onProgress, options = {}) {
371
+ return this.uploadFiles([{ fileName, content, targetRelativePath }], onProgress, options);
372
+ }
373
+ async uploadFiles(files, onProgress, options = {}) {
371
374
  this.initialize();
372
- const relativePath = this.getUploadRelativePath(fileName, targetRelativePath);
373
- const targetPath = this.resolveKbRelativePath(relativePath);
374
- fs.mkdirSync(path.dirname(targetPath), { recursive: true });
375
- fs.writeFileSync(targetPath, content);
375
+ for (const file of files) {
376
+ const relativePath = this.getUploadRelativePath(file.fileName, file.targetRelativePath);
377
+ const targetPath = this.resolveKbRelativePath(relativePath);
378
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
379
+ fs.writeFileSync(targetPath, file.content);
380
+ }
376
381
  return this.incrementalIndex({ onProgress, vectorMode: options.vectorMode });
377
382
  }
378
383
  listFailedFiles() {
@@ -19,6 +19,8 @@ export declare class ContentExtractor {
19
19
  private parseDelimitedLine;
20
20
  private extractDelimitedText;
21
21
  private extractOfficeDocument;
22
+ private extractRtf;
23
+ private extractLegacyOfficeBinary;
22
24
  private extractSpreadsheet;
23
25
  private extractOfficeZip;
24
26
  private extractArchive;
@@ -378,7 +378,12 @@ export class ContentExtractor {
378
378
  };
379
379
  }
380
380
  async extractOfficeDocument(file) {
381
- if (path.extname(file.absolutePath).toLowerCase() === '.docx') {
381
+ const ext = path.extname(file.absolutePath).toLowerCase();
382
+ if (ext === '.rtf')
383
+ return this.extractRtf(file);
384
+ if (ext === '.doc' || ext === '.ppt')
385
+ return this.extractLegacyOfficeBinary(file);
386
+ if (ext === '.docx') {
382
387
  try {
383
388
  const mammoth = await resolveAndImport('mammoth');
384
389
  const result = await mammoth.extractRawText({ path: file.absolutePath });
@@ -397,7 +402,31 @@ export class ContentExtractor {
397
402
  }
398
403
  return this.extractOfficeZip(file);
399
404
  }
405
+ extractRtf(file) {
406
+ const raw = fs.readFileSync(file.absolutePath, 'utf8');
407
+ const text = raw
408
+ .replace(/\\'[0-9a-fA-F]{2}/gu, ' ')
409
+ .replace(/\\[a-zA-Z]+-?\d* ?/gu, ' ')
410
+ .replace(/[{}]/gu, ' ')
411
+ .replace(/\s+/gu, ' ')
412
+ .trim();
413
+ return {
414
+ text,
415
+ metadata: { extractionMode: 'builtin_rtf_text', vectorizable: true, contentCoverage: 'rtf_text' },
416
+ warnings: text ? [] : ['RTF 解析未提取到正文,未入库'],
417
+ };
418
+ }
419
+ extractLegacyOfficeBinary(file) {
420
+ const strings = this.extractBinaryStrings(file.absolutePath).slice(0, 1_000);
421
+ const text = strings.join('\n').trim();
422
+ return {
423
+ text,
424
+ metadata: { extractionMode: 'builtin_legacy_office_binary_strings', vectorizable: true, contentCoverage: 'legacy_office_binary_strings', stringCount: strings.length },
425
+ warnings: text ? [] : ['旧版 Office 二进制文件未提取到正文,未入库'],
426
+ };
427
+ }
400
428
  async extractSpreadsheet(file) {
429
+ const ext = path.extname(file.absolutePath).toLowerCase();
401
430
  try {
402
431
  const XLSX = await resolveAndImport('xlsx');
403
432
  const workbook = XLSX.readFile(file.absolutePath, { cellDates: true, cellFormula: true, cellNF: true, cellStyles: true });
@@ -442,8 +471,12 @@ export class ContentExtractor {
442
471
  }
443
472
  }
444
473
  catch {
474
+ if (ext === '.xls')
475
+ return this.extractLegacyOfficeBinary(file);
445
476
  // fallback below
446
477
  }
478
+ if (ext === '.xls')
479
+ return this.extractLegacyOfficeBinary(file);
447
480
  return this.extractOfficeZip(file);
448
481
  }
449
482
  async extractOfficeZip(file) {
@@ -461,13 +494,14 @@ export class ContentExtractor {
461
494
  texts.push(`${entry.name}: ${stripped.slice(0, 8_000)}`);
462
495
  }
463
496
  metadata.entryCount = Object.keys(zip.files).length;
464
- metadata.contentCoverage = texts.length > 0 ? 'office_zip_xml_text' : 'metadata_filename';
465
- return { text: [this.metadataOnlyText(file), ...texts].join('\n'), metadata, warnings: texts.length ? [] : ['未从 Office 压缩结构中提取到正文,已跳过入库'] };
497
+ metadata.contentCoverage = texts.length > 0 ? 'office_zip_xml_text' : 'office_zip_empty_text';
498
+ return { text: texts.join('\n'), metadata, warnings: texts.length ? [] : ['Office/表格/演示文件未提取到正文,未入库'] };
466
499
  }
467
500
  catch (error) {
468
501
  metadata.extractionMode = 'office_zip_failed';
469
502
  metadata.parseError = error instanceof Error ? error.message : String(error);
470
- return { text: '', metadata, warnings: ['Office/表格/演示文件解析失败,内置解析器未提取到正文,未入库'] };
503
+ metadata.contentCoverage = 'office_zip_failed';
504
+ return { text: '', metadata, warnings: [`Office/表格/演示文件解析失败: ${metadata.parseError},未入库`] };
471
505
  }
472
506
  }
473
507
  async extractArchive(file) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@customize-agent/knowledge",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Local knowledge base infrastructure for customize-agent",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",