@customize-agent/server 4.0.93 → 4.0.95
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 +25 -57
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +0 -12
- package/.next/server/chunks/1936.js +2 -2
- package/.next/server/chunks/5840.js +1 -0
- package/.next/server/chunks/6041.js +176 -0
- package/.next/server/chunks/8204.js +1 -1
- package/.next/server/chunks/8661.js +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/assets/generated/preview.js +1 -1
- package/.next/server/pages/api/assets/generated/preview.js.nft.json +1 -1
- package/.next/server/pages/api/assets/generated.js +1 -1
- package/.next/server/pages/api/assets/generated.js.nft.json +1 -1
- package/.next/server/pages/api/config/web-access.js +1 -0
- package/.next/server/pages/api/config/web-access.js.nft.json +1 -0
- package/.next/server/pages/api/documents/chapter/regenerate.js +1 -1
- package/.next/server/pages/api/documents/chapter/regenerate.js.nft.json +1 -1
- package/.next/server/pages/api/documents/export.js +3 -3
- package/.next/server/pages/api/documents/export.js.nft.json +1 -1
- package/.next/server/pages/api/documents/generate.js +2 -2
- package/.next/server/pages/api/documents/generate.js.nft.json +1 -1
- package/.next/server/pages/api/documents/generated/[id].js +1 -1
- package/.next/server/pages/api/documents/generated/[id].js.nft.json +1 -1
- package/.next/server/pages/api/documents/generated.js +1 -1
- package/.next/server/pages/api/documents/generated.js.nft.json +1 -1
- package/.next/server/pages/api/documents/roles.js +1 -1
- package/.next/server/pages/api/documents/roles.js.nft.json +1 -1
- package/.next/server/pages/api/documents/templates.js +1 -1
- package/.next/server/pages/api/documents/templates.js.nft.json +1 -1
- package/.next/server/pages/asset-library.html +1 -1
- package/.next/server/pages/document-roles.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/search.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/system/logs.html +1 -1
- package/.next/server/pages-manifest.json +20 -22
- package/.next/static/3nHhxjRVb6Sv1RCvTTJ6o/_buildManifest.js +1 -0
- package/.next/static/chunks/192-dee7faefaf840b17.js +1 -0
- package/.next/static/chunks/238-4ad320af4f787bd6.js +1 -0
- package/.next/static/chunks/405-74ecbacd0b5a3128.js +8 -0
- package/.next/static/chunks/621-1c48b0d6d904f023.js +4 -0
- package/.next/static/chunks/{795-d8fb7a0420512701.js → 795-e8cfd56df2293576.js} +1 -1
- package/.next/static/chunks/{455-97ad88d6604f54b7.js → 797-9166f495bb6138e3.js} +1 -1
- package/.next/static/chunks/pages/{_app-e1434faf3490a025.js → _app-d0d7f3a02373fa7e.js} +14 -14
- package/.next/static/chunks/pages/{asset-library-37f844cb358f5457.js → asset-library-c744f6c91b24629f.js} +1 -1
- package/.next/static/chunks/pages/{document-roles-6134d2d3284a530a.js → document-roles-5108efe16c9b0dd0.js} +1 -1
- package/.next/static/chunks/pages/documents-1fad70e8cff2eff9.js +1 -0
- package/.next/static/chunks/pages/guide-e00b6e23a8dd41b3.js +1 -0
- package/.next/static/chunks/pages/knowledge/{file-detail-87669392540614e4.js → file-detail-44e52d9e351e8784.js} +1 -1
- package/.next/static/chunks/pages/knowledge/{files-14ef1012fd201e47.js → files-4f7bacb11528982e.js} +1 -1
- package/.next/static/chunks/pages/knowledge/{manage-ed99a6cb254ddbb7.js → manage-205647551376b193.js} +1 -1
- package/.next/static/chunks/pages/knowledge/{search-afb423fc22eb623b.js → search-577f08171a786578.js} +1 -1
- package/.next/static/chunks/pages/models-47a9542ac5bec5c0.js +1 -0
- package/.next/static/chunks/pages/{prompt-9b869fbe3463020d.js → prompt-aad4329e419fb442.js} +1 -1
- package/.next/static/chunks/pages/{settings-fa9d6a56898ba678.js → settings-78d0d5322fd61afe.js} +1 -1
- package/.next/static/chunks/pages/system/{logs-cbeeb77dc70086ae.js → logs-c97311a24d1a67e1.js} +1 -1
- package/messages/en-US.json +0 -16
- package/messages/zh-CN.json +0 -16
- package/package.json +8 -4
- package/scripts/start-server.cjs +79 -0
- package/scripts/upload-matrix.cjs +258 -0
- package/.next/server/chunks/7899.js +0 -1
- package/.next/server/chunks/8409.js +0 -159
- package/.next/server/pages/api/context.js +0 -11
- package/.next/server/pages/api/context.js.nft.json +0 -1
- package/.next/server/pages/context/long-term.html +0 -1
- package/.next/server/pages/context/long-term.js.nft.json +0 -1
- package/.next/server/pages/context/short-term.html +0 -1
- package/.next/server/pages/context/short-term.js.nft.json +0 -1
- package/.next/static/GKO7Mk_X_04LsBLfFvfCc/_buildManifest.js +0 -1
- package/.next/static/chunks/466-1cd359f130473697.js +0 -1
- package/.next/static/chunks/63-dd8eeb8edd766bae.js +0 -4
- package/.next/static/chunks/642-708b928fbafc6c20.js +0 -8
- package/.next/static/chunks/647-d5e08fda405f7059.js +0 -1
- package/.next/static/chunks/932-2f195f4200ce9378.js +0 -1
- package/.next/static/chunks/pages/context/long-term-29cbf51a281951d9.js +0 -1
- package/.next/static/chunks/pages/context/short-term-fcae99e1744d998a.js +0 -1
- package/.next/static/chunks/pages/documents-aa14e6ec02784787.js +0 -1
- package/.next/static/chunks/pages/guide-c00be7803483b703.js +0 -1
- package/.next/static/chunks/pages/models-e2914678369d2823.js +0 -1
- /package/.next/static/{GKO7Mk_X_04LsBLfFvfCc → 3nHhxjRVb6Sv1RCvTTJ6o}/_ssgManifest.js +0 -0
package/.next/static/chunks/pages/system/{logs-cbeeb77dc70086ae.js → logs-c97311a24d1a67e1.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[979],{14995:(e,t)=>{"use strict";t.A={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"}},39214:(e,t,r)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/system/logs",function(){return r(91698)}])},91698:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>k});var a=r(65321),s=r(97109),i=r(35292),n=r(9137),l=r(11702),o=r(88762),c=r(33442),d=r(85114),h=r(26171),p=r(85493),g=r(7576),u=r(21289),x=r(84253),f=r(99811),y=r(58209),m=r(96651),w=r(60470),j=r(
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[979],{14995:(e,t)=>{"use strict";t.A={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"}},39214:(e,t,r)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/system/logs",function(){return r(91698)}])},91698:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>k});var a=r(65321),s=r(97109),i=r(35292),n=r(9137),l=r(11702),o=r(88762),c=r(33442),d=r(85114),h=r(26171),p=r(85493),g=r(7576),u=r(21289),x=r(84253),f=r(99811),y=r(58209),m=r(96651),w=r(60470),j=r(44494),v=r(6578);let{Text:A,Paragraph:b}=i.A;function k(){let e=(0,j.Vr)(),[t,r]=(0,s.useState)([]),[i,k]=(0,s.useState)(!0),[S,z]=(0,s.useState)(""),[I,C]=(0,s.useState)(!1),N=async()=>{k(!0);try{r((await (0,v.oH)(500)).logs)}catch(e){n.Ay.error(e instanceof Error?e.message:"加载日志失败")}finally{k(!1)}};(0,s.useEffect)(()=>{N()},[]);let B=(0,s.useMemo)(()=>{let e=S.trim().toLowerCase();return e?t.filter(t=>[t.id,t.level,t.source,t.functionName,t.message,t.stack].filter(Boolean).some(t=>String(t).toLowerCase().includes(e))):t},[S,t]),O=[{title:"序号",key:"index",width:70,render:(e,t,r)=>r+1},{title:"时间",dataIndex:"createdAt",width:170,render:e=>new Date(e).toLocaleString()},{title:"级别",dataIndex:"level",width:80,render:e=>(0,a.jsx)(l.A,{color:"error"===e?"error":"warn"===e?"warning":"blue",style:{margin:0},children:e})},{title:"来源",dataIndex:"source",width:200,render:e=>(0,a.jsx)(A,{code:!0,style:{fontSize:12},children:e})},{title:"函数",dataIndex:"functionName",width:160,render:e=>e?(0,a.jsx)(A,{code:!0,style:{fontSize:12},children:e}):(0,a.jsx)(A,{type:"secondary",children:"-"})},{title:"错误信息",dataIndex:"message",render:e=>(0,a.jsx)(b,{style:{maxWidth:480,overflowWrap:"anywhere",wordBreak:"break-all",marginBottom:0,fontSize:12},ellipsis:{rows:2,expandable:!0,symbol:"展开"},children:e})},{title:"Request ID",dataIndex:"id",width:200,render:e=>(0,a.jsx)(A,{copyable:!0,code:!0,style:{fontSize:12},children:e.slice(0,8)})}];return i&&0===t.length?(0,a.jsxs)("div",{className:"space-y-5 animateFadeIn",children:[(0,a.jsx)(o.A,{active:!0,title:!0,paragraph:{rows:1}}),(0,a.jsx)(o.A,{active:!0,paragraph:{rows:12}})]}):(0,a.jsxs)("div",{className:"space-y-5 animateFadeIn",children:[(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",flexWrap:"wrap",gap:12},children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"pageTitle",children:e("nav.systemLogs")}),(0,a.jsx)("p",{className:"pageDesc",children:"查看 API 异常、模型健康检查失败、PDF 降级等运行时问题。"})]}),(0,a.jsxs)(c.A,{children:[(0,a.jsx)(d.Ay,{icon:(0,a.jsx)(f.A,{}),loading:i,onClick:()=>void N(),children:"刷新"}),(0,a.jsx)(h.A,{title:"确认清空所有错误日志?",onConfirm:()=>{(async()=>{await (0,v.hH)(),n.Ay.success("已清空"),await N()})()},children:(0,a.jsx)(d.Ay,{danger:!0,icon:(0,a.jsx)(y.A,{}),children:"清空日志"})})]})]}),(0,a.jsx)(p.A,{type:"info",showIcon:!0,message:(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[(0,a.jsx)("span",{children:"日志保存在本机 ~/.customize-agent/logs/errors.jsonl,最多读取最近 500 条。"}),(0,a.jsx)(d.Ay,{type:"link",size:"small",icon:I?(0,a.jsx)(m.A,{}):(0,a.jsx)(w.A,{}),onClick:()=>C(!I),style:{padding:"0 4px"},children:I?"收起":"展开"})]}),description:I?"系统自动记录未捕获的异常、API 错误、模型健康检查失败等运行时问题。日志文件超过 2MB 会自动轮转。":void 0}),(0,a.jsx)(g.A.Search,{allowClear:!0,placeholder:"搜索 requestId / source / function / message / stack",value:S,onChange:e=>z(e.target.value),style:{maxWidth:480}}),(0,a.jsx)(u.A,{rowKey:"id",loading:i,dataSource:B,columns:O,size:"middle",locale:{emptyText:(0,a.jsx)(x.A,{description:"暂无错误日志"})},pagination:{pageSize:20,showSizeChanger:!0,showTotal:e=>"共 ".concat(e," 条")},expandable:{expandedRowRender:e=>(0,a.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:8,padding:"8px 0"},children:[e.request&&(0,a.jsxs)("div",{children:[(0,a.jsx)(A,{strong:!0,style:{fontSize:12,marginBottom:4,display:"block"},children:"Request"}),(0,a.jsx)("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-all",margin:0,padding:10,background:"var(--colorFillAlter)",borderRadius:8,fontSize:12,lineHeight:1.5},children:JSON.stringify(e.request,null,2)})]}),void 0!==e.meta&&(0,a.jsxs)("div",{children:[(0,a.jsx)(A,{strong:!0,style:{fontSize:12,marginBottom:4,display:"block"},children:"Meta"}),(0,a.jsx)("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-all",margin:0,padding:10,background:"var(--colorFillAlter)",borderRadius:8,fontSize:12,lineHeight:1.5},children:JSON.stringify(e.meta,null,2)})]}),e.stack&&(0,a.jsxs)("div",{children:[(0,a.jsx)(A,{strong:!0,style:{fontSize:12,marginBottom:4,display:"block"},children:"Stack"}),(0,a.jsx)("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-all",margin:0,padding:10,background:"var(--colorFillAlter)",borderRadius:8,fontSize:12,lineHeight:1.5,maxHeight:300,overflow:"auto"},children:e.stack})]})]})}})]})}},92123:(e,t)=>{"use strict";t.A={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"}}]},name:"up",theme:"outlined"}},96651:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(97109),s=r(92123),i=r(88483);function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e}).apply(this,arguments)}let l=a.forwardRef((e,t)=>a.createElement(i.A,n({},e,{ref:t,icon:s.A})))},99811:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(97109),s=r(14995),i=r(88483);function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e}).apply(this,arguments)}let l=a.forwardRef((e,t)=>a.createElement(i.A,n({},e,{ref:t,icon:s.A})))}},e=>{e.O(0,[433,576,195,985,375,102,289,861,636,593,792],()=>e(e.s=39214)),_N_E=e.O()}]);
|
package/messages/en-US.json
CHANGED
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
"guide": "Guide",
|
|
17
17
|
"models": "Model Config",
|
|
18
18
|
"settings": "Settings",
|
|
19
|
-
"contextEngineering": "Context Engineering",
|
|
20
|
-
"longTermContext": "Long-term Context",
|
|
21
|
-
"shortTermContext": "Short-term Context",
|
|
22
19
|
"promptManagement": "Prompt Management",
|
|
23
20
|
"systemLogs": "System Logs"
|
|
24
21
|
},
|
|
@@ -206,19 +203,6 @@
|
|
|
206
203
|
"save": "Save",
|
|
207
204
|
"cancel": "Cancel"
|
|
208
205
|
},
|
|
209
|
-
"context": {
|
|
210
|
-
"title": "Context Engineering",
|
|
211
|
-
"longTermDesc": "Persistent context from memory store (cross-session)",
|
|
212
|
-
"shortTermDesc": "Short-term context from recent session logs",
|
|
213
|
-
"longTermSource": "Source: ~/.customize-agent/memory.db (Memory Store)",
|
|
214
|
-
"shortTermSource": "Source: ~/.customize-agent/logs/ (Session Logs)",
|
|
215
|
-
"importance": "Importance",
|
|
216
|
-
"content": "Content",
|
|
217
|
-
"tags": "Tags",
|
|
218
|
-
"source": "Source",
|
|
219
|
-
"sourceHint": "Optional additional source/context description",
|
|
220
|
-
"updatedAt": "Updated"
|
|
221
|
-
},
|
|
222
206
|
"prompt": {
|
|
223
207
|
"title": "Prompt Management",
|
|
224
208
|
"description": "Manage CUSTOMIZE.md system prompt files per project",
|
package/messages/zh-CN.json
CHANGED
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
"guide": "指引",
|
|
17
17
|
"models": "模型配置",
|
|
18
18
|
"settings": "设置",
|
|
19
|
-
"contextEngineering": "上下文工程",
|
|
20
|
-
"longTermContext": "长期上下文",
|
|
21
|
-
"shortTermContext": "短期上下文",
|
|
22
19
|
"promptManagement": "提示词管理",
|
|
23
20
|
"systemLogs": "系统日志"
|
|
24
21
|
},
|
|
@@ -206,19 +203,6 @@
|
|
|
206
203
|
"save": "保存",
|
|
207
204
|
"cancel": "取消"
|
|
208
205
|
},
|
|
209
|
-
"context": {
|
|
210
|
-
"title": "上下文工程管理",
|
|
211
|
-
"longTermDesc": "来自记忆库的持久化上下文(跨会话保留)",
|
|
212
|
-
"shortTermDesc": "来自最近会话日志的短期上下文",
|
|
213
|
-
"longTermSource": "数据来源: ~/.customize-agent/memory.db(记忆库)",
|
|
214
|
-
"shortTermSource": "数据来源: ~/.customize-agent/logs/(会话日志)",
|
|
215
|
-
"importance": "重要性",
|
|
216
|
-
"content": "内容",
|
|
217
|
-
"tags": "标签",
|
|
218
|
-
"source": "来源",
|
|
219
|
-
"sourceHint": "可选,额外的来源/上下文说明",
|
|
220
|
-
"updatedAt": "更新时间"
|
|
221
|
-
},
|
|
222
206
|
"prompt": {
|
|
223
207
|
"title": "提示词管理",
|
|
224
208
|
"description": "管理各项目的 CUSTOMIZE.md 系统提示词文件",
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@customize-agent/server",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.95",
|
|
4
4
|
"description": "Customize Agent Web 管理控制台",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package.json": "./package.json"
|
|
7
7
|
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"customize-web": "scripts/start-server.cjs",
|
|
10
|
+
"customize-dashboard": "scripts/start-server.cjs"
|
|
11
|
+
},
|
|
8
12
|
"files": [
|
|
9
13
|
".next/BUILD_ID",
|
|
10
14
|
".next/app-build-manifest.json",
|
|
@@ -50,9 +54,9 @@
|
|
|
50
54
|
"tesseract.js": "^7.0.0",
|
|
51
55
|
"typescript": "^6.0.3",
|
|
52
56
|
"xlsx": "^0.18.5",
|
|
53
|
-
"@customize-agent/knowledge": "^4.0.
|
|
54
|
-
"@customize-agent/
|
|
55
|
-
"@customize-agent/
|
|
57
|
+
"@customize-agent/knowledge": "^4.0.37",
|
|
58
|
+
"@customize-agent/llm": "^3.0.10",
|
|
59
|
+
"@customize-agent/runtime": "^3.0.10"
|
|
56
60
|
},
|
|
57
61
|
"devDependencies": {
|
|
58
62
|
"@tailwindcss/postcss": "^4.3.2",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawnSync } = require('child_process');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const serverRoot = path.resolve(__dirname, '..');
|
|
7
|
+
const originalCwd = process.cwd();
|
|
8
|
+
|
|
9
|
+
function readOption(names, fallback) {
|
|
10
|
+
for (let i = 0; i < process.argv.length; i += 1) {
|
|
11
|
+
const arg = process.argv[i];
|
|
12
|
+
const matched = names.find(name => arg === name || arg.startsWith(`${name}=`));
|
|
13
|
+
if (!matched) continue;
|
|
14
|
+
if (arg.includes('=')) return arg.slice(arg.indexOf('=') + 1);
|
|
15
|
+
return process.argv[i + 1] || fallback;
|
|
16
|
+
}
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
21
|
+
console.log(`Usage: customize-web [--port 17321] [--host 127.0.0.1] [--project /path/to/project]
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
-p, --port Web server port, default 17321
|
|
25
|
+
-H, --host Web server host, default 127.0.0.1
|
|
26
|
+
--project Project root managed by the dashboard, default current directory
|
|
27
|
+
|
|
28
|
+
Environment:
|
|
29
|
+
CUSTOMIZE_PROJECT_ROOT Project root managed by the dashboard
|
|
30
|
+
PORT Web server port
|
|
31
|
+
HOST Web server host`);
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const port = readOption(['--port', '-p'], process.env.PORT || process.env.CUSTOMIZE_WEB_PORT || '17321');
|
|
36
|
+
const host = readOption(['--host', '-H'], process.env.HOST || process.env.CUSTOMIZE_WEB_HOST || '127.0.0.1');
|
|
37
|
+
const projectRoot = path.resolve(readOption(['--project'], process.env.CUSTOMIZE_PROJECT_ROOT || originalCwd));
|
|
38
|
+
const buildIdPath = path.join(serverRoot, '.next', 'BUILD_ID');
|
|
39
|
+
|
|
40
|
+
if (!fs.existsSync(buildIdPath)) {
|
|
41
|
+
console.error('[customize-web] Missing production build artifacts. Reinstall @customize-agent/server or run its build step before starting.');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const verify = spawnSync(process.execPath, [path.join(serverRoot, 'scripts', 'verify-next-static.js')], {
|
|
46
|
+
cwd: serverRoot,
|
|
47
|
+
stdio: 'inherit',
|
|
48
|
+
env: process.env,
|
|
49
|
+
});
|
|
50
|
+
if (verify.status !== 0) process.exit(verify.status || 1);
|
|
51
|
+
|
|
52
|
+
let nextBin;
|
|
53
|
+
try {
|
|
54
|
+
nextBin = require.resolve('next/dist/bin/next', { paths: [serverRoot] });
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('[customize-web] Unable to resolve Next.js runtime from @customize-agent/server.');
|
|
57
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log(`[customize-web] Project root: ${projectRoot}`);
|
|
62
|
+
console.log(`[customize-web] Starting: http://${host}:${port}/overview`);
|
|
63
|
+
|
|
64
|
+
const result = spawnSync(process.execPath, [nextBin, 'start', '-p', String(port), '-H', String(host)], {
|
|
65
|
+
cwd: serverRoot,
|
|
66
|
+
stdio: 'inherit',
|
|
67
|
+
env: {
|
|
68
|
+
...process.env,
|
|
69
|
+
NODE_ENV: 'production',
|
|
70
|
+
CUSTOMIZE_PROJECT_ROOT: projectRoot,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (result.error) {
|
|
75
|
+
console.error('[customize-web] Failed to start dashboard.');
|
|
76
|
+
console.error(result.error.message);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
process.exit(result.status ?? 0);
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const packageRoot = path.resolve(process.argv[2] || process.env.PACKAGE_ROOT || '.');
|
|
6
|
+
const installRoot = path.resolve(packageRoot, '..', '..');
|
|
7
|
+
const node = process.execPath;
|
|
8
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
9
|
+
const packageJson = fs.existsSync(packageJsonPath) ? JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) : null;
|
|
10
|
+
const serverRoot = packageJson?.name === '@customize-agent/server'
|
|
11
|
+
? packageRoot
|
|
12
|
+
: path.dirname(require.resolve('@customize-agent/server/package.json', { paths: [packageRoot, installRoot] }));
|
|
13
|
+
const nextBin = require.resolve('next/dist/bin/next', { paths: [serverRoot, packageRoot, installRoot] });
|
|
14
|
+
const tempRoot = process.env.RUNNER_TEMP || fs.mkdtempSync(path.join(require('os').tmpdir(), 'customize-upload-'));
|
|
15
|
+
const home = path.join(tempRoot, 'upload-home');
|
|
16
|
+
const projectRoot = path.join(tempRoot, 'upload-project');
|
|
17
|
+
const dashboardLog = path.join(tempRoot, 'upload-dashboard.log');
|
|
18
|
+
const basePort = 18000 + Math.floor(Math.random() * 1000);
|
|
19
|
+
const port = Number(process.env.CUSTOMIZE_UPLOAD_PORT || basePort);
|
|
20
|
+
const base = `http://127.0.0.1:${port}`;
|
|
21
|
+
const marker = `uploadmatrix${Date.now()}`;
|
|
22
|
+
|
|
23
|
+
fs.rmSync(home, { recursive: true, force: true });
|
|
24
|
+
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
25
|
+
fs.rmSync(dashboardLog, { force: true });
|
|
26
|
+
fs.mkdirSync(projectRoot, { recursive: true });
|
|
27
|
+
|
|
28
|
+
function minimalPng() {
|
|
29
|
+
return Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', 'base64');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function minimalPdf(text) {
|
|
33
|
+
const stream = `BT /F1 12 Tf 72 720 Td (${text.replace(/[()\\]/g, ' ')}) Tj ET`;
|
|
34
|
+
const objs = [
|
|
35
|
+
'1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj',
|
|
36
|
+
'2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj',
|
|
37
|
+
'3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Resources << /Font << /F1 4 0 R >> >> /Contents 5 0 R >> endobj',
|
|
38
|
+
'4 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj',
|
|
39
|
+
`5 0 obj << /Length ${Buffer.byteLength(stream)} >> stream\n${stream}\nendstream endobj`,
|
|
40
|
+
];
|
|
41
|
+
let out = '%PDF-1.4\n';
|
|
42
|
+
const offsets = [0];
|
|
43
|
+
for (const obj of objs) { offsets.push(Buffer.byteLength(out)); out += obj + '\n'; }
|
|
44
|
+
const xref = Buffer.byteLength(out);
|
|
45
|
+
out += `xref\n0 ${objs.length + 1}\n0000000000 65535 f \n`;
|
|
46
|
+
for (let i = 1; i < offsets.length; i++) out += String(offsets[i]).padStart(10, '0') + ' 00000 n \n';
|
|
47
|
+
out += `trailer << /Size ${objs.length + 1} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF`;
|
|
48
|
+
return Buffer.from(out);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const text = kind => `${marker} ${kind} searchable content`;
|
|
52
|
+
const samples = [
|
|
53
|
+
{ name: 'doc-plain.txt', kind: 'document/plaintext', content: text('txt') },
|
|
54
|
+
{ name: 'doc-markdown.md', kind: 'document/markdown', content: `# ${text('markdown')}\n` },
|
|
55
|
+
{ name: 'doc-pdf.pdf', kind: 'document/pdf', content: minimalPdf(text('pdf')), searchable: false },
|
|
56
|
+
{ name: 'sheet-csv.csv', kind: 'spreadsheet/csv', content: `name,value\n${marker},csv\n` },
|
|
57
|
+
{ name: 'sheet-tsv.tsv', kind: 'spreadsheet/tsv', content: `name\tvalue\n${marker}\ttsv\n` },
|
|
58
|
+
{ name: 'image-svg.svg', kind: 'image/vector', content: `<svg xmlns="http://www.w3.org/2000/svg"><text>${text('svg')}</text></svg>` },
|
|
59
|
+
{ name: 'image-png.png', kind: 'image/raster', content: minimalPng(), allowZeroChunks: true },
|
|
60
|
+
{ name: 'cad-dxf.dxf', kind: 'cad/autocad', content: `0\nSECTION\n2\nENTITIES\n0\nTEXT\n1\n${text('dxf')}\n0\nENDSEC\n0\nEOF\n` },
|
|
61
|
+
{ 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
|
+
{ name: 'code-js.js', kind: 'code/javascript', content: `export const marker = '${text('javascript')}';\n` },
|
|
63
|
+
{ name: 'code-py.py', kind: 'code/python', content: `marker = '${text('python')}'\n` },
|
|
64
|
+
{ name: 'data-json.json', kind: 'data/json', content: JSON.stringify({ marker, type: 'json', text: text('json') }) },
|
|
65
|
+
{ name: 'data-yaml.yaml', kind: 'data/yaml', content: `marker: ${marker}\ntext: ${text('yaml')}\n` },
|
|
66
|
+
{ name: 'web-html.html', kind: 'web/html', content: `<html><body>${text('html')}</body></html>` },
|
|
67
|
+
{ name: 'web-css.css', kind: 'web/stylesheet', content: `/* ${text('css')} */\nbody{color:#111}` },
|
|
68
|
+
{ name: 'diagram-drawio.drawio', kind: 'diagram/drawio', content: `<mxfile><diagram>${text('drawio')}</diagram></mxfile>`, searchable: false },
|
|
69
|
+
{ name: 'diagram-mermaid.mmd', kind: 'diagram/mermaid', content: `graph TD\nA[${text('mermaid')}] --> B` },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
async function request(method, url, body, timeoutMs = 30000) {
|
|
73
|
+
const init = { method, signal: AbortSignal.timeout(timeoutMs) };
|
|
74
|
+
if (body !== undefined) {
|
|
75
|
+
init.headers = { 'content-type': 'application/json' };
|
|
76
|
+
init.body = JSON.stringify(body);
|
|
77
|
+
}
|
|
78
|
+
const res = await fetch(url, init);
|
|
79
|
+
const raw = await res.text();
|
|
80
|
+
let json;
|
|
81
|
+
try { json = JSON.parse(raw); } catch { json = raw; }
|
|
82
|
+
return { status: res.status, json, raw };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function uploadSample(baseUrl, root, sample, uploadId) {
|
|
86
|
+
const form = new FormData();
|
|
87
|
+
form.append('uploadId', uploadId);
|
|
88
|
+
form.append('projectRoot', root);
|
|
89
|
+
form.append('relativePaths', sample.name);
|
|
90
|
+
form.append('batchIndex', '0');
|
|
91
|
+
form.append('totalBatches', '1');
|
|
92
|
+
form.append('startIndex', '1');
|
|
93
|
+
form.append('uploadComplete', '1');
|
|
94
|
+
form.append('fileOffset', '0');
|
|
95
|
+
form.append('files', new Blob([sample.content]), sample.name);
|
|
96
|
+
const res = await fetch(`${baseUrl}/api/kb/upload`, { method: 'POST', body: form, signal: AbortSignal.timeout(30000) });
|
|
97
|
+
const raw = await res.text();
|
|
98
|
+
let json;
|
|
99
|
+
try { json = JSON.parse(raw); } catch { json = raw; }
|
|
100
|
+
return { status: res.status, json, raw };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function waitFor(label, fn, timeoutMs = 120000) {
|
|
104
|
+
const deadline = Date.now() + timeoutMs;
|
|
105
|
+
let last;
|
|
106
|
+
while (Date.now() < deadline) {
|
|
107
|
+
try {
|
|
108
|
+
const result = await fn();
|
|
109
|
+
if (result) return result;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
last = error;
|
|
112
|
+
}
|
|
113
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`${label} timeout${last ? `: ${last.message || last}` : ''}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function assert(ok, message) {
|
|
119
|
+
if (!ok) throw new Error(message);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function indexedDetail(detail, allowZeroChunks = false) {
|
|
123
|
+
const file = detail.json?.file;
|
|
124
|
+
return file && file.status !== 'pending' && Number(file.indexedAt) > 0 && (allowZeroChunks || Number(file.chunkCount) > 0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function searchHasHit(search, relativePath, expectedText) {
|
|
128
|
+
return Array.isArray(search.json?.results) && search.json.results.some(result => {
|
|
129
|
+
const filePath = result.filePath || result.relativePath;
|
|
130
|
+
return filePath === relativePath && (!expectedText || String(result.content || '').includes(expectedText));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function startServer(serverPort, root, logPath) {
|
|
135
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
136
|
+
const out = fs.openSync(logPath, 'a');
|
|
137
|
+
const child = spawn(node, [nextBin, 'start', '-p', String(serverPort), '-H', '127.0.0.1'], {
|
|
138
|
+
cwd: serverRoot,
|
|
139
|
+
stdio: ['ignore', out, out],
|
|
140
|
+
env: { ...process.env, HOME: home, CUSTOMIZE_AGENT_HOME: home, NODE_ENV: 'production', CUSTOMIZE_PROJECT_ROOT: root, CUSTOMIZE_AGENT_DISABLE_OCR: '1', LOG_LEVEL: 'debug' },
|
|
141
|
+
});
|
|
142
|
+
fs.closeSync(out);
|
|
143
|
+
await waitFor(`dashboard ${serverPort}`, async () => {
|
|
144
|
+
const health = await request('GET', `http://127.0.0.1:${serverPort}/api/health`);
|
|
145
|
+
return health.status < 500 ? true : undefined;
|
|
146
|
+
}, 120000);
|
|
147
|
+
return child;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function dumpEnv() {
|
|
151
|
+
console.error('ENV:', {
|
|
152
|
+
NODE_VERSION: process.version,
|
|
153
|
+
packageRoot,
|
|
154
|
+
serverRoot,
|
|
155
|
+
nextBin,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const pages = ['/', '/overview', '/knowledge', '/knowledge/files', '/knowledge/manage', '/knowledge/search', '/models', '/prompt', '/settings'];
|
|
160
|
+
const apiChecks = [
|
|
161
|
+
{ method: 'GET', path: '/api/health' },
|
|
162
|
+
{ method: 'GET', path: '/api/config/models' },
|
|
163
|
+
{ method: 'GET', path: '/api/config/providers' },
|
|
164
|
+
{ method: 'GET', path: '/api/kb/features' },
|
|
165
|
+
{ method: 'GET', path: '/api/kb/categories' },
|
|
166
|
+
{ method: 'GET', path: '/api/kb/tags' },
|
|
167
|
+
{ method: 'GET', path: '/api/kb/files', query: root => `projectRoot=${encodeURIComponent(root)}&limit=10` },
|
|
168
|
+
{ 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=5` },
|
|
170
|
+
{ method: 'GET', path: '/api/kb/duplicates', query: root => `projectRoot=${encodeURIComponent(root)}` },
|
|
171
|
+
{ method: 'GET', path: '/api/kb/operations', query: root => `projectRoot=${encodeURIComponent(root)}` },
|
|
172
|
+
{ method: 'GET', path: '/api/prompt' },
|
|
173
|
+
{ method: 'GET', path: '/api/system/stats' },
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
async function verifyWebSurface(baseUrl, root, label) {
|
|
177
|
+
for (const page of pages) {
|
|
178
|
+
const res = await request('GET', `${baseUrl}${page}`);
|
|
179
|
+
assert(res.status >= 200 && res.status < 400, `${label} page ${page} failed: ${res.status} ${res.raw.slice(0, 300)}`);
|
|
180
|
+
}
|
|
181
|
+
for (const api of apiChecks) {
|
|
182
|
+
const query = api.query ? `?${api.query(root)}` : '';
|
|
183
|
+
const res = await request(api.method, `${baseUrl}${api.path}${query}`);
|
|
184
|
+
assert(res.status >= 200 && res.status < 300, `${label} api ${api.path} failed: ${res.status} ${res.raw.slice(0, 500)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
(async () => {
|
|
189
|
+
assert(fs.existsSync(path.join(serverRoot, '.next', 'BUILD_ID')), `dashboard build not found: ${serverRoot}`);
|
|
190
|
+
|
|
191
|
+
let dashboardPid;
|
|
192
|
+
try {
|
|
193
|
+
const dashboard = await startServer(port, projectRoot, dashboardLog);
|
|
194
|
+
dashboardPid = dashboard.pid;
|
|
195
|
+
await verifyWebSurface(base, projectRoot, 'direct dashboard');
|
|
196
|
+
|
|
197
|
+
for (let i = 0; i < samples.length; i++) {
|
|
198
|
+
const sample = samples[i];
|
|
199
|
+
const uploadId = `upload-matrix-${i}-${Date.now()}`;
|
|
200
|
+
const res = await uploadSample(base, projectRoot, sample, uploadId);
|
|
201
|
+
assert(res.status === 202 && res.json.success, `${sample.name} upload failed: ${res.status} ${res.raw}`);
|
|
202
|
+
const relativePath = res.json.relativePath;
|
|
203
|
+
assert(relativePath, `${sample.name} missing relativePath`);
|
|
204
|
+
const progress = await request('GET', `${base}/api/kb/upload/progress?id=${encodeURIComponent(uploadId)}`);
|
|
205
|
+
assert(progress.status === 200, `${sample.name} progress failed: ${progress.status} ${progress.raw}`);
|
|
206
|
+
const files = await request('GET', `${base}/api/kb/files?projectRoot=${encodeURIComponent(projectRoot)}&limit=500`);
|
|
207
|
+
assert(files.status === 200, `${sample.name} files failed: ${files.status} ${files.raw}`);
|
|
208
|
+
assert(files.json.files?.some(f => f.relativePath === relativePath), `${sample.name} not listed`);
|
|
209
|
+
const reindex = await request('POST', `${base}/api/kb/files/reindex`, { projectRoot, relativePath });
|
|
210
|
+
assert(reindex.status === 200 || reindex.status === 202, `${sample.name} reindex failed: ${reindex.status} ${reindex.raw}`);
|
|
211
|
+
const detail = await waitFor(`${sample.name} indexed detail`, async () => {
|
|
212
|
+
const current = await request('GET', `${base}/api/kb/files/detail?projectRoot=${encodeURIComponent(projectRoot)}&relativePath=${encodeURIComponent(relativePath)}`);
|
|
213
|
+
if (current.status !== 200) throw new Error(`${sample.name} detail failed: ${current.status} ${current.raw}`);
|
|
214
|
+
if (current.json.file?.relativePath !== relativePath) throw new Error(`${sample.name} detail mismatch`);
|
|
215
|
+
return indexedDetail(current, sample.allowZeroChunks) ? current : undefined;
|
|
216
|
+
}, 120000);
|
|
217
|
+
if (!sample.allowZeroChunks && sample.searchable !== false) {
|
|
218
|
+
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=50&vectorWeight=1&rewriteWeight=0&keywordWeight=1`);
|
|
220
|
+
if (current.status !== 200) throw new Error(`${sample.name} search failed: ${current.status} ${current.raw}`);
|
|
221
|
+
return searchHasHit(current, relativePath, marker) ? current : undefined;
|
|
222
|
+
}, 120000);
|
|
223
|
+
assert(searchHasHit(search, relativePath, marker), `${sample.name} search did not include marker hit`);
|
|
224
|
+
}
|
|
225
|
+
console.log('UPLOAD', sample.kind, sample.name, JSON.stringify({ relativePath, chunks: detail.json.file?.chunkCount, vector: res.json.vectorStatus?.status }));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const incrementalPath = path.join(projectRoot, 'knowledgeBase', '文档资料', 'incremental-local.txt');
|
|
229
|
+
fs.mkdirSync(path.dirname(incrementalPath), { recursive: true });
|
|
230
|
+
fs.writeFileSync(incrementalPath, text('incremental-local'));
|
|
231
|
+
const reindexAll = await request('POST', `${base}/api/kb/reindex`, { projectRoot });
|
|
232
|
+
assert((reindexAll.status === 200 || reindexAll.status === 202) && reindexAll.json.success, `incremental reindex failed: ${reindexAll.status} ${reindexAll.raw}`);
|
|
233
|
+
if (reindexAll.status === 200) assert(Number(reindexAll.json.diff?.newFiles) >= 1, `incremental reindex did not detect new file: ${reindexAll.raw}`);
|
|
234
|
+
const incrementalDetail = await waitFor('incremental indexed detail', async () => {
|
|
235
|
+
const current = await request('GET', `${base}/api/kb/files/detail?projectRoot=${encodeURIComponent(projectRoot)}&relativePath=${encodeURIComponent('文档资料/incremental-local.txt')}`);
|
|
236
|
+
if (current.status !== 200) throw new Error(`incremental detail failed: ${current.status} ${current.raw}`);
|
|
237
|
+
return indexedDetail(current) ? current : undefined;
|
|
238
|
+
}, 120000);
|
|
239
|
+
assert(Number(incrementalDetail.json.file?.chunkCount) > 0, 'incremental file was not parsed/chunked');
|
|
240
|
+
|
|
241
|
+
const readyStats = await waitFor('HNSWLib vector index', async () => {
|
|
242
|
+
const stats = await request('GET', `${base}/api/kb/stats?projectRoot=${encodeURIComponent(projectRoot)}`);
|
|
243
|
+
if (stats.status !== 200) throw new Error(`stats ${stats.status} ${stats.raw}`);
|
|
244
|
+
const vector = stats.json.vectorStatus;
|
|
245
|
+
if (vector?.status === 'ready' && Number(vector.indexedChunks) >= Number(stats.json.chunkCount) && Number(stats.json.chunkCount) > 0) return stats.json;
|
|
246
|
+
return undefined;
|
|
247
|
+
}, 180000);
|
|
248
|
+
console.log('UPLOAD_VECTOR_MATRIX_OK', JSON.stringify({ files: samples.length, marker, projectRoot, chunkCount: readyStats.chunkCount, indexedChunks: readyStats.vectorStatus.indexedChunks }));
|
|
249
|
+
process.exitCode = 0;
|
|
250
|
+
} finally {
|
|
251
|
+
if (dashboardPid) { try { process.kill(dashboardPid); } catch {} }
|
|
252
|
+
}
|
|
253
|
+
})().catch(error => {
|
|
254
|
+
process.exitCode = 1;
|
|
255
|
+
console.error(error.stack || String(error));
|
|
256
|
+
dumpEnv();
|
|
257
|
+
if (fs.existsSync(dashboardLog)) console.error(fs.readFileSync(dashboardLog, 'utf8'));
|
|
258
|
+
}).finally(() => process.exit(process.exitCode ?? 0));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=7899,exports.ids=[7899],exports.modules={47899:(a,b,c)=>{c.d(b,{ee:()=>k,DB:()=>y,jt:()=>d,Ks:()=>z,Y8:()=>C,jM:()=>A,hH:()=>h,hc:()=>o,Ab:()=>p,Uv:()=>q,cA:()=>s,h2:()=>g,IA:()=>Q,ZH:()=>D,A5:()=>I,gW:()=>x,Dc:()=>B,AQ:()=>u,N3:()=>w,w7:()=>v,bu:()=>R,Wc:()=>e,ZT:()=>F,mu:()=>M,tg:()=>N,FM:()=>K,No:()=>L,QX:()=>S,Nx:()=>j,YB:()=>f,_$:()=>n,NP:()=>m,gr:()=>r,MG:()=>l,AB:()=>i,_U:()=>P,Lp:()=>t,pP:()=>O,HX:()=>E,sr:()=>H,EB:()=>G,ug:()=>J});let d={user_preference:"用户偏好",feedback:"历史纠偏",pattern:"解决方案"},e=2,f=new Set(["fact_extraction","chapter_generation","llm_review","validation","formatting","reference"]),g=new Set(["rule","table","drawing","specification","reference"]),h=80,i=[{outputType:"template_requirements",pattern:/模板|范本|章节|目录|输出要求|编制要求|template|requirement/u},{outputType:"bill_facts",pattern:/表格|列表|明细|数量|数据|table|sheet|quantity|data/u},{outputType:"drawing_facts",pattern:/设计|方案|说明|图像|地图|drawing|image|map|design/u},{outputType:"technical_facts",pattern:/规范|标准|规则|参数|技术|spec|standard|technical|rule/u},{outputType:"reference_facts",pattern:/任务|范围|事实|fact|scope|reference/u}],j=[{points:5,promptPattern:/fact|抽取|读取|提取|理解|reference/u},{points:1,promptPattern:/chapter_generation|章节生成|正文生成/u},{points:6,filePattern:/requirement|rule|template|需求|规则|模板|范本/u,promptPattern:/requirement|rule|template|需求|规则|模板|范本|章节|目录|输出要求|编制要求/u},{points:6,filePattern:/table|sheet|quantity|data|表格|列表|明细|数量|数据/u,promptPattern:/table|sheet|quantity|data|表格|列表|明细|数量|数据|字段/u},{points:6,filePattern:/drawing|image|map|design|设计|方案|说明|图像|地图/u,promptPattern:/drawing|image|map|design|设计|方案|说明|文本|标注/u},{points:6,filePattern:/material|equipment|brand|resource|材料|设备|品牌|资源/u,promptPattern:/material|equipment|brand|resource|材料|设备|品牌|资源|推荐/u},{points:6,filePattern:/schedule|quality|safety|progress|周期|质量|安全|进度/u,promptPattern:/schedule|quality|safety|progress|周期|质量|安全|进度/u},{points:6,filePattern:/risk|constraint|重点|难点|约束|风险/u,promptPattern:/risk|constraint|重点|难点|约束|风险/u}],k=/正文缺少章节标题|缺少规划小节|空小节|小节只有标题|只有标题或表格无正文|规划小节正文过短|正文篇幅明显低于目标|后台流程话术|重复 token|退化输出/u,l=/阻断|错误|正文缺少章节标题|缺少规划小节|空小节|小节只有标题|只有标题或表格无正文|规划小节正文过短|缺少必要的正式表格|事实一致性|其他项目|项目编号|项目名称|后台流程|提示词|结构化精确参数使用不足|正文未体现结构化数据资料|正文未体现设计\/方案\/说明类资料|图片|重复 token|退化输出/u,m=[{type:"missing_structure",pattern:/缺少规划小节|二级小节少于|三级小节|目录|章节|结构/u},{type:"loop_closure",pattern:/闭环|责任|检查|验收|整改|风险|安全|质量|进度/u},{type:"fact_conflict",pattern:/事实一致性|其他项目|项目编号|项目名称|冲突|污染|requiredFacts/u},{type:"terminology",pattern:/术语|名称不一致|前后不一致/u},{type:"table_numeric",pattern:/表格|量化|数值|单位|参数|结构化|数据/u},{type:"placeholder",pattern:/占位|空泛|后台流程|提示词|泄露|图片/u}],n={missing_structure:"修复重点:补齐缺失小节、修正标题层级和目录相关结构;只在相关位置追加必要正文,不重排一级章节。",loop_closure:"修复重点:补齐与问题相关的责任、措施、检查、验收、整改或记录说明;不得编造具体数据。",fact_conflict:"修复重点:删除或改正与证据冲突的名称、编号、范围、参数;不确定内容改为基于材料的表述,不得新增无来源事实。",terminology:"修复重点:统一同一对象的术语、简称和称谓,保持前后一致,不改变事实含义。",table_numeric:"修复重点:补足表格前后说明、单位、参数来源和量化表达;材料不足时不得编造精确数值。",placeholder:"修复重点:移除占位话术、后台流程话术、提示词痕迹和不允许的图片语法,替换为正文表述。",generic:"修复重点:仅针对列出问题做最小必要修改,避免全文重写。"},o=/用户要求不得|出现禁用文本|生成未完成|章节生成失败|大模型未能|重新生成|空小节|小节只有标题|只有标题或表格无正文|缺少必要表格|正文缺少章节标题|重复 token|退化输出|其他对象|其他文档|文档编号|明确事实污染|明确无来源编造|必需材料角色缺失|章节缺少证据|文档质量基准评分未达标/iu,p=/可靠精确参数使用不足/u,q=/其他对象|其他文档|文档编号|对象名称|事实一致性冲突/iu,r=[{severity:"blocking",pattern:/阻断|空小节|小节只有标题|只有标题或表格无正文|缺少必要表格|正文缺少章节标题|章节生成失败|其他对象|其他文档|文档编号|后台流程|提示词|文档质量基准评分未达标/iu},{severity:"important",pattern:/量化|数值|单位|事实|requiredFacts|闭环|安全|质量|工期|表格|三级小节|目录|术语|不一致/iu}],s={required_fact:a=>({subject:"fact",operator:"exists",target:a.target}),required_chapter:a=>({subject:"chapter",operator:"exists",target:a.target}),required_file_role:a=>({subject:"file_role",operator:"exists",target:a.target}),required_prompt_role:a=>({subject:"prompt_role",operator:"exists",target:a.target}),source_required:()=>({subject:"source",operator:"all_have_source"}),forbidden_text:a=>({subject:"document",operator:"not_contains",value:a.value}),min_chapter_length:a=>({subject:"chapter",operator:"min_length",target:a.target,min:Number(a.value)||void 0}),table_required:()=>({subject:"table",operator:"min_count",min:1})},t=[({evaluator:a,target:b,factNames:c})=>"fact"===a.subject&&"exists"===a.operator&&b&&!c.has(b)?`缺少事实 ${b}`:void 0,({evaluator:a,target:b,chapterTitles:c})=>"chapter"===a.subject&&"exists"===a.operator&&b&&!c.has(b)?`缺少章节 ${b}`:void 0,({evaluator:a,target:b,fileBindings:c})=>"file_role"===a.subject&&"exists"===a.operator&&b&&!c.some(a=>a.roleId===b)?`缺少文件角色 ${b}`:void 0,({evaluator:a,target:b,promptBindings:c})=>"prompt_role"===a.subject&&"exists"===a.operator&&b&&!c.some(a=>a.roleId===b)?`缺少提示词角色 ${b}`:void 0,({evaluator:a,value:b,markdown:c})=>"document"===a.subject&&"contains"===a.operator&&b&&!c.includes(b)?`全文必须包含 ${b}`:void 0,({evaluator:a,value:b,markdown:c})=>"document"===a.subject&&"not_contains"===a.operator&&b&&c.includes(b)?`出现禁用文本 ${b}`:void 0,({evaluator:a,value:b,regex:c,textScope:d})=>"document"!==a.subject&&"chapter"!==a.subject||"regex_match"!==a.operator||!b||c&&c.test(d)?void 0:`未匹配正则 ${b}`,({evaluator:a,value:b,regex:c,textScope:d})=>("document"===a.subject||"chapter"===a.subject)&&"regex_not_match"===a.operator&&c?.test(d)?`匹配到禁止正则 ${b}`:void 0,({evaluator:a,target:b,value:c,chapter:d})=>"chapter"===a.subject&&"contains"===a.operator&&b&&c&&(!d||!d.content.includes(c))?`章节 ${b} 必须包含 ${c}`:void 0,({evaluator:a,target:b,value:c,chapter:d})=>"chapter"===a.subject&&"not_contains"===a.operator&&d?.content.includes(c)?`章节 ${b} 出现禁用文本 ${c}`:void 0,({evaluator:a,target:b,min:c,chapter:d})=>"chapter"===a.subject&&"min_length"===a.operator&&b&&(!d||d.content.length<c)?`章节 ${b} 低于 ${c} 字`:void 0,({evaluator:a,min:b,tableBlocks:c,factsModel:d})=>"table"===a.subject&&"min_count"===a.operator&&d.tables.length+c.length<b?`表格数量少于 ${b}`:void 0,({evaluator:a,markdown:b,tableBlocks:c})=>"table"===a.subject&&"table_explanation_required"===a.operator&&function(a,b){for(let c of b){let b=a.indexOf(c);if(b>=0&&a.slice(b+c.length,b+c.length+120).trim().length<10)return!0}return!1}(b,c)?"存在缺少说明文字的表格":void 0,({evaluator:a,min:b,imageRefs:c})=>"image"===a.subject&&"min_count"===a.operator&&c.length<b?`图片数量少于 ${b}`:void 0,({evaluator:a,min:b,estimatedPages:c})=>"page"===a.subject&&"min_count"===a.operator&&c<b?`预计页数 ${c} 少于 ${b}`:void 0,({evaluator:a,min:b,estimatedPages:c})=>"page"===a.subject&&"max_count"===a.operator&&c>b?`预计页数 ${c} 超过 ${b}`:void 0,({evaluator:a,markdown:b,imageRefs:c})=>"image"===a.subject&&"image_caption_required"===a.operator&&function(a,b){for(let c of b)if(!c.alt&&a.slice(c.index+c.url.length,c.index+c.url.length+120).trim().length<10)return!0;return!1}(b,c)?"存在缺少说明文字的图片":void 0,({evaluator:a,allFacts:b})=>"source"===a.subject&&"all_have_source"===a.operator&&b.some(a=>!a.sourceFile)?"存在无来源事实":void 0,({evaluator:a,min:b,allFacts:c})=>"source"===a.subject&&"min_count"===a.operator&&function(a){let b=new Set;for(let c of a)c.sourceFile&&b.add(c.sourceFile);return b.size}(c)<b?`来源数量少于 ${b}`:void 0],u=/\n{2,}/u,v=/\|.+\|/u,w=/\n\s*\|?\s*:?-{3,}:?/u,x=/!\[([^\]]*)\]\(([^)]+)\)/gu,y=/^##\s+第[一二三四五六七八九十百]+章\s+.+$/gmu,z=/(?:文档|任务|对象)?基本信息表|资料(?:文档|任务|对象)?基本信息|^###\s*(?:文档|任务|对象)?基本信息\s*$/mu,A=/(?:文档|任务|对象)?基本信息表|资料(?:文档|任务|对象)?基本信息|\|\s*(?:字段|文档|任务|对象|内容)\s*\|/u,B=/^##\s+.+$|^###\s+.+$/gmu,C=["对象名称","对象编号","文档名称","文档编号","任务名称","任务编号","地点","责任主体","范围","周期要求","计划周期","质量标准"],D=["本节","本章将","以下从","以下内容","综上所述"],E=/^##\s+目录\s*$([\s\S]*?)(?=\n<div class="page-break"><\/div>|\n##\s+)/mu,F=/\S/u,G=/^\s*\d+\.\d+\s+\S/u,H=/^\s{2,}\d+\.\d+\s+\S/u,I=/\r?\n/u,J=/\s+/gu,K=/drawing|table|bill|boq|draw|data|sheet|spec|standard|record|report|表格|数据|规格|参数|标准|记录|报告/u,L=/(?:[A-Z]{1,8}[\w.-]*\d[\w.-]*|\d+(?:\.\d+)?\s*(?:mm|cm|m|km|㎡|m²|m3|kg|g|t|L|ml|MPa|kPa|℃|%|台|套|个|项|批|次|页|份|人|小时|分钟|天|周|月|年|万元|元)|\d+\s*[×xX]\s*\d+(?:\s*[×xX]\s*\d+)?|\b(?:GB|GB\/T|ISO|IEC|IEEE|RFC|API|DB\d*|T\/[A-Z]+)\s*[\w.-]+\b)/giu,M=20,N=.28,O=/表格|数据|列表|明细|参数|规格|数量|记录|报告|标准/u,P=/设计|方案|说明|节点|流程|步骤|尺寸|做法|配置|规则|标准/u,Q=[/见(?:资料|文件|说明|方案|附件|相关文件)/u,/按(?:资料|文件|说明|方案|规范|标准|要求)/u,/满足(?:相关|有关)?要求/u,/\|\s*(?:[/—-]|无|暂无|待定|待补充|N\/?A)\s*\|/iu],R=/^#\s+/mu,S=/(?:示例|样例|范例|例如|参考示例|示例数据|示例正文|示例目录|example|sample)\s*[::]?\s*([\s\S]{20,800}?)(?=\n\s*\n|$)/giu}};
|