engine7 7.0.3 → 7.0.4
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/dist/cli.mjs
CHANGED
|
@@ -40,6 +40,7 @@ Engine 7 \u2014 Self-hosted AI agent engine
|
|
|
40
40
|
\u7528\u6CD5:
|
|
41
41
|
engine7 init --state-dir <path> [\u9009\u9879] \u521D\u59CB\u5316 agent \u5DE5\u4F5C\u76EE\u5F55
|
|
42
42
|
engine7 start [--config <path>] \u542F\u52A8 Engine
|
|
43
|
+
engine7 service install|uninstall|status \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
43
44
|
|
|
44
45
|
init \u9009\u9879:
|
|
45
46
|
--state-dir <path> agent \u6839\u76EE\u5F55\uFF08\u5FC5\u586B\uFF0C\u652F\u6301\u76F8\u5BF9\u8DEF\u5F84\uFF09
|
|
@@ -92,6 +93,7 @@ function getDefaultValues(stateDir) {
|
|
|
92
93
|
feishuAppId: "",
|
|
93
94
|
feishuAppSecret: "",
|
|
94
95
|
feishuOpenId: "",
|
|
96
|
+
tavilyKey: "",
|
|
95
97
|
apiPort: 16990
|
|
96
98
|
};
|
|
97
99
|
}
|
|
@@ -157,6 +159,8 @@ async function interactiveConfig(rl, defaults) {
|
|
|
157
159
|
v.feishuAppSecret = await ask(rl, "\u98DE\u4E66 App Secret");
|
|
158
160
|
v.feishuOpenId = await ask(rl, "\u4F60\u7684\u98DE\u4E66 open_id");
|
|
159
161
|
}
|
|
162
|
+
const tavilyKey = await ask(rl, "Tavily API Key\uFF08\u8054\u7F51\u641C\u7D22\uFF0C\u56DE\u8F66\u8DF3\u8FC7\uFF09", "");
|
|
163
|
+
v.tavilyKey = tavilyKey;
|
|
160
164
|
const portAns = await ask(rl, "API \u7AEF\u53E3", String(defaults.apiPort));
|
|
161
165
|
v.apiPort = parseInt(portAns, 10) || defaults.apiPort;
|
|
162
166
|
return v;
|
|
@@ -170,7 +174,7 @@ function generateConfig(v) {
|
|
|
170
174
|
models: {
|
|
171
175
|
providers: {}
|
|
172
176
|
},
|
|
173
|
-
tools: {},
|
|
177
|
+
tools: v.tavilyKey ? { tavily: { apiKey: v.tavilyKey } } : {},
|
|
174
178
|
session: { dmScope: "main", groupScope: "main" },
|
|
175
179
|
sandbox: { mode: "off" },
|
|
176
180
|
display: {
|
|
@@ -321,6 +325,7 @@ function buildDirTree(v) {
|
|
|
321
325
|
type: "file",
|
|
322
326
|
content: readTemplate("workspace/prompts/contacts.md").replace("{{DISCORD_USER_ID}}", v.discordUserId || "YOUR_DISCORD_ID").replace("{{FEISHU_OPEN_ID}}", v.feishuOpenId || "YOUR_FEISHU_OPEN_ID")
|
|
323
327
|
},
|
|
328
|
+
{ path: path.join(w, "prompts", "auto-memory-instructions.md"), type: "file", content: readTemplate("workspace/prompts/auto-memory-instructions.md") },
|
|
324
329
|
{ path: path.join(w, "MEMORY.md"), type: "file", content: "# MEMORY.md \u2014 \u8BB0\u5FC6\u6587\u4EF6\u7D22\u5F15\n\n> \u6700\u540E\u66F4\u65B0\uFF1A\u521D\u59CB\u5316\n" },
|
|
325
330
|
{ path: path.join(w, "USER.md"), type: "file", content: "# USER.md \u2014 \u7528\u6237\u4FE1\u606F\n\n\uFF08\u5728\u8FD9\u91CC\u8BB0\u5F55\u7528\u6237\u7684\u504F\u597D\u3001\u80CC\u666F\u7B49\uFF09\n" },
|
|
326
331
|
// package.json — 让 agent 目录成为独立 npm 项目根,防止 npm hoisting
|
|
@@ -510,6 +515,171 @@ engine7 start \u2014 \u542F\u52A8 Engine
|
|
|
510
515
|
child.on("exit", (code) => process.exit(code ?? 1));
|
|
511
516
|
return;
|
|
512
517
|
}
|
|
518
|
+
if (subcommand === "service") {
|
|
519
|
+
const action = args[1];
|
|
520
|
+
if (!action || action === "--help" || action === "-h") {
|
|
521
|
+
console.log(`
|
|
522
|
+
engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
523
|
+
|
|
524
|
+
\u7528\u6CD5:
|
|
525
|
+
engine7 service install \u5B89\u88C5\u5F00\u673A\u81EA\u542F\u52A8
|
|
526
|
+
engine7 service uninstall \u5378\u8F7D\u5F00\u673A\u81EA\u542F\u52A8
|
|
527
|
+
engine7 service status \u67E5\u770B\u72B6\u6001
|
|
528
|
+
|
|
529
|
+
\u9009\u9879:
|
|
530
|
+
--config <path> \u6307\u5B9A config \u6587\u4EF6\uFF08\u9ED8\u8BA4: configs/main7.json\uFF09
|
|
531
|
+
--cwd <path> engine7 \u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4: \u5F53\u524D\u76EE\u5F55\uFF09
|
|
532
|
+
`);
|
|
533
|
+
process.exit(0);
|
|
534
|
+
}
|
|
535
|
+
let configPath2 = "";
|
|
536
|
+
let cwd = process.cwd();
|
|
537
|
+
for (let i = 2; i < args.length; i++) {
|
|
538
|
+
if (args[i] === "--config" && args[i + 1]) configPath2 = args[++i];
|
|
539
|
+
else if (args[i] === "--cwd" && args[i + 1]) cwd = args[++i];
|
|
540
|
+
}
|
|
541
|
+
if (!configPath2) {
|
|
542
|
+
const defaultCfg = path.join(cwd, "configs", "main7.json");
|
|
543
|
+
configPath2 = fs.existsSync(defaultCfg) ? defaultCfg : path.join(cwd, "configs", "main7.json");
|
|
544
|
+
}
|
|
545
|
+
const { execSync } = await import("node:child_process");
|
|
546
|
+
const engine7Bin = process.argv[1];
|
|
547
|
+
if (action === "install") {
|
|
548
|
+
if (process.platform === "win32") {
|
|
549
|
+
const taskName = "Engine7";
|
|
550
|
+
const cmd = `"${engine7Bin}" start --config "${path.resolve(configPath2)}"`;
|
|
551
|
+
try {
|
|
552
|
+
execSync(`schtasks /create /tn "${taskName}" /tr "${cmd}" /sc onlogon /rl highest /f`, { stdio: "inherit", shell: true });
|
|
553
|
+
console.log(`\u2705 Windows \u8BA1\u5212\u4EFB\u52A1 "${taskName}" \u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
|
|
554
|
+
} catch {
|
|
555
|
+
console.error("\u274C \u521B\u5EFA\u8BA1\u5212\u4EFB\u52A1\u5931\u8D25\uFF0C\u53EF\u80FD\u9700\u8981\u7BA1\u7406\u5458\u6743\u9650");
|
|
556
|
+
process.exit(1);
|
|
557
|
+
}
|
|
558
|
+
} else if (process.platform === "darwin") {
|
|
559
|
+
const label = "com.engine7.agent";
|
|
560
|
+
const plistDir = path.join(process.env.HOME, "Library", "LaunchAgents");
|
|
561
|
+
fs.mkdirSync(plistDir, { recursive: true });
|
|
562
|
+
const plistPath = path.join(plistDir, `${label}.plist`);
|
|
563
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
564
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
565
|
+
<plist version="1.0">
|
|
566
|
+
<dict>
|
|
567
|
+
<key>Label</key><string>${label}</string>
|
|
568
|
+
<key>ProgramArguments</key>
|
|
569
|
+
<array>
|
|
570
|
+
<string>${process.execPath}</string>
|
|
571
|
+
<string>${engine7Bin}</string>
|
|
572
|
+
<string>start</string>
|
|
573
|
+
<string>--config</string>
|
|
574
|
+
<string>${path.resolve(configPath2)}</string>
|
|
575
|
+
</array>
|
|
576
|
+
<key>WorkingDirectory</key><string>${cwd}</string>
|
|
577
|
+
<key>RunAtLoad</key><true/>
|
|
578
|
+
<key>KeepAlive</key><true/>
|
|
579
|
+
</dict>
|
|
580
|
+
</plist>`;
|
|
581
|
+
fs.writeFileSync(plistPath, plist);
|
|
582
|
+
try {
|
|
583
|
+
execSync(`launchctl load "${plistPath}"`, { stdio: "inherit" });
|
|
584
|
+
console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
|
|
585
|
+
console.log(` ${plistPath}`);
|
|
586
|
+
} catch {
|
|
587
|
+
console.error("\u274C launchctl load \u5931\u8D25");
|
|
588
|
+
process.exit(1);
|
|
589
|
+
}
|
|
590
|
+
} else {
|
|
591
|
+
const svcName = "engine7";
|
|
592
|
+
const svcDir = path.join(process.env.HOME, ".config", "systemd", "user");
|
|
593
|
+
fs.mkdirSync(svcDir, { recursive: true });
|
|
594
|
+
const svcPath = path.join(svcDir, `${svcName}.service`);
|
|
595
|
+
const svc = `[Unit]
|
|
596
|
+
Description=Engine 7 Agent
|
|
597
|
+
After=network.target
|
|
598
|
+
|
|
599
|
+
[Service]
|
|
600
|
+
Type=simple
|
|
601
|
+
WorkingDirectory=${cwd}
|
|
602
|
+
ExecStart=${process.execPath} ${engine7Bin} start --config ${path.resolve(configPath2)}
|
|
603
|
+
Restart=on-failure
|
|
604
|
+
RestartSec=10
|
|
605
|
+
|
|
606
|
+
[Install]
|
|
607
|
+
WantedBy=default.target`;
|
|
608
|
+
fs.writeFileSync(svcPath, svc);
|
|
609
|
+
try {
|
|
610
|
+
execSync(`systemctl --user daemon-reload`, { stdio: "inherit" });
|
|
611
|
+
execSync(`systemctl --user enable ${svcName}`, { stdio: "inherit" });
|
|
612
|
+
console.log(`\u2705 systemd \u7528\u6237\u670D\u52A1\u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
|
|
613
|
+
console.log(` ${svcPath}`);
|
|
614
|
+
} catch {
|
|
615
|
+
console.error("\u274C systemctl enable \u5931\u8D25");
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
} else if (action === "uninstall") {
|
|
620
|
+
if (process.platform === "win32") {
|
|
621
|
+
try {
|
|
622
|
+
execSync(`schtasks /delete /tn "Engine7" /f`, { stdio: "inherit", shell: true });
|
|
623
|
+
console.log(`\u2705 Windows \u8BA1\u5212\u4EFB\u52A1\u5DF2\u5220\u9664`);
|
|
624
|
+
} catch {
|
|
625
|
+
console.error("\u274C \u5220\u9664\u5931\u8D25\uFF0C\u4EFB\u52A1\u53EF\u80FD\u4E0D\u5B58\u5728");
|
|
626
|
+
process.exit(1);
|
|
627
|
+
}
|
|
628
|
+
} else if (process.platform === "darwin") {
|
|
629
|
+
const plistPath = path.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
|
|
630
|
+
try {
|
|
631
|
+
execSync(`launchctl unload "${plistPath}"`, { stdio: "inherit" });
|
|
632
|
+
} catch {
|
|
633
|
+
}
|
|
634
|
+
try {
|
|
635
|
+
fs.unlinkSync(plistPath);
|
|
636
|
+
} catch {
|
|
637
|
+
}
|
|
638
|
+
console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u5220\u9664`);
|
|
639
|
+
} else {
|
|
640
|
+
try {
|
|
641
|
+
execSync(`systemctl --user disable engine7`, { stdio: "inherit" });
|
|
642
|
+
} catch {
|
|
643
|
+
}
|
|
644
|
+
const svcPath = path.join(process.env.HOME, ".config", "systemd", "user", "engine7.service");
|
|
645
|
+
try {
|
|
646
|
+
fs.unlinkSync(svcPath);
|
|
647
|
+
} catch {
|
|
648
|
+
}
|
|
649
|
+
try {
|
|
650
|
+
execSync(`systemctl --user daemon-reload`, { stdio: "inherit" });
|
|
651
|
+
} catch {
|
|
652
|
+
}
|
|
653
|
+
console.log(`\u2705 systemd \u7528\u6237\u670D\u52A1\u5DF2\u5220\u9664`);
|
|
654
|
+
}
|
|
655
|
+
} else if (action === "status") {
|
|
656
|
+
if (process.platform === "win32") {
|
|
657
|
+
try {
|
|
658
|
+
execSync(`schtasks /query /tn "Engine7"`, { stdio: "inherit", shell: true });
|
|
659
|
+
} catch {
|
|
660
|
+
console.log("\u274C \u672A\u5B89\u88C5");
|
|
661
|
+
}
|
|
662
|
+
} else if (process.platform === "darwin") {
|
|
663
|
+
const plistPath = path.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
|
|
664
|
+
if (fs.existsSync(plistPath)) {
|
|
665
|
+
console.log("\u2705 \u5DF2\u5B89\u88C5\uFF08launchd\uFF09");
|
|
666
|
+
} else {
|
|
667
|
+
console.log("\u274C \u672A\u5B89\u88C5");
|
|
668
|
+
}
|
|
669
|
+
} else {
|
|
670
|
+
try {
|
|
671
|
+
execSync(`systemctl --user is-enabled engine7`, { stdio: "inherit" });
|
|
672
|
+
} catch {
|
|
673
|
+
console.log("\u274C \u672A\u5B89\u88C5");
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
} else {
|
|
677
|
+
console.error(`\u274C \u672A\u77E5\u64CD\u4F5C: ${action}`);
|
|
678
|
+
console.error(" \u7528\u6CD5: engine7 service install|uninstall|status");
|
|
679
|
+
process.exit(1);
|
|
680
|
+
}
|
|
681
|
+
process.exit(0);
|
|
682
|
+
}
|
|
513
683
|
const opts = parseArgs();
|
|
514
684
|
console.log(`
|
|
515
685
|
\u{1F680} engine7 init`);
|
package/package.json
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# auto memory
|
|
2
|
+
|
|
3
|
+
You have a persistent, file-based memory system. Write to it directly with the Write tool.
|
|
4
|
+
|
|
5
|
+
Build up memory over time: who the user is, how they like to collaborate, what to avoid or repeat, and context behind their work.
|
|
6
|
+
|
|
7
|
+
## When to save
|
|
8
|
+
- User explicitly asks to remember something → save immediately
|
|
9
|
+
- Learn new preferences, role details, decisions, or surprising feedback → save
|
|
10
|
+
- Don't save: code patterns, file paths, project structure, git history, ephemeral task state
|
|
11
|
+
|
|
12
|
+
## Types
|
|
13
|
+
- **user** — role, goals, knowledge, preferences
|
|
14
|
+
- **feedback** — corrections + validated approaches (include *why*)
|
|
15
|
+
- **project** — ongoing work, decisions, milestones (convert relative dates to absolute)
|
|
16
|
+
- **reference** — pointers to external systems
|
|
17
|
+
- **emotion** — 关系里程碑、深度对话、情感转折点
|
|
18
|
+
|
|
19
|
+
## How to save
|
|
20
|
+
1. Write the memory file to `topics/{type}/{name}.md` with frontmatter
|
|
21
|
+
2. Add a one-line pointer to `topics/MEMORY.md` index
|
|
22
|
+
|
|
23
|
+
## Recall
|
|
24
|
+
每轮对话会自动把相关的记忆送到你面前(`<system-reminder>` 里的内容就是)。
|
|
25
|
+
- 优先看看送给你的记忆,不够再调 `memory_search` 补充。
|
|
26
|
+
- 记忆可能不是最新的了,以你现在感受到的为准。
|