@leterhong/multichat 1.6.0 → 1.7.0

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 (83) hide show
  1. package/README.md +9 -22
  2. package/backend/dist/routes/agents.js +4 -2
  3. package/backend/dist/routes/agents.js.map +1 -1
  4. package/backend/dist/routes/assistants.js +4 -2
  5. package/backend/dist/routes/assistants.js.map +1 -1
  6. package/backend/dist/routes/chat.js +45 -13
  7. package/backend/dist/routes/chat.js.map +1 -1
  8. package/backend/dist/routes/control-plane.js +25 -18
  9. package/backend/dist/routes/control-plane.js.map +1 -1
  10. package/backend/dist/routes/conversations.js +116 -30
  11. package/backend/dist/routes/conversations.js.map +1 -1
  12. package/backend/dist/routes/import.js +5 -4
  13. package/backend/dist/routes/import.js.map +1 -1
  14. package/backend/dist/routes/mock.js +3 -0
  15. package/backend/dist/routes/mock.js.map +1 -1
  16. package/backend/dist/routes/prompt-templates.js +50 -0
  17. package/backend/dist/routes/prompt-templates.js.map +1 -0
  18. package/backend/dist/routes/providers.js +15 -4
  19. package/backend/dist/routes/providers.js.map +1 -1
  20. package/backend/dist/routes/runs.js +35 -16
  21. package/backend/dist/routes/runs.js.map +1 -1
  22. package/backend/dist/routes/tools.js +15 -13
  23. package/backend/dist/routes/tools.js.map +1 -1
  24. package/backend/dist/runtime/auto-snapshot.js +73 -0
  25. package/backend/dist/runtime/auto-snapshot.js.map +1 -0
  26. package/backend/dist/server.js +3 -0
  27. package/backend/dist/server.js.map +1 -1
  28. package/backend/package.json +5 -2
  29. package/backend/routes/agents.ts +6 -4
  30. package/backend/routes/assistants.ts +4 -2
  31. package/backend/routes/chat.ts +43 -13
  32. package/backend/routes/control-plane.ts +22 -14
  33. package/backend/routes/conversations.ts +105 -29
  34. package/backend/routes/import.ts +11 -10
  35. package/backend/routes/mock.ts +4 -0
  36. package/backend/routes/prompt-templates.ts +38 -0
  37. package/backend/routes/providers.ts +14 -4
  38. package/backend/routes/runs.ts +42 -20
  39. package/backend/routes/tools.ts +14 -12
  40. package/backend/runtime/auto-snapshot.ts +60 -0
  41. package/backend/server.ts +3 -0
  42. package/bin/multichat.mjs +18 -0
  43. package/frontend/dist/assets/agentPicker-DIOlVr1C.js +18 -0
  44. package/frontend/dist/assets/assets-D2_TVEqD.js +1 -0
  45. package/frontend/dist/assets/compare-BYqbOF36.js +1 -0
  46. package/frontend/dist/assets/conversations-DSJtvviE.js +1 -0
  47. package/frontend/dist/assets/data-D6TAf2h9.js +1 -0
  48. package/frontend/dist/assets/{extensionImport-CnTWKtWm.js → extensionImport-C2cHyfeC.js} +7 -7
  49. package/frontend/dist/assets/importExport-BWpKt1dW.js +69 -0
  50. package/frontend/dist/assets/index-BaUGyQ3C.js +46 -0
  51. package/frontend/dist/assets/index-DXwClNo-.css +1 -0
  52. package/frontend/dist/assets/init-DUZJcBWS.js +1 -0
  53. package/frontend/dist/assets/modal-CO4he94s.js +2 -0
  54. package/frontend/dist/assets/modelPicker-Ddloc_nz.js +14 -0
  55. package/frontend/dist/assets/pluginsUI-28Rxtlgo.js +16 -0
  56. package/frontend/dist/assets/react-CDEwA66Z.js +1 -0
  57. package/frontend/dist/assets/{render-DgAg1K8A.js → render-BVmIwN3C.js} +1 -1
  58. package/frontend/dist/assets/send-yu3ud0kM.js +14 -0
  59. package/frontend/dist/assets/settings-IUzleKUb.js +2 -0
  60. package/frontend/dist/assets/{shell-DFV2khQl.js → shell-BLqMMR-L.js} +1 -1
  61. package/frontend/dist/assets/workbench-ChZGUESv.js +40 -0
  62. package/frontend/dist/boot-fallback.js +16 -0
  63. package/frontend/dist/icon-maskable.svg +6 -3
  64. package/frontend/dist/icon.svg +6 -3
  65. package/frontend/dist/index.html +11 -4
  66. package/frontend/dist/manifest.webmanifest +2 -2
  67. package/frontend/dist/theme-seed.js +11 -0
  68. package/package.json +4 -1
  69. package/frontend/dist/assets/agentPicker-C39VzmYa.js +0 -13
  70. package/frontend/dist/assets/compare-BpaGD32J.js +0 -1
  71. package/frontend/dist/assets/conversations-COuLmg99.js +0 -7
  72. package/frontend/dist/assets/data-ZH7Dux1K.js +0 -1
  73. package/frontend/dist/assets/importExport-B3mB-9zs.js +0 -70
  74. package/frontend/dist/assets/index-CASVCOUO.js +0 -34
  75. package/frontend/dist/assets/index-DSvbjNLc.css +0 -1
  76. package/frontend/dist/assets/init-ZPK483vB.js +0 -1
  77. package/frontend/dist/assets/jsx-runtime-ZSsbr0oW.js +0 -9
  78. package/frontend/dist/assets/modal-CgHocv3n.js +0 -2
  79. package/frontend/dist/assets/modelPicker-EUmmVnbj.js +0 -14
  80. package/frontend/dist/assets/pluginsUI-B6jGUQkx.js +0 -16
  81. package/frontend/dist/assets/send-BJhZ_5YA.js +0 -14
  82. package/frontend/dist/assets/settings-DdnYwZl-.js +0 -2
  83. package/frontend/dist/assets/workbench-BY2J4vWC.js +0 -41
@@ -1 +1 @@
1
- {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../routes/runs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../routes/runs.ts"],"names":[],"mappings":"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"}
@@ -22,19 +22,21 @@ module.exports = function registerTools(app) {
22
22
  });
23
23
  // ── 本地试跑:只开放无网络、无副作用的纯计算类工具,避免端点被当作代理 ──
24
24
  const TESTABLE_TYPES = new Set(['datetime', 'calculator']);
25
- app.post('/api/tools/:id/test', async (req, res) => {
26
- const tool = listTools().find(item => item.id === req.params.id);
27
- if (!tool)
28
- return res.status(404).json({ error: 'tool not found', code: 'NOT_FOUND' });
29
- if (!TESTABLE_TYPES.has(tool.type)) {
30
- return res.status(400).json({ error: `「${tool.name}」暂不支持界面试跑(涉及网络访问,请通过对话调用)`, code: 'NOT_TESTABLE' });
31
- }
32
- const args = tool.type === 'calculator'
33
- ? { expression: String(req.body?.expression ?? '').trim() }
34
- : {};
35
- const started = Date.now();
36
- const result = await agent.executeSkill(tool, args);
37
- res.json({ ...result, elapsedMs: Date.now() - started });
25
+ app.post('/api/tools/:id/test', (req, res, next) => {
26
+ void (async () => {
27
+ const tool = listTools().find(item => item.id === req.params.id);
28
+ if (!tool)
29
+ return res.status(404).json({ error: 'tool not found', code: 'NOT_FOUND' });
30
+ if (!TESTABLE_TYPES.has(tool.type)) {
31
+ return res.status(400).json({ error: `「${tool.name}」暂不支持界面试跑(涉及网络访问,请通过对话调用)`, code: 'NOT_TESTABLE' });
32
+ }
33
+ const args = tool.type === 'calculator'
34
+ ? { expression: String(req.body?.expression ?? '').trim() }
35
+ : {};
36
+ const started = Date.now();
37
+ const result = await agent.executeSkill(tool, args);
38
+ res.json({ ...result, elapsedMs: Date.now() - started });
39
+ })().catch(next);
38
40
  });
39
41
  };
40
42
  //# sourceMappingURL=tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../routes/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../routes/tools.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AACtC,MAAM,KAAK,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAE1C,SAAS,SAAS;IAChB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC;SACtC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtD,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,SAAS,aAAa,CAAC,GAAG;IACzC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC3D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1G,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC3F,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,0CAA0C;IAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3D,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YACvF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,2BAA2B,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;YACzG,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,YAAY;gBACrC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC3D,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACpD,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runAutoSnapshotSweep = runAutoSnapshotSweep;
4
+ exports.startAutoSnapshots = startAutoSnapshots;
5
+ // ── 每日自动快照:为每个项目在距上次自动快照 ≥24h 时创建一份,并只保留最近 N 份自动快照 ──
6
+ // 手动创建的项目快照永不参与清理。MULTICHAT_AUTO_SNAPSHOT=0 可整体关闭。
7
+ const ctx = require('../lib/context');
8
+ const controlPlane = require('../routes/control-plane');
9
+ const SWEEP_INTERVAL_MS = 6 * 60 * 60 * 1000; // 每 6 小时巡检一次,是否到期由 24h 阈值判断
10
+ const DUE_MS = 24 * 60 * 60 * 1000;
11
+ const KEEP = Math.max(1, Number(process.env.MULTICHAT_AUTO_SNAPSHOT_KEEP || 7));
12
+ const AUTO_TITLE_PREFIX = '自动快照 ';
13
+ function isAutomatic(row) { return row.automatic === true || String(row.title || '').startsWith(AUTO_TITLE_PREFIX); }
14
+ function runAutoSnapshotSweep(nowMs = Date.now()) {
15
+ if (process.env.MULTICHAT_AUTO_SNAPSHOT === '0')
16
+ return { created: [], pruned: 0, disabled: true };
17
+ const created = [];
18
+ let pruned = 0;
19
+ const projects = ctx.workspaceStore.projects();
20
+ const assets = ctx.workspaceStore.assets();
21
+ const memories = ctx.store.read('memories.json', []);
22
+ const rows = ctx.store.read('snapshots.json', []);
23
+ for (const project of projects) {
24
+ const hasRecoverableState = assets.some(item => item.projectId === project.id)
25
+ || memories.some(item => item.projectId === project.id)
26
+ || Boolean(project.defaultAgentId || project.defaultProviderId || project.defaultModel);
27
+ // A fresh inbox/project has nothing to recover. Skipping it avoids a daily
28
+ // stream of empty snapshots that obscures meaningful restore points.
29
+ if (!hasRecoverableState)
30
+ continue;
31
+ const autoRows = rows
32
+ .filter(row => row.projectId === project.id && isAutomatic(row))
33
+ .sort((a, b) => String(b.createdAt).localeCompare(String(a.createdAt)));
34
+ const newest = autoRows[0]?.createdAt ? Date.parse(autoRows[0].createdAt) : 0;
35
+ if (Number.isFinite(newest) && nowMs - newest < DUE_MS)
36
+ continue;
37
+ try {
38
+ const row = controlPlane.makeSnapshot(project.id, { title: AUTO_TITLE_PREFIX + new Date(nowMs).toISOString().slice(0, 10) }, true);
39
+ created.push({ projectId: project.id, id: row.id, title: row.title });
40
+ }
41
+ catch { /* 单个项目失败(如超大文件)不阻断其他项目 */ }
42
+ }
43
+ if (created.length) {
44
+ const all = ctx.store.read('snapshots.json', []);
45
+ const keep = new Set();
46
+ for (const project of ctx.workspaceStore.projects()) {
47
+ all.filter(row => row.projectId === project.id && isAutomatic(row))
48
+ .sort((a, b) => String(b.createdAt).localeCompare(String(a.createdAt)))
49
+ .slice(0, KEEP)
50
+ .forEach(row => keep.add(row.id));
51
+ }
52
+ const next = all.filter(row => !isAutomatic(row) || keep.has(row.id));
53
+ pruned = all.length - next.length;
54
+ if (pruned > 0)
55
+ ctx.store.write('snapshots.json', next);
56
+ }
57
+ return { created, pruned };
58
+ }
59
+ function startAutoSnapshots() {
60
+ if (process.env.MULTICHAT_AUTO_SNAPSHOT === '0')
61
+ return;
62
+ const boot = setTimeout(() => { try {
63
+ runAutoSnapshotSweep();
64
+ }
65
+ catch { } }, 2 * 60 * 1000);
66
+ const timer = setInterval(() => { try {
67
+ runAutoSnapshotSweep();
68
+ }
69
+ catch { } }, SWEEP_INTERVAL_MS);
70
+ boot.unref?.();
71
+ timer.unref?.();
72
+ }
73
+ //# sourceMappingURL=auto-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-snapshot.js","sourceRoot":"","sources":["../../runtime/auto-snapshot.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAab,oDAuCC;AAED,gDAKC;AA1DD,uDAAuD;AACvD,mDAAmD;AACnD,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AACtC,MAAM,YAAY,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAExD,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,4BAA4B;AAC1E,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,CAAC,CAAC,CAAC;AAChF,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAElC,SAAS,WAAW,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAErH,SAAgB,oBAAoB,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACnG,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAClD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CAAC;eACzE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CAAC;eACpD,OAAO,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;QAC1F,2EAA2E;QAC3E,qEAAqE;QACrE,IAAI,CAAC,mBAAmB;YAAE,SAAS;QACnC,MAAM,QAAQ,GAAG,IAAI;aAClB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;aAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,MAAM,GAAG,MAAM;YAAE,SAAS;QACjE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACnI,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;iBAChE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;iBACtE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;iBACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAClC,IAAI,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,kBAAkB;IAChC,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG;QAAE,OAAO;IACxD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAAC,oBAAoB,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3F,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAAC,oBAAoB,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACjG,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;IAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;AAClC,CAAC"}
@@ -63,6 +63,7 @@ require('./routes/conversations')(app);
63
63
  require('./routes/workspaces')(app);
64
64
  require('./routes/assistants')(app);
65
65
  require('./routes/runs')(app);
66
+ require('./routes/prompt-templates')(app);
66
67
  require('./routes/usage')(app);
67
68
  require('./routes/control-plane')(app);
68
69
  require('./routes/skills')(app);
@@ -84,6 +85,8 @@ app.use(errorHandler);
84
85
  // ── 启动 ──
85
86
  runtime.ensureSeed();
86
87
  require('./extensions/manager').ensureDefaults();
88
+ // 每日自动快照调度(可用 MULTICHAT_AUTO_SNAPSHOT=0 关闭)
89
+ require("./runtime/auto-snapshot").startAutoSnapshots();
87
90
  const server = app.listen(PORT, HOST, () => {
88
91
  console.log(`Multi-model chat server running on http://${HOST}:${PORT}`);
89
92
  console.log(`OpenAI-compatible endpoint: POST /v1/chat/completions`);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multichat-backend",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "private": true,
5
5
  "type": "commonjs",
6
6
  "description": "MultiChat backend — Express-based multi-model Agent platform",
@@ -9,7 +9,7 @@
9
9
  "build": "tsc -p tsconfig.build.json",
10
10
  "start": "node dist/server.js",
11
11
  "dev": "tsx watch server.ts",
12
- "test": "tsc -p tsconfig.test.json && node --test .test-dist/tests/*.test.js",
12
+ "test": "tsc -p tsconfig.test.json && node --test --test-concurrency=1 .test-dist/tests/*.test.js",
13
13
  "lint": "eslint . --ext .ts,.cjs --max-warnings 99999",
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
@@ -22,6 +22,9 @@
22
22
  "cors": "^2.8.5",
23
23
  "express": "^4.19.2"
24
24
  },
25
+ "overrides": {
26
+ "qs": "^6.16.0"
27
+ },
25
28
  "devDependencies": {
26
29
  "@types/express": "^4.17.21",
27
30
  "@types/node": "^22.10.0",
@@ -27,9 +27,10 @@ module.exports = function registerAgents(app) {
27
27
  });
28
28
  app.post('/api/agents', (req, res) => {
29
29
  const agents = ctx.store.read(ctx.AGENT_FILE, []);
30
+ const input = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
30
31
  const agent = normalizeCapabilityRefs(
31
- { id: 'ag_' + Date.now().toString(36), skillIds: [], skillRefs: [], toolIds: [], mcpServerIds: [], systemPrompt: '', createdAt: new Date().toISOString(), ...req.body },
32
- !Array.isArray(req.body?.toolIds),
32
+ { skillIds: [], skillRefs: [], toolIds: [], mcpServerIds: [], systemPrompt: '', ...input, id: 'ag_' + Date.now().toString(36), createdAt: new Date().toISOString() },
33
+ !Array.isArray(input.toolIds),
33
34
  );
34
35
  agents.push(agent);
35
36
  ctx.store.write(ctx.AGENT_FILE, agents);
@@ -39,9 +40,10 @@ module.exports = function registerAgents(app) {
39
40
  const agents = ctx.store.read(ctx.AGENT_FILE, []);
40
41
  const idx = agents.findIndex(a => a.id === req.params.id);
41
42
  if (idx < 0) return res.status(404).json({ error: 'not found' });
43
+ const input = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
42
44
  agents[idx] = normalizeCapabilityRefs(
43
- { ...agents[idx], ...req.body, id: req.params.id },
44
- !Array.isArray(req.body?.toolIds),
45
+ { ...agents[idx], ...input, id: req.params.id, createdAt: agents[idx].createdAt },
46
+ !Array.isArray(input.toolIds),
45
47
  );
46
48
  ctx.store.write(ctx.AGENT_FILE, agents);
47
49
  res.json(agents[idx]);
@@ -8,7 +8,8 @@ module.exports = function registerAssistants(app) {
8
8
  });
9
9
  app.post('/api/assistants', (req, res) => {
10
10
  const assistants = ctx.store.read('assistants.json', []);
11
- const assistant = { id: Date.now().toString(36), ...req.body };
11
+ const input = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
12
+ const assistant = { ...input, id: Date.now().toString(36) };
12
13
  assistants.push(assistant);
13
14
  ctx.store.write('assistants.json', assistants);
14
15
  res.json(assistant);
@@ -17,7 +18,8 @@ module.exports = function registerAssistants(app) {
17
18
  const assistants = ctx.store.read('assistants.json', []);
18
19
  const idx = assistants.findIndex(a => a.id === req.params.id);
19
20
  if (idx < 0) return res.status(404).json({ error: 'not found' });
20
- assistants[idx] = { ...assistants[idx], ...req.body, id: req.params.id };
21
+ const input = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
22
+ assistants[idx] = { ...assistants[idx], ...input, id: req.params.id };
21
23
  ctx.store.write('assistants.json', assistants);
22
24
  res.json(assistants[idx]);
23
25
  });
@@ -39,13 +39,34 @@ function usageContext(body, provider, modelName, extra: JsonRecord = {}) {
39
39
  };
40
40
  }
41
41
 
42
+ async function recordUsageSafely(store, entry) {
43
+ try {
44
+ await usageLedger.recordUsage(store, entry);
45
+ } catch (error) {
46
+ // Usage telemetry must never turn an otherwise valid chat response into a
47
+ // failed request. Keep the failure visible to operators without exposing
48
+ // credentials or upstream response bodies.
49
+ console.error('Usage persistence error:', redactSecrets(error?.message || String(error)));
50
+ }
51
+ }
52
+
53
+ function requestValidationError(body, { allowResume = false } = {}) {
54
+ if (!String(body.model || '').trim()) return 'model 不能为空';
55
+ if ((!allowResume || !body.resumeFromRunId) && (!Array.isArray(body.messages) || body.messages.length === 0)) {
56
+ return 'messages 必须是非空数组';
57
+ }
58
+ return '';
59
+ }
60
+
42
61
  module.exports = function registerChat(app) {
43
62
  // ── OpenAI 兼容统一端点(透传上游,做 SSE 适配) ──
44
63
  app.post('/v1/chat/completions', async (req, res) => {
45
- const body = req.body;
64
+ const body = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
46
65
  const requestStartedAt = new Date().toISOString();
47
66
  const requestStartedMs = Date.now();
48
- const requestedModel = body.model || '';
67
+ const validationError = requestValidationError(body);
68
+ if (validationError) return res.status(400).json({ error: { message: validationError }, code: 'BAD_REQUEST' });
69
+ const requestedModel = String(body.model).trim();
49
70
 
50
71
  // model format: "providerId:modelName" or plain "modelName"
51
72
  // modelName may contain colons (e.g. Ollama: "llama3:latest")
@@ -118,7 +139,7 @@ module.exports = function registerChat(app) {
118
139
  }, allowPrivateProvider(provider));
119
140
  if (!upstream.ok) {
120
141
  const errText = await readResponseText(upstream, 128_000);
121
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
142
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
122
143
  timestamp: requestStartedAt, durationMs: Date.now() - requestStartedMs,
123
144
  interactionId: body.interactionId || res.locals?.requestId, mode: 'chat', status: 'error', errorCode: `HTTP_${upstream.status}`,
124
145
  usage: { input: 0, output: 0, total: 0, source: 'estimated' },
@@ -139,7 +160,7 @@ module.exports = function registerChat(app) {
139
160
  let observedUsage: JsonRecord = {};
140
161
  let output = '';
141
162
 
142
- (async () => {
163
+ void (async () => {
143
164
  let status = 'success';
144
165
  try {
145
166
  while (true) {
@@ -169,7 +190,7 @@ module.exports = function registerChat(app) {
169
190
  console.error('Stream read error:', redactSecrets(e.message));
170
191
  } finally {
171
192
  const normalized = usageLedger.normalizeUsage(observedUsage, messages, output);
172
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
193
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
173
194
  timestamp: requestStartedAt, durationMs: Date.now() - requestStartedMs,
174
195
  interactionId: body.interactionId || res.locals?.requestId, mode: 'chat', status,
175
196
  usage: normalized,
@@ -179,12 +200,19 @@ module.exports = function registerChat(app) {
179
200
  res.end();
180
201
  }
181
202
  }
182
- })();
203
+ })().catch((error) => {
204
+ console.error('Stream finalization error:', redactSecrets(error?.message || String(error)));
205
+ if (!res.writableEnded && !res.destroyed) {
206
+ res.write(`data: ${JSON.stringify({ error: { message: '流式响应意外中断' } })}\n\n`);
207
+ res.write('data: [DONE]\n\n');
208
+ res.end();
209
+ }
210
+ });
183
211
  } else {
184
212
  const data = await readResponseJson(upstream, 20_000_000);
185
213
  const transformed = adapter.transformResponse(data);
186
214
  const output = transformed?.choices?.[0]?.message?.content || '';
187
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
215
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
188
216
  timestamp: requestStartedAt, durationMs: Date.now() - requestStartedMs,
189
217
  interactionId: body.interactionId || res.locals?.requestId, mode: 'chat', status: 'success',
190
218
  usage: usageLedger.normalizeUsage(transformed.usage, messages, output),
@@ -194,7 +222,7 @@ module.exports = function registerChat(app) {
194
222
  } catch (err) {
195
223
  const safeMessage = redactSecrets(err.message);
196
224
  console.error('Upstream error:', safeMessage);
197
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
225
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
198
226
  timestamp: requestStartedAt, durationMs: Date.now() - requestStartedMs,
199
227
  interactionId: body.interactionId || res.locals?.requestId, mode: 'chat', status: err.name === 'AbortError' ? 'cancelled' : 'error', errorCode: err.name || 'UPSTREAM_ERROR',
200
228
  usage: { input: 0, output: 0, total: 0, source: 'estimated' },
@@ -212,7 +240,9 @@ module.exports = function registerChat(app) {
212
240
  if (!found) return res.status(404).json({ error: { message: 'Agent not found: ' + req.params.id } });
213
241
 
214
242
  const body = req.body || {};
215
- const requestedModel = body.model || '';
243
+ const validationError = requestValidationError(body, { allowResume: true });
244
+ if (validationError) return res.status(400).json({ error: { message: validationError }, code: 'BAD_REQUEST' });
245
+ const requestedModel = String(body.model).trim();
216
246
  const explicitProviderId = String(body.providerId || body.provider || '').trim();
217
247
  const colonIdx = requestedModel.indexOf(':');
218
248
  let providerId, modelName;
@@ -414,7 +444,7 @@ module.exports = function registerChat(app) {
414
444
  emit('step_update', modelStep);
415
445
  run.status = cancelled ? 'cancelled' : 'error';
416
446
  run.error = modelStep.error;
417
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
447
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
418
448
  timestamp: modelStep.startedAt, durationMs: Date.parse(modelStep.finishedAt) - Date.parse(modelStep.startedAt),
419
449
  interactionId: run.id, runId: run.id, mode: 'agent', status: run.status, errorCode: cancelled ? 'CANCELLED' : 'NETWORK_ERROR', step: iter,
420
450
  usage: { input: 0, output: 0, total: 0, source: 'estimated' },
@@ -432,7 +462,7 @@ module.exports = function registerChat(app) {
432
462
  emit('step_update', modelStep);
433
463
  run.status = 'error';
434
464
  run.error = modelStep.error;
435
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
465
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
436
466
  timestamp: modelStep.startedAt, durationMs: Date.parse(modelStep.finishedAt) - Date.parse(modelStep.startedAt),
437
467
  interactionId: run.id, runId: run.id, mode: 'agent', status: 'error', errorCode: `HTTP_${upstream.status}`, step: iter,
438
468
  usage: { input: 0, output: 0, total: 0, source: 'estimated' },
@@ -448,7 +478,7 @@ module.exports = function registerChat(app) {
448
478
  emit('step_update', modelStep);
449
479
  run.status = 'error';
450
480
  run.error = modelStep.error;
451
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
481
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
452
482
  timestamp: modelStep.startedAt, durationMs: Date.parse(modelStep.finishedAt) - Date.parse(modelStep.startedAt),
453
483
  interactionId: run.id, runId: run.id, mode: 'agent', status: 'error', errorCode: 'EMPTY_BODY', step: iter,
454
484
  usage: { input: 0, output: 0, total: 0, source: 'estimated' },
@@ -526,7 +556,7 @@ module.exports = function registerChat(app) {
526
556
  run.usage.reasoningTokens += normalized.reasoning;
527
557
  if (normalized.source === 'reported') run.usage.reportedTokens += normalized.total;
528
558
  else run.usage.estimatedTokens += normalized.total;
529
- await usageLedger.recordUsage(ctx.store, usageContext(body, provider, modelName, {
559
+ await recordUsageSafely(ctx.store, usageContext(body, provider, modelName, {
530
560
  timestamp: modelStep.startedAt, durationMs: modelStep.durationMs,
531
561
  interactionId: run.id, runId: run.id, mode: 'agent', status: 'success', step: iter,
532
562
  usage: normalized,
@@ -95,21 +95,25 @@ module.exports = function registerControlPlane(app) {
95
95
  res.status(201).json(row);
96
96
  } catch (error) { res.status(400).json({ error: error.message }); }
97
97
  });
98
- app.put('/api/memories/:id', async (req, res) => {
99
- let updated = null;
100
- await ctx.store.mutate(MEMORY_FILE, rows => rows.map(item => {
101
- if (item.id !== req.params.id) return item;
102
- updated = { ...item, ...(req.body.title !== undefined ? { title: cleanText(req.body.title, 120) } : {}), ...(req.body.content !== undefined ? { content: cleanText(req.body.content, 4000) } : {}), ...(req.body.enabled !== undefined ? { enabled: req.body.enabled === true } : {}), updatedAt: now() };
103
- return updated;
104
- }), []);
105
- if (!updated) return res.status(404).json({ error: 'memory not found' });
106
- res.json(updated);
98
+ app.put('/api/memories/:id', (req, res, next) => {
99
+ void (async () => {
100
+ let updated = null;
101
+ await ctx.store.mutate(MEMORY_FILE, rows => rows.map(item => {
102
+ if (item.id !== req.params.id) return item;
103
+ updated = { ...item, ...(req.body.title !== undefined ? { title: cleanText(req.body.title, 120) } : {}), ...(req.body.content !== undefined ? { content: cleanText(req.body.content, 4000) } : {}), ...(req.body.enabled !== undefined ? { enabled: req.body.enabled === true } : {}), updatedAt: now() };
104
+ return updated;
105
+ }), []);
106
+ if (!updated) return res.status(404).json({ error: 'memory not found' });
107
+ res.json(updated);
108
+ })().catch(next);
107
109
  });
108
- app.delete('/api/memories/:id', async (req, res) => {
109
- let found = false;
110
- await ctx.store.mutate(MEMORY_FILE, rows => rows.filter(item => { if (item.id === req.params.id) found = true; return item.id !== req.params.id; }), []);
111
- if (!found) return res.status(404).json({ error: 'memory not found' });
112
- res.json({ ok: true });
110
+ app.delete('/api/memories/:id', (req, res, next) => {
111
+ void (async () => {
112
+ let found = false;
113
+ await ctx.store.mutate(MEMORY_FILE, rows => rows.filter(item => { if (item.id === req.params.id) found = true; return item.id !== req.params.id; }), []);
114
+ if (!found) return res.status(404).json({ error: 'memory not found' });
115
+ res.json({ ok: true });
116
+ })().catch(next);
113
117
  });
114
118
 
115
119
  app.get('/api/projects/:id/search', (req, res) => {
@@ -163,3 +167,7 @@ module.exports = function registerControlPlane(app) {
163
167
  res.json({ ok: true });
164
168
  });
165
169
  };
170
+
171
+ // 供每日自动快照调度复用
172
+ module.exports.makeSnapshot = makeSnapshot;
173
+ module.exports.snapshotRows = snapshotRows;