@customize-agent/server 4.60.6 → 4.60.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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +1 -1
- package/.next/server/chunks/1001.js +1 -1
- package/.next/server/chunks/1243.js +1 -1
- package/.next/server/chunks/2328.js +1 -1
- package/.next/server/chunks/3806.js +1 -1
- package/.next/server/chunks/{7848.js → 4722.js} +65 -65
- package/.next/server/chunks/8204.js +1 -1
- package/.next/server/chunks/9666.js +76 -76
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/api/documents/export.js +1 -1
- package/.next/server/pages/api/documents/generate/preview.js +1 -1
- package/.next/server/pages/api/documents/generate.js +1 -1
- package/.next/server/pages/api/documents/generated/[id]/instruction.js +1 -1
- package/.next/server/pages/api/documents/generated/[id]/pause.js +1 -1
- package/.next/server/pages/api/health.js +1 -1
- package/.next/server/pages/api/kb/upload.js +2 -2
- package/.next/server/pages/api/system/data-health.js +1 -1
- package/.next/server/pages/canvas/[id].html +1 -1
- package/.next/server/pages/canvas.html +1 -1
- package/.next/server/pages/documents.html +1 -1
- package/.next/server/pages/guide.html +1 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/knowledge/file-detail.html +1 -1
- package/.next/server/pages/knowledge/files.html +1 -1
- package/.next/server/pages/knowledge/manage.html +1 -1
- package/.next/server/pages/knowledge/source-preview.html +1 -1
- package/.next/server/pages/knowledge.html +1 -1
- package/.next/server/pages/models.html +1 -1
- package/.next/server/pages/overview.html +1 -1
- package/.next/server/pages/prompt.html +1 -1
- package/.next/server/pages/settings.html +1 -1
- package/.next/server/pages/skills/[id]/edit.html +1 -1
- package/.next/server/pages/skills/[id].html +1 -1
- package/.next/server/pages/skills/new.html +1 -1
- package/.next/server/pages/skills.html +1 -1
- package/.next/server/pages/system/logs.html +1 -1
- package/.next/server/pages-manifest.json +31 -31
- package/.next/static/chunks/pages/{_app-3f5aa4ff7951feca.js → _app-28228d95968c4d44.js} +1 -1
- package/package.json +2 -2
- package/scripts/capture-baseline.mjs +4 -2
- package/scripts/half-built-scan.allow.json +1 -1
- package/scripts/kb-index-worker.cjs +2 -2
- package/scripts/kb-worker-ipc.cjs +1 -1
- package/scripts/upload-matrix.cjs +44 -25
- /package/.next/static/{3a50a07d5e578847f7a1eefe9573b36527d6e1f5a7d0cb3b4883423ccfabc75b → 36956db6655c7ce7a67c9b6862b2ca1b6b5308f268b5595d430facff6c0f4152}/_buildManifest.js +0 -0
- /package/.next/static/{3a50a07d5e578847f7a1eefe9573b36527d6e1f5a7d0cb3b4883423ccfabc75b → 36956db6655c7ce7a67c9b6862b2ca1b6b5308f268b5595d430facff6c0f4152}/_ssgManifest.js +0 -0
|
@@ -12,7 +12,7 @@ const serverRoot = packageJson?.name === '@customize-agent/server'
|
|
|
12
12
|
: path.dirname(require.resolve('@customize-agent/server/package.json', { paths: [packageRoot, installRoot] }));
|
|
13
13
|
const nextBin = require.resolve('next/dist/bin/next', { paths: [serverRoot, packageRoot, installRoot] });
|
|
14
14
|
const tempRoot = process.env.RUNNER_TEMP || fs.mkdtempSync(path.join(require('os').tmpdir(), 'customize-upload-'));
|
|
15
|
-
const
|
|
15
|
+
const uploadDataHome = path.join(tempRoot, 'upload-home');
|
|
16
16
|
const projectRoot = path.join(tempRoot, 'upload-project');
|
|
17
17
|
const dashboardLog = path.join(tempRoot, 'upload-dashboard.log');
|
|
18
18
|
const basePort = 18000 + Math.floor(Math.random() * 1000);
|
|
@@ -20,7 +20,7 @@ const port = Number(process.env.CUSTOMIZE_UPLOAD_PORT || basePort);
|
|
|
20
20
|
const base = `http://127.0.0.1:${port}`;
|
|
21
21
|
const marker = `uploadmatrix${Date.now()}`;
|
|
22
22
|
|
|
23
|
-
fs.rmSync(
|
|
23
|
+
fs.rmSync(uploadDataHome, { recursive: true, force: true });
|
|
24
24
|
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
25
25
|
fs.rmSync(dashboardLog, { force: true });
|
|
26
26
|
fs.mkdirSync(projectRoot, { recursive: true });
|
|
@@ -29,6 +29,19 @@ function minimalPng() {
|
|
|
29
29
|
return Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', 'base64');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function ocrPng() {
|
|
33
|
+
const canvasModule = require(require.resolve('@napi-rs/canvas', { paths: [serverRoot] }));
|
|
34
|
+
const font = path.join(serverRoot, 'public', 'fonts', 'NotoSansCJKsc-Regular.otf');
|
|
35
|
+
assert(fs.existsSync(font), 'Packaged review font is missing');
|
|
36
|
+
canvasModule.GlobalFonts.registerFromPath(font, 'UploadFixtureFont');
|
|
37
|
+
const canvas = canvasModule.createCanvas(1200, 240), context = canvas.getContext('2d');
|
|
38
|
+
context.fillStyle = '#fff'; context.fillRect(0, 0, 1200, 240);
|
|
39
|
+
context.fillStyle = '#000'; context.font = '44px UploadFixtureFont';
|
|
40
|
+
context.fillText('混凝土强度等级 C35', 30, 75);
|
|
41
|
+
context.fillText('合同工期 180 日历天', 30, 165);
|
|
42
|
+
return canvas.toBuffer('image/png');
|
|
43
|
+
}
|
|
44
|
+
|
|
32
45
|
function minimalPdf(text) {
|
|
33
46
|
const stream = `BT /F1 12 Tf 72 720 Td (${text.replace(/[()\\]/g, ' ')}) Tj ET`;
|
|
34
47
|
const objs = [
|
|
@@ -57,6 +70,7 @@ const samples = [
|
|
|
57
70
|
{ name: 'sheet-tsv.tsv', kind: 'spreadsheet/tsv', content: `name\tvalue\n${marker}\ttsv\n` },
|
|
58
71
|
{ name: 'image-svg.svg', kind: 'image/vector', content: `<svg xmlns="http://www.w3.org/2000/svg"><text>${text('svg')}</text></svg>` },
|
|
59
72
|
{ name: 'image-png.png', kind: 'image/raster', content: minimalPng(), allowZeroChunks: true },
|
|
73
|
+
{ name: 'image-ocr.png', kind: 'image/raster-ocr', content: ocrPng(), expectedText: 'C35', additionalText: '180', query: '混凝土 C35 工期 180' },
|
|
60
74
|
{ name: 'cad-dxf.dxf', kind: 'cad/autocad', content: `0\nSECTION\n2\nENTITIES\n0\nTEXT\n1\n${text('dxf')}\n0\nENDSEC\n0\nEOF\n` },
|
|
61
75
|
{ name: 'cad-step.step', kind: 'cad/step', content: `ISO-10303-21; HEADER; FILE_DESCRIPTION(('${text('step')}'),'2;1'); ENDSEC; DATA; ENDSEC; END-ISO-10303-21;` },
|
|
62
76
|
{ name: 'code-js.js', kind: 'code/javascript', content: `export const marker = '${text('javascript')}';\n` },
|
|
@@ -65,7 +79,7 @@ const samples = [
|
|
|
65
79
|
{ name: 'data-yaml.yaml', kind: 'data/yaml', content: `marker: ${marker}\ntext: ${text('yaml')}\n` },
|
|
66
80
|
{ name: 'web-html.html', kind: 'web/html', content: `<html><body>${text('html')}</body></html>` },
|
|
67
81
|
{ name: 'web-css.css', kind: 'web/stylesheet', content: `/* ${text('css')} */\nbody{color:#111}` },
|
|
68
|
-
{ name: 'diagram-drawio.drawio', kind: 'diagram/drawio', content: `<mxfile><diagram
|
|
82
|
+
{ name: 'diagram-drawio.drawio', kind: 'diagram/drawio', content: `<mxfile><diagram><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" parent="1" vertex="1" value="${text('drawio')}"><mxGeometry x="10" y="10" width="100" height="40" as="geometry"/></mxCell></root></mxGraphModel></diagram></mxfile>` },
|
|
69
83
|
{ name: 'diagram-mermaid.mmd', kind: 'diagram/mermaid', content: `graph TD\nA[${text('mermaid')}] --> B` },
|
|
70
84
|
];
|
|
71
85
|
|
|
@@ -86,13 +100,13 @@ async function uploadSample(baseUrl, root, sample, uploadId) {
|
|
|
86
100
|
const form = new FormData();
|
|
87
101
|
form.append('uploadId', uploadId);
|
|
88
102
|
form.append('projectRoot', root);
|
|
89
|
-
form.append('relativePaths', sample.name);
|
|
103
|
+
form.append('relativePaths[0]', sample.name);
|
|
90
104
|
form.append('batchIndex', '0');
|
|
91
105
|
form.append('totalBatches', '1');
|
|
92
106
|
form.append('startIndex', '1');
|
|
93
107
|
form.append('uploadComplete', '1');
|
|
94
108
|
form.append('fileOffset', '0');
|
|
95
|
-
form.append('files', new Blob([sample.content]), sample.name);
|
|
109
|
+
form.append('files[0]', new Blob([sample.content]), sample.name);
|
|
96
110
|
const res = await fetch(`${baseUrl}/api/kb/upload`, { method: 'POST', body: form, signal: AbortSignal.timeout(30000) });
|
|
97
111
|
const raw = await res.text();
|
|
98
112
|
let json;
|
|
@@ -124,11 +138,9 @@ function indexedDetail(detail, allowZeroChunks = false) {
|
|
|
124
138
|
return file && file.status !== 'pending' && Number(file.indexedAt) > 0 && (allowZeroChunks || Number(file.chunkCount) > 0);
|
|
125
139
|
}
|
|
126
140
|
|
|
127
|
-
function searchHasHit(search, relativePath
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
return filePath === relativePath && (!expectedText || String(result.content || '').includes(expectedText));
|
|
131
|
-
});
|
|
141
|
+
function searchHasHit(search, relativePath) {
|
|
142
|
+
return search.json?.contentSearchStatus === 'success' && !search.json.failures?.length
|
|
143
|
+
&& search.json.files?.some(result => result.relativePath === relativePath && result.matchedBy === 'content');
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
async function startServer(serverPort, root, logPath) {
|
|
@@ -137,12 +149,12 @@ async function startServer(serverPort, root, logPath) {
|
|
|
137
149
|
const child = spawn(node, [nextBin, 'start', '-p', String(serverPort), '-H', '127.0.0.1'], {
|
|
138
150
|
cwd: serverRoot,
|
|
139
151
|
stdio: ['ignore', out, out],
|
|
140
|
-
env: { ...process.env,
|
|
152
|
+
env: { ...process.env, CUSTOMIZE_AGENT_HOME: uploadDataHome, CUSTOMIZE_EMBEDDING_PROVIDER: 'transformers-local', NODE_ENV: 'production', CUSTOMIZE_PROJECT_ROOT: root, LOG_LEVEL: 'debug' },
|
|
141
153
|
});
|
|
142
154
|
fs.closeSync(out);
|
|
143
155
|
await waitFor(`dashboard ${serverPort}`, async () => {
|
|
144
156
|
const health = await request('GET', `http://127.0.0.1:${serverPort}/api/health`);
|
|
145
|
-
return health.status
|
|
157
|
+
return health.status === 200 && health.json?.status === 'ok' ? true : undefined;
|
|
146
158
|
}, 120000);
|
|
147
159
|
return child;
|
|
148
160
|
}
|
|
@@ -156,7 +168,7 @@ function dumpEnv() {
|
|
|
156
168
|
});
|
|
157
169
|
}
|
|
158
170
|
|
|
159
|
-
const pages = ['/', '/overview', '/knowledge', '/knowledge/files', '/knowledge/manage', '/
|
|
171
|
+
const pages = ['/', '/overview', '/knowledge', '/knowledge/files', '/knowledge/manage', '/models', '/prompt', '/settings'];
|
|
160
172
|
const apiChecks = [
|
|
161
173
|
{ method: 'GET', path: '/api/health' },
|
|
162
174
|
{ method: 'GET', path: '/api/config/models' },
|
|
@@ -166,7 +178,7 @@ const apiChecks = [
|
|
|
166
178
|
{ method: 'GET', path: '/api/kb/tags' },
|
|
167
179
|
{ method: 'GET', path: '/api/kb/files', query: root => `projectRoot=${encodeURIComponent(root)}&limit=10` },
|
|
168
180
|
{ method: 'GET', path: '/api/kb/stats', query: root => `projectRoot=${encodeURIComponent(root)}` },
|
|
169
|
-
{ method: 'GET', path: '/api/kb/search', query: root => `projectRoot=${encodeURIComponent(root)}&q=${encodeURIComponent(marker)}&limit=
|
|
181
|
+
{ method: 'GET', path: '/api/kb/files/search', query: root => `projectRoot=${encodeURIComponent(root)}&q=${encodeURIComponent(marker)}&limit=50` },
|
|
170
182
|
{ method: 'GET', path: '/api/kb/duplicates', query: root => `projectRoot=${encodeURIComponent(root)}` },
|
|
171
183
|
{ method: 'GET', path: '/api/kb/operations', query: root => `projectRoot=${encodeURIComponent(root)}` },
|
|
172
184
|
{ method: 'GET', path: '/api/prompt' },
|
|
@@ -201,13 +213,13 @@ async function verifyWebSurface(baseUrl, root, label) {
|
|
|
201
213
|
assert(res.status === 202 && res.json.success, `${sample.name} upload failed: ${res.status} ${res.raw}`);
|
|
202
214
|
const relativePath = res.json.relativePath;
|
|
203
215
|
assert(relativePath, `${sample.name} missing relativePath`);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
216
|
+
await waitFor(`${sample.name} background upload operation`, async () => {
|
|
217
|
+
const progress = await request('GET', `${base}/api/kb/operations?projectRoot=${encodeURIComponent(projectRoot)}`);
|
|
218
|
+
assert(progress.status === 200, `${sample.name} operations failed: ${progress.status}`);
|
|
219
|
+
const operation = progress.json.operations?.find(item => item.id === uploadId);
|
|
220
|
+
if (operation?.status === 'error') throw new Error(operation.error || operation.message);
|
|
221
|
+
return operation?.status === 'success' ? operation : undefined;
|
|
222
|
+
}, 120000);
|
|
211
223
|
const detail = await waitFor(`${sample.name} indexed detail`, async () => {
|
|
212
224
|
const current = await request('GET', `${base}/api/kb/files/detail?projectRoot=${encodeURIComponent(projectRoot)}&relativePath=${encodeURIComponent(relativePath)}`);
|
|
213
225
|
if (current.status !== 200) throw new Error(`${sample.name} detail failed: ${current.status} ${current.raw}`);
|
|
@@ -216,16 +228,23 @@ async function verifyWebSurface(baseUrl, root, label) {
|
|
|
216
228
|
}, 120000);
|
|
217
229
|
if (!sample.allowZeroChunks && sample.searchable !== false) {
|
|
218
230
|
const search = await waitFor(`${sample.name} searchable marker`, async () => {
|
|
219
|
-
const current = await request('GET', `${base}/api/kb/search?projectRoot=${encodeURIComponent(projectRoot)}&q=${encodeURIComponent(marker)}&limit=
|
|
231
|
+
const current = await request('GET', `${base}/api/kb/files/search?projectRoot=${encodeURIComponent(projectRoot)}&q=${encodeURIComponent(sample.query ?? marker)}&limit=500`);
|
|
220
232
|
if (current.status !== 200) throw new Error(`${sample.name} search failed: ${current.status} ${current.raw}`);
|
|
221
|
-
return searchHasHit(current, relativePath
|
|
233
|
+
return searchHasHit(current, relativePath) ? current : undefined;
|
|
222
234
|
}, 120000);
|
|
223
|
-
assert(searchHasHit(search, relativePath
|
|
235
|
+
assert(searchHasHit(search, relativePath), `${sample.name} search did not include marker hit`);
|
|
224
236
|
}
|
|
237
|
+
const preview = await request('GET', `${base}/api/kb/files/source-preview?projectRoot=${encodeURIComponent(projectRoot)}&relativePath=${encodeURIComponent(relativePath)}`);
|
|
238
|
+
assert(preview.status === 200 && preview.json.status === 'recorded' && preview.json.conservation?.status === 'verified'
|
|
239
|
+
&& preview.json.conservation.chunkCountMatches && !preview.json.conservation.staleChunkIdentities.length, `${sample.name} parsed source/chunk conservation failed`);
|
|
240
|
+
if (!sample.allowZeroChunks) assert(preview.json.text?.includes(sample.expectedText ?? marker)
|
|
241
|
+
&& (!sample.additionalText || preview.json.text.includes(sample.additionalText)), `${sample.name} indexed text lost submitted content`);
|
|
242
|
+
else assert(detail.json.file?.chunkCount === 0 && preview.json.text === '', `${sample.name} empty image produced fictional source text`);
|
|
225
243
|
console.log('UPLOAD', sample.kind, sample.name, JSON.stringify({ relativePath, chunks: detail.json.file?.chunkCount, vector: res.json.vectorStatus?.status }));
|
|
226
244
|
}
|
|
227
245
|
|
|
228
|
-
const
|
|
246
|
+
const sdk = await import(require.resolve('@customize-agent/knowledge', { paths: [serverRoot] }));
|
|
247
|
+
const incrementalPath = path.join(sdk.getProjectKbPath(projectRoot, path.join(uploadDataHome, '.customize-agent')), '文档资料', 'incremental-local.txt');
|
|
229
248
|
fs.mkdirSync(path.dirname(incrementalPath), { recursive: true });
|
|
230
249
|
fs.writeFileSync(incrementalPath, text('incremental-local'));
|
|
231
250
|
const reindexAll = await request('POST', `${base}/api/kb/reindex`, { projectRoot });
|
|
File without changes
|