@customize-agent/knowledge 3.0.10 → 3.0.11
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.
- package/dist/core/index-state-store.js +7 -1
- package/dist/core/knowledge-base-manager.js +11 -2
- package/dist/core/multi-project-manager.js +2 -1
- package/dist/core/project-config.d.ts +3 -1
- package/dist/core/project-config.js +10 -8
- package/dist/extraction/content-extractor.d.ts +1 -0
- package/dist/extraction/content-extractor.js +20 -1
- package/package.json +2 -1
|
@@ -494,7 +494,13 @@ export class IndexStateStore {
|
|
|
494
494
|
);
|
|
495
495
|
`);
|
|
496
496
|
this.initFts();
|
|
497
|
-
|
|
497
|
+
try {
|
|
498
|
+
if (this.getMetadata('schema_version') !== '2')
|
|
499
|
+
this.setMetadata('schema_version', '2');
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
// 受限环境中已有索引库可能以只读方式挂载;运行时元数据不是必需项。
|
|
503
|
+
}
|
|
498
504
|
}
|
|
499
505
|
initFts() {
|
|
500
506
|
try {
|
|
@@ -32,7 +32,7 @@ export class KnowledgeBaseManager {
|
|
|
32
32
|
relationshipDetector = new RelationshipDetector();
|
|
33
33
|
embeddingProvider;
|
|
34
34
|
vectorStores;
|
|
35
|
-
configManager
|
|
35
|
+
configManager;
|
|
36
36
|
projectConfig;
|
|
37
37
|
lastSkippedFiles = [];
|
|
38
38
|
llmProvider;
|
|
@@ -47,6 +47,7 @@ export class KnowledgeBaseManager {
|
|
|
47
47
|
this.llmProvider = options.llmProvider;
|
|
48
48
|
this.onProgress = options.onProgress;
|
|
49
49
|
const storageRoot = options.storageRoot ?? path.join(os.homedir(), USER_DATA_DIR);
|
|
50
|
+
this.configManager = new ProjectConfigManager(storageRoot);
|
|
50
51
|
let dbPath;
|
|
51
52
|
if (this.scope === 'global') {
|
|
52
53
|
this.kbPath = options.kbPath ?? path.join(storageRoot, GLOBAL_KNOWLEDGE_DIR);
|
|
@@ -366,18 +367,26 @@ export class KnowledgeBaseManager {
|
|
|
366
367
|
return this.incrementalIndex();
|
|
367
368
|
}
|
|
368
369
|
getUploadRelativePath(fileName, targetRelativePath) {
|
|
369
|
-
return targetRelativePath
|
|
370
|
+
return targetRelativePath ? this.normalizeRelativePath(targetRelativePath) : this.defaultUploadRelativePath(fileName);
|
|
370
371
|
}
|
|
371
372
|
async uploadFile(fileName, content, targetRelativePath, onProgress, options = {}) {
|
|
372
373
|
return this.uploadFiles([{ fileName, content, targetRelativePath }], onProgress, options);
|
|
373
374
|
}
|
|
374
375
|
async uploadFiles(files, onProgress, options = {}) {
|
|
375
376
|
this.initialize();
|
|
377
|
+
const uploadedPaths = [];
|
|
376
378
|
for (const file of files) {
|
|
377
379
|
const relativePath = this.getUploadRelativePath(file.fileName, file.targetRelativePath);
|
|
378
380
|
const targetPath = this.resolveKbRelativePath(relativePath);
|
|
379
381
|
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
380
382
|
fs.writeFileSync(targetPath, file.content);
|
|
383
|
+
uploadedPaths.push(relativePath);
|
|
384
|
+
}
|
|
385
|
+
for (const relativePath of uploadedPaths) {
|
|
386
|
+
const record = this.store.listRecords().find(item => item.relativePath === relativePath);
|
|
387
|
+
if (record)
|
|
388
|
+
await this.deleteVectorFile(record.collectionName, relativePath);
|
|
389
|
+
this.store.deleteRecord(relativePath);
|
|
381
390
|
}
|
|
382
391
|
return this.incrementalIndex({ onProgress, vectorMode: options.vectorMode });
|
|
383
392
|
}
|
|
@@ -10,13 +10,14 @@ export class MultiProjectManager {
|
|
|
10
10
|
storageRoot;
|
|
11
11
|
llmProvider;
|
|
12
12
|
registry;
|
|
13
|
-
configManager
|
|
13
|
+
configManager;
|
|
14
14
|
projects = new Map();
|
|
15
15
|
globalKB;
|
|
16
16
|
constructor(storageRoot = path.join(os.homedir(), USER_DATA_DIR), llmProvider) {
|
|
17
17
|
this.storageRoot = storageRoot;
|
|
18
18
|
this.llmProvider = llmProvider;
|
|
19
19
|
this.registry = new ProjectRegistry(path.join(storageRoot, 'projects', 'registry.db'));
|
|
20
|
+
this.configManager = new ProjectConfigManager(storageRoot);
|
|
20
21
|
}
|
|
21
22
|
async getProject(projectRoot) {
|
|
22
23
|
const resolvedRoot = path.resolve(projectRoot);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ProjectConfig } from '../types.js';
|
|
2
|
-
export declare function getProjectConfigPath(projectRoot: string): string;
|
|
2
|
+
export declare function getProjectConfigPath(projectRoot: string, storageRoot?: string): string;
|
|
3
3
|
export declare function getProjectKbPath(projectRoot: string): string;
|
|
4
4
|
export declare function ensureProjectCustomizeFile(projectRoot: string): void;
|
|
5
5
|
export declare class ProjectConfigManager {
|
|
6
|
+
private readonly storageRoot;
|
|
7
|
+
constructor(storageRoot?: string);
|
|
6
8
|
loadOrCreate(projectRoot: string): ProjectConfig;
|
|
7
9
|
save(projectRoot: string, config: ProjectConfig): void;
|
|
8
10
|
private withDefaults;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import * as os from 'node:os';
|
|
4
|
-
import { DEFAULT_CATEGORY_DIRS, KNOWLEDGE_BASE_DIR,
|
|
4
|
+
import { DEFAULT_CATEGORY_DIRS, KNOWLEDGE_BASE_DIR, USER_DATA_DIR } from '../constants.js';
|
|
5
5
|
import { computeProjectId } from './project-id.js';
|
|
6
|
-
export function getProjectConfigPath(projectRoot) {
|
|
6
|
+
export function getProjectConfigPath(projectRoot, storageRoot = path.join(os.homedir(), USER_DATA_DIR)) {
|
|
7
7
|
const projectId = computeProjectId(projectRoot);
|
|
8
|
-
return path.join(
|
|
8
|
+
return path.join(storageRoot, 'projects', projectId, 'project.json');
|
|
9
9
|
}
|
|
10
10
|
export function getProjectKbPath(projectRoot) {
|
|
11
11
|
return path.join(projectRoot, KNOWLEDGE_BASE_DIR);
|
|
@@ -35,22 +35,24 @@ export function ensureProjectCustomizeFile(projectRoot) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
export class ProjectConfigManager {
|
|
38
|
+
storageRoot;
|
|
39
|
+
constructor(storageRoot = path.join(os.homedir(), USER_DATA_DIR)) {
|
|
40
|
+
this.storageRoot = storageRoot;
|
|
41
|
+
}
|
|
38
42
|
loadOrCreate(projectRoot) {
|
|
39
43
|
ensureProjectCustomizeFile(projectRoot);
|
|
40
|
-
const configPath = getProjectConfigPath(projectRoot);
|
|
44
|
+
const configPath = getProjectConfigPath(projectRoot, this.storageRoot);
|
|
41
45
|
const now = Date.now();
|
|
42
46
|
if (fs.existsSync(configPath)) {
|
|
43
47
|
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
44
|
-
|
|
45
|
-
this.save(projectRoot, { ...config, lastOpenedAt: now });
|
|
46
|
-
return { ...config, lastOpenedAt: now };
|
|
48
|
+
return this.withDefaults(projectRoot, raw, now);
|
|
47
49
|
}
|
|
48
50
|
const config = this.withDefaults(projectRoot, {}, now);
|
|
49
51
|
this.save(projectRoot, config);
|
|
50
52
|
return config;
|
|
51
53
|
}
|
|
52
54
|
save(projectRoot, config) {
|
|
53
|
-
const configPath = getProjectConfigPath(projectRoot);
|
|
55
|
+
const configPath = getProjectConfigPath(projectRoot, this.storageRoot);
|
|
54
56
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
55
57
|
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
56
58
|
}
|
|
@@ -333,10 +333,30 @@ export class ContentExtractor {
|
|
|
333
333
|
warnings,
|
|
334
334
|
};
|
|
335
335
|
}
|
|
336
|
+
async tryConvertDwgWithBundledWasm(filePath) {
|
|
337
|
+
try {
|
|
338
|
+
const mod = await resolveAndImport('dwgdxf');
|
|
339
|
+
if (!mod.convertDwgToDxf)
|
|
340
|
+
return { tool: 'dwgdxf_wasm', warnings: ['内置 dwgdxf WASM 转换器未导出 convertDwgToDxf'] };
|
|
341
|
+
const dxfBytes = await mod.convertDwgToDxf(fs.readFileSync(filePath));
|
|
342
|
+
const dxfText = Buffer.from(dxfBytes).toString('utf8');
|
|
343
|
+
return dxfText.trim()
|
|
344
|
+
? { dxfText, tool: 'dwgdxf_wasm', warnings: [] }
|
|
345
|
+
: { tool: 'dwgdxf_wasm', warnings: ['内置 dwgdxf WASM 转换器未输出 DXF 文本'] };
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
return { tool: 'dwgdxf_wasm', warnings: [`内置 dwgdxf WASM 转换失败: ${error instanceof Error ? error.message : String(error)}`] };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
336
351
|
async tryConvertDwgToDxf(filePath) {
|
|
337
352
|
const tmpDir = fs.mkdtempSync(path.join(this.getTempRoot(), 'customize-dwg-'));
|
|
338
353
|
const outputPath = path.join(tmpDir, `${path.basename(filePath, path.extname(filePath))}.dxf`);
|
|
339
354
|
try {
|
|
355
|
+
const failures = [];
|
|
356
|
+
const bundled = await this.tryConvertDwgWithBundledWasm(filePath);
|
|
357
|
+
if (bundled.dxfText)
|
|
358
|
+
return bundled;
|
|
359
|
+
failures.push(...bundled.warnings);
|
|
340
360
|
const customCmd = process.env.CUSTOMIZE_DWG_TO_DXF_CMD;
|
|
341
361
|
if (customCmd) {
|
|
342
362
|
if (/\s/u.test(customCmd))
|
|
@@ -357,7 +377,6 @@ export class ContentExtractor {
|
|
|
357
377
|
return { dxfText: fs.readFileSync(outputPath, 'utf8'), tool: 'external_dwg_to_dxf', warnings: [] };
|
|
358
378
|
return { tool: 'external_dwg_to_dxf', warnings: [`CUSTOMIZE_DWG_TO_DXF_CMD 转换失败: ${result.stderr || result.stdout || result.error?.message || 'unknown error'}`] };
|
|
359
379
|
}
|
|
360
|
-
const failures = [];
|
|
361
380
|
for (const bin of ['dwgread', 'dwg2dxf']) {
|
|
362
381
|
const result = spawnSync(bin, bin === 'dwgread' ? ['-O', 'DXF', '-o', outputPath, filePath] : [filePath, outputPath], { encoding: 'utf8', timeout: 120_000 });
|
|
363
382
|
if (result.status === 0 && fs.existsSync(outputPath))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@customize-agent/knowledge",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.11",
|
|
4
4
|
"description": "Local knowledge base infrastructure for customize-agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@napi-rs/canvas": "^0.1.82",
|
|
39
39
|
"better-sqlite3": "^12.10.0",
|
|
40
|
+
"dwgdxf": "^2.0.1",
|
|
40
41
|
"dxf-parser": "^1.1.2",
|
|
41
42
|
"fast-glob": "^3.3.3",
|
|
42
43
|
"jszip": "^3.10.1",
|