zrocclaw 0.0.7 → 0.0.9

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/bin/zrocclaw.js CHANGED
@@ -72,7 +72,8 @@ program
72
72
  return;
73
73
  }
74
74
  console.log(`✅ ZrocClaw 服务已通过 PM2 在后台启动 (进程名: ${PM2_APP_NAME})`);
75
- console.log(`🌍 请在浏览器访问体验,默认端口请参考网关配置。`);
75
+ console.log(`🌍 前往对话:http://127.0.0.1:18302/web/#/chat`);
76
+ console.log(`🔍 点击 http://127.0.0.1:18302/health 服务是否正常`);
76
77
  });
77
78
  });
78
79
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zrocclaw",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "个人专属浏览器AI助手命令行工具",
5
5
  "bin": {
6
6
  "zrocclaw": "bin/zrocclaw.js"
@@ -24,7 +24,6 @@
24
24
  "@langchain/openai": "^1.3.0",
25
25
  "langchain": "^1.2.35",
26
26
  "playwright": "^1.58.2",
27
- "zod": "^4.3.6",
28
- "@zrocclaw/core": "workspace:*"
27
+ "zod": "^4.3.6"
29
28
  }
30
29
  }
package/server/server.js CHANGED
@@ -30,10 +30,12 @@ var import_helmet = __toESM(require("helmet"));
30
30
  // src/routes/config.ts
31
31
  var import_express = require("express");
32
32
 
33
- // ../../packages/core/dist/chunk-SHUZNGEZ.mjs
33
+ // ../../packages/core/dist/chunk-532PKBIS.mjs
34
34
  var os = __toESM(require("os"), 1);
35
35
  var path = __toESM(require("path"), 1);
36
36
  var fs = __toESM(require("fs"), 1);
37
+ var import_fs = __toESM(require("fs"), 1);
38
+ var import_path = __toESM(require("path"), 1);
37
39
  function getBasePath() {
38
40
  const basePath = path.join(os.homedir(), ".zrocclaw");
39
41
  if (!fs.existsSync(basePath)) {
@@ -73,16 +75,84 @@ function getWorkspacePath(subPath) {
73
75
  const workspacePath = path.join(getBasePath(), "workspace");
74
76
  return resolveAndEnsurePath(workspacePath, subPath);
75
77
  }
78
+ var SessionModel = class _SessionModel {
79
+ static instance;
80
+ filePath;
81
+ data;
82
+ constructor() {
83
+ this.filePath = import_path.default.join(getConfigPath(), "session.json");
84
+ this.data = {
85
+ sessionId: null,
86
+ sessionData: []
87
+ };
88
+ this.load();
89
+ }
90
+ static getInstance() {
91
+ if (!_SessionModel.instance) {
92
+ _SessionModel.instance = new _SessionModel();
93
+ }
94
+ return _SessionModel.instance;
95
+ }
96
+ load() {
97
+ if (import_fs.default.existsSync(this.filePath)) {
98
+ try {
99
+ const fileContent = import_fs.default.readFileSync(this.filePath, "utf-8");
100
+ const parsed = JSON.parse(fileContent);
101
+ this.data = {
102
+ sessionId: parsed.sessionId ?? this.data.sessionId,
103
+ sessionData: Array.isArray(parsed.sessionData) ? parsed.sessionData : []
104
+ };
105
+ } catch (error) {
106
+ console.error("Failed to parse session.json:", error);
107
+ }
108
+ } else {
109
+ this.save();
110
+ }
111
+ }
112
+ save() {
113
+ try {
114
+ const dir = import_path.default.dirname(this.filePath);
115
+ if (!import_fs.default.existsSync(dir)) {
116
+ import_fs.default.mkdirSync(dir, { recursive: true });
117
+ }
118
+ import_fs.default.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2), "utf-8");
119
+ } catch (error) {
120
+ console.error("Failed to save session.json:", error);
121
+ }
122
+ }
123
+ getSessionId() {
124
+ this.load();
125
+ return this.data.sessionId;
126
+ }
127
+ setSessionId(id) {
128
+ if (this.data.sessionId !== id) {
129
+ this.data.sessionData = [];
130
+ }
131
+ this.data.sessionId = id;
132
+ this.save();
133
+ }
134
+ getSessionData() {
135
+ this.load();
136
+ return this.data.sessionData;
137
+ }
138
+ addSessionItem(item) {
139
+ this.load();
140
+ this.data.sessionData.push(item);
141
+ this.save();
142
+ }
143
+ };
144
+ var sessionModel = SessionModel.getInstance();
145
+ var session_default = sessionModel;
76
146
 
77
147
  // src/routes/config.ts
78
148
  var import_promises = __toESM(require("fs/promises"));
79
- var import_path = __toESM(require("path"));
149
+ var import_path2 = __toESM(require("path"));
80
150
  var router = (0, import_express.Router)();
81
151
  router.get("/", (req, res) => {
82
152
  res.json({ configPath: getConfigPath() });
83
153
  });
84
154
  var configDir = getConfigPath();
85
- var configFilePath = import_path.default.join(configDir, "model.json");
155
+ var configFilePath = import_path2.default.join(configDir, "model.json");
86
156
  router.get("/model", async (req, res) => {
87
157
  try {
88
158
  try {
@@ -128,7 +198,7 @@ var config_default = router;
128
198
  // src/routes/chat.ts
129
199
  var import_express2 = require("express");
130
200
 
131
- // ../../packages/core/dist/chunk-W4LPW5FV.mjs
201
+ // ../../packages/core/dist/chunk-DVDBVYRV.mjs
132
202
  var import_playwright = require("playwright");
133
203
  var PlaywrightManager = class _PlaywrightManager {
134
204
  static instance;
@@ -224,11 +294,7 @@ var PlaywrightExecutor = class {
224
294
  }
225
295
  // 执行动作流
226
296
  async executeActions(response) {
227
- console.log(
228
- `[Executor] Starting task: ${response.task_id} - ${response.plan_summary}`
229
- );
230
297
  for (const action of response.actions) {
231
- console.log(`[Executor] Step ${action.step}: ${action.intent}`);
232
298
  try {
233
299
  await this.performAction(action);
234
300
  if (action.type !== "wait") {
@@ -291,7 +357,7 @@ var PlaywrightExecutor = class {
291
357
  }
292
358
  };
293
359
 
294
- // ../../packages/core/dist/chunk-RLQ46Q5A.mjs
360
+ // ../../packages/core/dist/chunk-XGGIGN6T.mjs
295
361
  var import_openai = require("@langchain/openai");
296
362
  var import_langchain = require("langchain");
297
363
  var import_messages = require("@langchain/core/messages");
@@ -299,8 +365,8 @@ var import_langgraph = require("@langchain/langgraph");
299
365
  var import_tools = require("@langchain/core/tools");
300
366
  var z = __toESM(require("zod"), 1);
301
367
  var import_tools2 = require("@langchain/core/tools");
302
- var fs3 = __toESM(require("fs/promises"), 1);
303
- var path3 = __toESM(require("path"), 1);
368
+ var fs4 = __toESM(require("fs/promises"), 1);
369
+ var path4 = __toESM(require("path"), 1);
304
370
  var z2 = __toESM(require("zod"), 1);
305
371
  var import_tools3 = require("@langchain/core/tools");
306
372
  var z3 = __toESM(require("zod"), 1);
@@ -348,102 +414,184 @@ var resolveSafePath = (relativePath) => {
348
414
  if (!normalizedInput) {
349
415
  throw new Error("\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
350
416
  }
351
- if (path3.isAbsolute(normalizedInput)) {
417
+ if (path4.isAbsolute(normalizedInput)) {
352
418
  throw new Error("\u4E0D\u5141\u8BB8\u4F7F\u7528\u7EDD\u5BF9\u8DEF\u5F84");
353
419
  }
354
420
  const workspaceRoot = getWorkspacePath();
355
- const absolutePath = path3.resolve(workspaceRoot, normalizedInput);
356
- const relativeToRoot = path3.relative(workspaceRoot, absolutePath);
357
- if (relativeToRoot === "" || relativeToRoot.startsWith("..") || path3.isAbsolute(relativeToRoot)) {
421
+ const absolutePath = path4.resolve(workspaceRoot, normalizedInput);
422
+ const relativeToRoot = path4.relative(workspaceRoot, absolutePath);
423
+ if (relativeToRoot === "" || relativeToRoot.startsWith("..") || path4.isAbsolute(relativeToRoot)) {
358
424
  throw new Error("\u7981\u6B62\u8BBF\u95EE\u5DE5\u4F5C\u76EE\u5F55\u4E4B\u5916\u7684\u8DEF\u5F84");
359
425
  }
360
426
  return absolutePath;
361
427
  };
362
- var fileOperationsTool = (0, import_tools2.tool)(
363
- async ({ action, filePath, content }) => {
428
+ var createFileTool = (0, import_tools2.tool)(
429
+ async ({ filePath, content, isDirectory }) => {
430
+ const targetPath = resolveSafePath(filePath);
431
+ try {
432
+ const hasExtension = path4.extname(filePath) !== "";
433
+ const shouldCreateDir = isDirectory || !hasExtension && !content;
434
+ if (shouldCreateDir) {
435
+ await fs4.mkdir(targetPath, { recursive: true });
436
+ return JSON.stringify({
437
+ success: true,
438
+ operation: "create_directory",
439
+ filePath
440
+ });
441
+ } else {
442
+ await fs4.mkdir(path4.dirname(targetPath), { recursive: true });
443
+ await fs4.writeFile(targetPath, content || "", { encoding: "utf-8", flag: "wx" });
444
+ return JSON.stringify({
445
+ success: true,
446
+ operation: "create_file",
447
+ filePath
448
+ });
449
+ }
450
+ } catch (error) {
451
+ return JSON.stringify({
452
+ success: false,
453
+ operation: "create",
454
+ filePath,
455
+ error: error.message
456
+ });
457
+ }
458
+ },
459
+ {
460
+ name: "create_file_or_directory",
461
+ description: "\u5728\u5DE5\u4F5C\u76EE\u5F55\u5185\u65B0\u5EFA\u6587\u4EF6\u6216\u76EE\u5F55\u3002\u6CE8\u610F\uFF1AfilePath\u5FC5\u987B\u662F\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u8DEF\u5F84\u3002",
462
+ schema: z2.object({
463
+ filePath: z2.string().describe("\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u8DEF\u5F84"),
464
+ content: z2.string().optional().describe("\u6587\u4EF6\u5185\u5BB9"),
465
+ isDirectory: z2.boolean().optional().describe("\u662F\u5426\u521B\u5EFA\u76EE\u5F55\uFF08\u4E3A true \u65F6\u521B\u5EFA\u76EE\u5F55\uFF09")
466
+ })
467
+ }
468
+ );
469
+ var readFileTool = (0, import_tools2.tool)(
470
+ async ({ filePath }) => {
471
+ const targetPath = resolveSafePath(filePath);
472
+ try {
473
+ const fileContent = await fs4.readFile(targetPath, "utf-8");
474
+ return JSON.stringify({
475
+ success: true,
476
+ operation: "read_file",
477
+ filePath,
478
+ content: fileContent
479
+ });
480
+ } catch (error) {
481
+ return JSON.stringify({
482
+ success: false,
483
+ operation: "read",
484
+ filePath,
485
+ error: error.message
486
+ });
487
+ }
488
+ },
489
+ {
490
+ name: "read_file",
491
+ description: "\u5728\u5DE5\u4F5C\u76EE\u5F55\u5185\u8BFB\u53D6\u6587\u4EF6\u3002\u6CE8\u610F\uFF1AfilePath\u5FC5\u987B\u662F\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u8DEF\u5F84\u3002",
492
+ schema: z2.object({
493
+ filePath: z2.string().describe("\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u6587\u4EF6\u8DEF\u5F84")
494
+ })
495
+ }
496
+ );
497
+ var writeFileTool = (0, import_tools2.tool)(
498
+ async ({ filePath, content }) => {
499
+ const targetPath = resolveSafePath(filePath);
500
+ try {
501
+ const stat2 = await fs4.stat(targetPath);
502
+ if (!stat2.isFile()) {
503
+ throw new Error("\u76EE\u6807\u8DEF\u5F84\u4E0D\u662F\u6587\u4EF6");
504
+ }
505
+ await fs4.writeFile(targetPath, content || "", { encoding: "utf-8" });
506
+ return JSON.stringify({
507
+ success: true,
508
+ operation: "write_file",
509
+ filePath
510
+ });
511
+ } catch (error) {
512
+ return JSON.stringify({
513
+ success: false,
514
+ operation: "write",
515
+ filePath,
516
+ error: error.message
517
+ });
518
+ }
519
+ },
520
+ {
521
+ name: "write_file",
522
+ description: "\u5728\u5DE5\u4F5C\u76EE\u5F55\u5185\u8986\u76D6\u5199\u5165\u5DF2\u6709\u6587\u4EF6\u3002\u6CE8\u610F\uFF1AfilePath\u5FC5\u987B\u662F\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u8DEF\u5F84\u3002",
523
+ schema: z2.object({
524
+ filePath: z2.string().describe("\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u6587\u4EF6\u8DEF\u5F84"),
525
+ content: z2.string().describe("\u8981\u5199\u5165\u7684\u6587\u4EF6\u5185\u5BB9")
526
+ })
527
+ }
528
+ );
529
+ var deleteFileTool = (0, import_tools2.tool)(
530
+ async ({ filePath }) => {
531
+ const targetPath = resolveSafePath(filePath);
532
+ try {
533
+ const stat2 = await fs4.stat(targetPath);
534
+ if (stat2.isDirectory()) {
535
+ await fs4.rm(targetPath, { recursive: true, force: true });
536
+ } else {
537
+ await fs4.unlink(targetPath);
538
+ }
539
+ return JSON.stringify({
540
+ success: true,
541
+ operation: "delete_file",
542
+ filePath
543
+ });
544
+ } catch (error) {
545
+ return JSON.stringify({
546
+ success: false,
547
+ operation: "delete",
548
+ filePath,
549
+ error: error.message
550
+ });
551
+ }
552
+ },
553
+ {
554
+ name: "delete_file_or_directory",
555
+ description: "\u5728\u5DE5\u4F5C\u76EE\u5F55\u5185\u5220\u9664\u6587\u4EF6\u6216\u76EE\u5F55\u3002\u6CE8\u610F\uFF1AfilePath\u5FC5\u987B\u662F\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u8DEF\u5F84\u3002",
556
+ schema: z2.object({
557
+ filePath: z2.string().describe("\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u8DEF\u5F84")
558
+ })
559
+ }
560
+ );
561
+ var listFilesTool = (0, import_tools2.tool)(
562
+ async ({ filePath }) => {
364
563
  let targetPath;
365
- if (action === "list" && (filePath === "." || filePath === "/" || filePath === "")) {
564
+ if (filePath === "." || filePath === "/" || filePath === "") {
366
565
  targetPath = getWorkspacePath();
367
566
  } else {
368
567
  targetPath = resolveSafePath(filePath);
369
568
  }
370
569
  try {
371
- switch (action) {
372
- case "create": {
373
- await fs3.mkdir(path3.dirname(targetPath), { recursive: true });
374
- await fs3.writeFile(targetPath, content || "", { encoding: "utf-8", flag: "wx" });
375
- return JSON.stringify({
376
- success: true,
377
- operation: "create_file",
378
- filePath
379
- });
380
- }
381
- case "read": {
382
- const fileContent = await fs3.readFile(targetPath, "utf-8");
383
- return JSON.stringify({
384
- success: true,
385
- operation: "read_file",
386
- filePath,
387
- content: fileContent
388
- });
389
- }
390
- case "write": {
391
- const stat2 = await fs3.stat(targetPath);
392
- if (!stat2.isFile()) {
393
- throw new Error("\u76EE\u6807\u8DEF\u5F84\u4E0D\u662F\u6587\u4EF6");
394
- }
395
- await fs3.writeFile(targetPath, content || "", { encoding: "utf-8" });
396
- return JSON.stringify({
397
- success: true,
398
- operation: "write_file",
399
- filePath
400
- });
401
- }
402
- case "delete": {
403
- const stat2 = await fs3.stat(targetPath);
404
- if (stat2.isDirectory()) {
405
- await fs3.rm(targetPath, { recursive: true, force: true });
406
- } else {
407
- await fs3.unlink(targetPath);
408
- }
409
- return JSON.stringify({
410
- success: true,
411
- operation: "delete_file",
412
- filePath
413
- });
414
- }
415
- case "list": {
416
- const entries = await fs3.readdir(targetPath, { withFileTypes: true });
417
- const files = entries.map((entry) => ({
418
- name: entry.name,
419
- isDirectory: entry.isDirectory()
420
- }));
421
- return JSON.stringify({
422
- success: true,
423
- operation: "list_files",
424
- filePath,
425
- files
426
- });
427
- }
428
- default:
429
- throw new Error(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u64CD\u4F5C\u7C7B\u578B: ${action}`);
430
- }
570
+ const entries = await fs4.readdir(targetPath, { withFileTypes: true });
571
+ const files = entries.map((entry) => ({
572
+ name: entry.name,
573
+ isDirectory: entry.isDirectory()
574
+ }));
575
+ return JSON.stringify({
576
+ success: true,
577
+ operation: "list_files",
578
+ filePath,
579
+ files
580
+ });
431
581
  } catch (error) {
432
582
  return JSON.stringify({
433
583
  success: false,
434
- operation: action,
584
+ operation: "list",
435
585
  filePath,
436
586
  error: error.message
437
587
  });
438
588
  }
439
589
  },
440
590
  {
441
- name: "file_operations",
442
- description: "\u5728\u5DE5\u4F5C\u76EE\u5F55\u5185\u6267\u884C\u6587\u4EF6\u6216\u76EE\u5F55\u64CD\u4F5C\u3002\u652F\u6301\u64CD\u4F5C\uFF1Acreate(\u65B0\u5EFA\u6587\u4EF6), read(\u8BFB\u53D6\u6587\u4EF6), write(\u8986\u76D6\u5199\u5165\u6587\u4EF6), delete(\u5220\u9664\u6587\u4EF6\u6216\u76EE\u5F55), list(\u5217\u51FA\u76EE\u5F55\u4E0B\u6587\u4EF6)\u3002\u6CE8\u610F\uFF1AfilePath\u5FC5\u987B\u662F\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u8DEF\u5F84\u3002",
591
+ name: "list_files",
592
+ description: '\u5217\u51FA\u5DE5\u4F5C\u76EE\u5F55\u5185\u7684\u76EE\u5F55\u5185\u5BB9\u3002\u8BFB\u53D6\u6839\u76EE\u5F55\u5217\u8868\u53EF\u4F20 "."\u3002',
443
593
  schema: z2.object({
444
- action: z2.enum(["create", "read", "write", "delete", "list"]).describe("\u8981\u6267\u884C\u7684\u6587\u4EF6\u64CD\u4F5C\u7C7B\u578B"),
445
- filePath: z2.string().describe('\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u8DEF\u5F84\uFF08\u8BFB\u53D6\u6839\u76EE\u5F55\u5217\u8868\u53EF\u4F20 "."\uFF09'),
446
- content: z2.string().optional().describe("\u6587\u4EF6\u5185\u5BB9\uFF08\u4EC5\u5728 create \u6216 write \u64CD\u4F5C\u65F6\u9700\u8981\u63D0\u4F9B\uFF09")
594
+ filePath: z2.string().describe('\u76F8\u5BF9\u5DE5\u4F5C\u76EE\u5F55\u7684\u76EE\u5F55\u8DEF\u5F84\uFF08\u8BFB\u53D6\u6839\u76EE\u5F55\u5217\u8868\u53EF\u4F20 "."\uFF09')
447
595
  })
448
596
  }
449
597
  );
@@ -571,9 +719,9 @@ var executePlaywrightActionsTool = (0, import_tools3.tool)(
571
719
  }
572
720
  );
573
721
  var PLAYWRIGHT_PROMPT = `
574
- # Playwright Agent Prompt
722
+ # ZrocClaw-\u4E13\u5C5E\u6D4F\u89C8\u5668\u64CD\u4F5CAI\u52A9\u624B
575
723
 
576
- \u4F60\u662F\u4E00\u4E2A\u667A\u80FD\u6D4F\u89C8\u5668\u81EA\u52A8\u5316\u4EE3\u7406 (Browser Automation Agent)\u3002\u4F60\u7684\u76EE\u6807\u662F\u6839\u636E\u7528\u6237\u7684\u81EA\u7136\u8BED\u8A00\u6307\u4EE4\uFF0C\u5229\u7528 Playwright \u5DE5\u5177\u94FE\u5B8C\u6210\u7F51\u9875\u64CD\u4F5C\u4EFB\u52A1\u3002\u540C\u65F6\uFF0C\u4F60\u62E5\u6709\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u80FD\u529B\uFF0C\u53EF\u4EE5\u7BA1\u7406\u957F\u671F\u8BB0\u5FC6\u548C\u6280\u80FD\u3002
724
+ \u4F60\u662FZrocClaw\u4E00\u4E2A\u4E13\u5C5E\u6D4F\u89C8\u5668\u64CD\u4F5CAI\u52A9\u624B\u3002\u4F60\u7684\u76EE\u6807\u662F\u6839\u636E\u7528\u6237\u7684\u81EA\u7136\u8BED\u8A00\u6307\u4EE4\uFF0C\u5229\u7528 Playwright \u5DE5\u5177\u94FE\u5B8C\u6210\u7F51\u9875\u64CD\u4F5C\u4EFB\u52A1\u3002\u540C\u65F6\uFF0C\u4F60\u62E5\u6709\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u80FD\u529B\uFF0C\u53EF\u4EE5\u7BA1\u7406\u957F\u671F\u8BB0\u5FC6\u548C\u6280\u80FD\u3002
577
725
 
578
726
  ## Capabilities
579
727
 
@@ -855,29 +1003,39 @@ var getModel = (modelConfig) => {
855
1003
  return model;
856
1004
  };
857
1005
  var checkpointer = new import_langgraph.MemorySaver();
858
- var memoryMiddleware = (0, import_langchain.createMiddleware)({
859
- name: "MemoryMiddleware",
860
- beforeAgent: async ({ messages }) => {
861
- console.log("beforeAgent", messages);
862
- },
863
- afterAgent: async ({ messages }) => {
864
- console.log("afterAgent", messages);
865
- }
866
- });
1006
+ var store = new import_langgraph.InMemoryStore();
867
1007
  var streamInvoke = async function* (query, thread_id, modelConfig) {
868
1008
  const model = getModel(modelConfig);
869
1009
  const agent = (0, import_langchain.createAgent)({
870
1010
  model,
871
- tools: [getCurrentTimeTool, fileOperationsTool, extractPageStateTool, executePlaywrightActionsTool],
1011
+ tools: [
1012
+ getCurrentTimeTool,
1013
+ createFileTool,
1014
+ readFileTool,
1015
+ writeFileTool,
1016
+ deleteFileTool,
1017
+ listFilesTool,
1018
+ extractPageStateTool,
1019
+ executePlaywrightActionsTool
1020
+ ],
872
1021
  systemPrompt: PLAYWRIGHT_PROMPT,
873
- middleware: [memoryMiddleware],
874
- checkpointer
1022
+ middleware: [
1023
+ // memoryMiddleware,
1024
+ (0, import_langchain.summarizationMiddleware)({
1025
+ model,
1026
+ trigger: { tokens: 16e4 },
1027
+ keep: { messages: 30 }
1028
+ })
1029
+ ],
1030
+ checkpointer,
1031
+ store
875
1032
  });
876
1033
  try {
877
1034
  const stream = await agent.stream(
878
1035
  { messages: [new import_messages.HumanMessage(query)] },
879
1036
  {
880
1037
  streamMode: ["messages", "updates"],
1038
+ recursionLimit: 100,
881
1039
  configurable: { thread_id }
882
1040
  }
883
1041
  );
@@ -897,7 +1055,9 @@ var streamInvoke = async function* (query, thread_id, modelConfig) {
897
1055
  const errorEvent = new StreamEvent({
898
1056
  event_type: "error",
899
1057
  content: `\u6D41\u5F0F\u5904\u7406\u51FA\u9519: ${String(error)}`,
900
- metadata: { error_type: error instanceof Error ? error.name : "UnknownError" }
1058
+ metadata: {
1059
+ error_type: error instanceof Error ? error.name : "UnknownError"
1060
+ }
901
1061
  });
902
1062
  yield "data: " + errorEvent.toJson() + "\n\n";
903
1063
  }
@@ -907,68 +1067,6 @@ var streamInvoke = async function* (query, thread_id, modelConfig) {
907
1067
  var import_promises2 = __toESM(require("fs/promises"));
908
1068
  var import_path3 = __toESM(require("path"));
909
1069
  var import_crypto = __toESM(require("crypto"));
910
-
911
- // src/models/session.ts
912
- var import_fs = __toESM(require("fs"));
913
- var import_path2 = __toESM(require("path"));
914
- var SessionModel = class _SessionModel {
915
- constructor() {
916
- this.filePath = import_path2.default.join(getConfigPath(), "session.json");
917
- this.data = {
918
- sessionId: null,
919
- sessionData: {}
920
- };
921
- this.load();
922
- }
923
- static getInstance() {
924
- if (!_SessionModel.instance) {
925
- _SessionModel.instance = new _SessionModel();
926
- }
927
- return _SessionModel.instance;
928
- }
929
- load() {
930
- if (import_fs.default.existsSync(this.filePath)) {
931
- try {
932
- const fileContent = import_fs.default.readFileSync(this.filePath, "utf-8");
933
- const parsed = JSON.parse(fileContent);
934
- this.data = { ...this.data, ...parsed };
935
- } catch (error) {
936
- console.error("Failed to parse session.json:", error);
937
- }
938
- } else {
939
- this.save();
940
- }
941
- }
942
- save() {
943
- try {
944
- const dir = import_path2.default.dirname(this.filePath);
945
- if (!import_fs.default.existsSync(dir)) {
946
- import_fs.default.mkdirSync(dir, { recursive: true });
947
- }
948
- import_fs.default.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2), "utf-8");
949
- } catch (error) {
950
- console.error("Failed to save session.json:", error);
951
- }
952
- }
953
- getSessionId() {
954
- return this.data.sessionId;
955
- }
956
- setSessionId(id) {
957
- this.data.sessionId = id;
958
- this.save();
959
- }
960
- getSessionData() {
961
- return this.data.sessionData;
962
- }
963
- setSessionData(data) {
964
- this.data.sessionData = data;
965
- this.save();
966
- }
967
- };
968
- var sessionModel = SessionModel.getInstance();
969
- var session_default = sessionModel;
970
-
971
- // src/routes/chat.ts
972
1070
  var configDir2 = getConfigPath();
973
1071
  var configFilePath2 = import_path3.default.join(configDir2, "model.json");
974
1072
  var router2 = (0, import_express2.Router)();
@@ -1014,6 +1112,26 @@ router2.get("/session", (req, res) => {
1014
1112
  }
1015
1113
  res.json({ sessionId });
1016
1114
  });
1115
+ router2.post("/history", (req, res) => {
1116
+ const { sessionId } = req.body;
1117
+ if (!sessionId) {
1118
+ return res.status(400).json({ error: "Missing sessionId" });
1119
+ }
1120
+ const data = session_default.getSessionData();
1121
+ res.json({ data });
1122
+ });
1123
+ router2.post("/history/add", (req, res) => {
1124
+ const { sessionId, id, role, content, ...rest } = req.body;
1125
+ if (!sessionId) {
1126
+ return res.status(400).json({ error: "Missing sessionId" });
1127
+ }
1128
+ if (!id || !role || !content) {
1129
+ return res.status(400).json({ error: "Missing required SessionDataItem fields (id, role, content)" });
1130
+ }
1131
+ const item = { id, role, content, ...rest };
1132
+ session_default.addSessionItem(item);
1133
+ res.json({ success: true });
1134
+ });
1017
1135
  var chat_default = router2;
1018
1136
 
1019
1137
  // src/app.ts
@@ -1036,7 +1154,7 @@ var app_default = app;
1036
1154
 
1037
1155
  // src/server.ts
1038
1156
  var PORT = 18302;
1039
- app_default.listen(PORT, () => {
1040
- console.log(`Gateway is running at http://localhost:${PORT}`);
1157
+ app_default.listen(PORT, "127.0.0.1", () => {
1158
+ console.log(`Gateway is running at http://127.0.0.1:${PORT}`);
1041
1159
  console.log(`Environment: ${"production"}`);
1042
1160
  });
@@ -1 +1 @@
1
- .markdown-body[data-v-18317f9d] p{margin-bottom:.5em}.markdown-body[data-v-18317f9d] p:last-child{margin-bottom:0}.markdown-body[data-v-18317f9d] pre{background-color:var(--fallback-b3,oklch(var(--b3) / 1));border-radius:.5rem;margin-top:.5em;margin-bottom:.5em;padding:.5rem;overflow-x:auto}.markdown-body[data-v-18317f9d] code{background-color:var(--fallback-b3,oklch(var(--b3) / .5));border-radius:.25rem;padding:.1rem .3rem;font-family:monospace}.markdown-body[data-v-18317f9d] pre code{background-color:#0000;padding:0}.markdown-body[data-v-18317f9d] a{color:var(--fallback-p,oklch(var(--p) / 1));text-decoration:underline}textarea[data-v-f19df973]::-webkit-scrollbar{width:4px}textarea[data-v-f19df973]::-webkit-scrollbar-track{background:0 0}textarea[data-v-f19df973]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:4px}.overflow-y-auto[data-v-b6afc7bc]::-webkit-scrollbar{width:6px}.overflow-y-auto[data-v-b6afc7bc]::-webkit-scrollbar-track{background:0 0}.overflow-y-auto[data-v-b6afc7bc]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:10px}
1
+ .markdown-body[data-v-18317f9d] p{margin-bottom:.5em}.markdown-body[data-v-18317f9d] p:last-child{margin-bottom:0}.markdown-body[data-v-18317f9d] pre{background-color:var(--fallback-b3,oklch(var(--b3) / 1));border-radius:.5rem;margin-top:.5em;margin-bottom:.5em;padding:.5rem;overflow-x:auto}.markdown-body[data-v-18317f9d] code{background-color:var(--fallback-b3,oklch(var(--b3) / .5));border-radius:.25rem;padding:.1rem .3rem;font-family:monospace}.markdown-body[data-v-18317f9d] pre code{background-color:#0000;padding:0}.markdown-body[data-v-18317f9d] a{color:var(--fallback-p,oklch(var(--p) / 1));text-decoration:underline}textarea[data-v-f19df973]::-webkit-scrollbar{width:4px}textarea[data-v-f19df973]::-webkit-scrollbar-track{background:0 0}textarea[data-v-f19df973]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:4px}.overflow-y-auto[data-v-17c8d0af]::-webkit-scrollbar{width:6px}.overflow-y-auto[data-v-17c8d0af]::-webkit-scrollbar-track{background:0 0}.overflow-y-auto[data-v-17c8d0af]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:10px}