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 +2 -1
- package/package.json +2 -3
- package/server/server.js +281 -163
- package/server/static/assets/{Chat-DUc2YNA1.css → Chat-DESWEJOR.css} +1 -1
- package/server/static/assets/Chat-Hyshyebd.js +15 -0
- package/server/static/assets/Config-CA88hlfK.js +1 -0
- package/server/static/assets/Welcome-rn5evpg8.js +1 -0
- package/server/static/assets/{index-Dh0OZbcj.css → index-B546EPyO.css} +1 -1
- package/server/static/assets/index-CbKn96gV.js +2 -0
- package/server/static/assets/runtime-core.esm-bundler-DEKlsnJd.js +1 -0
- package/server/static/index.html +3 -3
- package/server/static/assets/Chat-9YnlTybN.js +0 -15
- package/server/static/assets/Config-iHT4yGKm.js +0 -1
- package/server/static/assets/Welcome-ChEkTj3S.js +0 -1
- package/server/static/assets/index-CPxNZVgF.js +0 -2
- package/server/static/assets/runtime-core.esm-bundler-CWHhnmHT.js +0 -1
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.
|
|
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-
|
|
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
|
|
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 =
|
|
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-
|
|
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-
|
|
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
|
|
303
|
-
var
|
|
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 (
|
|
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 =
|
|
356
|
-
const relativeToRoot =
|
|
357
|
-
if (relativeToRoot === "" || relativeToRoot.startsWith("..") ||
|
|
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
|
|
363
|
-
async ({
|
|
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 (
|
|
564
|
+
if (filePath === "." || filePath === "/" || filePath === "") {
|
|
366
565
|
targetPath = getWorkspacePath();
|
|
367
566
|
} else {
|
|
368
567
|
targetPath = resolveSafePath(filePath);
|
|
369
568
|
}
|
|
370
569
|
try {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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:
|
|
584
|
+
operation: "list",
|
|
435
585
|
filePath,
|
|
436
586
|
error: error.message
|
|
437
587
|
});
|
|
438
588
|
}
|
|
439
589
|
},
|
|
440
590
|
{
|
|
441
|
-
name: "
|
|
442
|
-
description:
|
|
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
|
-
|
|
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
|
-
#
|
|
722
|
+
# ZrocClaw-\u4E13\u5C5E\u6D4F\u89C8\u5668\u64CD\u4F5CAI\u52A9\u624B
|
|
575
723
|
|
|
576
|
-
\u4F60\
|
|
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
|
|
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: [
|
|
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: [
|
|
874
|
-
|
|
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: {
|
|
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://
|
|
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-
|
|
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}
|