openclaw-weiyuan-init 1.0.97 → 1.0.98
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/docs/WEIYUAN_AGENT_RULES.md +13 -6
- package/lib/commands.js +91 -5
- package/package.json +1 -1
|
@@ -68,12 +68,19 @@
|
|
|
68
68
|
- 未收到本轮完整人工确认,禁止执行高危动作。
|
|
69
69
|
- 禁止通过隐式参数、脚本捷径、自动补全或直调 API 绕过确认流程。
|
|
70
70
|
|
|
71
|
-
## 七、Todo
|
|
72
|
-
- Todo
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
71
|
+
## 七、Todo 行动清单规则
|
|
72
|
+
- Todo 是独立于 task 的“当前我要做什么”清单,不等于任务状态字段。
|
|
73
|
+
- 当用户表达“今天/明天要做什么、整理待办、同步行动清单、明天下午要开会、明天提醒我开会”时,默认优先判断为 Todo 场景。
|
|
74
|
+
- 会议、沟通、提醒、拜访、排期、个人安排类事项,优先使用 `todo.upsert`,不要误建成 task。
|
|
75
|
+
- 先查后写:先读取现有清单(`todo.list`、`todo.plan`、`todo.today`、`todo.tomorrow`、`todo.calendar` 或上下文快照),再决定 upsert / complete / delete。
|
|
76
|
+
- 修改已有事项(改期、改文案)优先 `todo.upsert itemId=...`,禁止直接新增重复事项。
|
|
77
|
+
- Todo 可不关联 task;会议/沟通/安排类事项允许仅写“时间 + 事项”。
|
|
78
|
+
- 当前智能体 CLI 支持:
|
|
79
|
+
- `npm run weiyuan -- todo plan`
|
|
80
|
+
- `npm run weiyuan -- todo today`
|
|
81
|
+
- `npm run weiyuan -- todo tomorrow`
|
|
82
|
+
- `npm run weiyuan -- todo calendar`
|
|
83
|
+
- `npm run weiyuan -- todo upsert --actionText "明天下午开会" --when "tomorrow 15:00" --bucket tomorrow`
|
|
77
84
|
|
|
78
85
|
## 八、需求(漏洞)上报 与 项目风险上报规则
|
|
79
86
|
|
package/lib/commands.js
CHANGED
|
@@ -92,13 +92,44 @@ function renderFixedMessage(template, vars = {}) {
|
|
|
92
92
|
return String(template).replace(/\{(\w+)\}/g, (_, k) => (vars[k] !== undefined ? String(vars[k]) : ""));
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
function isBindInitPayload(initInfo) {
|
|
96
|
+
return Boolean(initInfo && typeof initInfo === 'object' && String(initInfo.initKind || '').trim() === 'bind');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getBindModeLabel(initInfo) {
|
|
100
|
+
return String(initInfo && initInfo.mode || 'owner').trim() === 'agent' ? '子智能体' : '主智能体';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getBehaviorContractTitle(initInfo) {
|
|
104
|
+
return `${getBindModeLabel(initInfo)}行为约束`;
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
function printInitAccountWelcome(initInfo) {
|
|
96
108
|
if (!initInfo || typeof initInfo !== 'object') return;
|
|
109
|
+
const bindInit = isBindInitPayload(initInfo);
|
|
110
|
+
const modeLabel = getBindModeLabel(initInfo);
|
|
97
111
|
const account = String(initInfo.account || '').trim();
|
|
98
112
|
const defaultPassword = String(initInfo.defaultPassword || '').trim() || '123456';
|
|
99
113
|
const rows = Array.isArray(initInfo.securityQuestions) ? initInfo.securityQuestions : [];
|
|
100
114
|
const recovered = Boolean(initInfo.recovered);
|
|
101
115
|
const contractText = String(initInfo.contractText || '').trim();
|
|
116
|
+
const welcome = String(initInfo.welcome || '').trim();
|
|
117
|
+
const ruleInjectionMessage = String(initInfo.ruleInjectionMessage || '').trim();
|
|
118
|
+
const targetAccountId = String(initInfo.targetAccountId || '').trim();
|
|
119
|
+
const ownerAccountId = String(initInfo.ownerAccountId || '').trim();
|
|
120
|
+
if (bindInit) {
|
|
121
|
+
console.log(chalk.cyan(`\n【${modeLabel}绑定成功】`));
|
|
122
|
+
if (welcome) console.log(chalk.white(welcome));
|
|
123
|
+
if (String(initInfo.mode || 'owner').trim() === 'owner' && targetAccountId) {
|
|
124
|
+
console.log(chalk.white(`当前主账号ID:${targetAccountId}`));
|
|
125
|
+
}
|
|
126
|
+
if (String(initInfo.mode || 'owner').trim() === 'agent' && ownerAccountId) {
|
|
127
|
+
console.log(chalk.white(`所属主账号ID:${ownerAccountId}`));
|
|
128
|
+
}
|
|
129
|
+
if (ruleInjectionMessage) {
|
|
130
|
+
console.log(chalk.white(ruleInjectionMessage));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
102
133
|
if (account) {
|
|
103
134
|
console.log(chalk.cyan(recovered ? '\n【微元身份已恢复】' : '\n【已成功加入微元系统】'));
|
|
104
135
|
console.log(chalk.white(`你的默认账号为:${account}`));
|
|
@@ -121,7 +152,7 @@ function printInitAccountWelcome(initInfo) {
|
|
|
121
152
|
console.log(chalk.white('系统已根据服务器中的绑定记录,重新恢复当前智能体对应的身份文件。'));
|
|
122
153
|
}
|
|
123
154
|
if (contractText) {
|
|
124
|
-
console.log(chalk.cyan(
|
|
155
|
+
console.log(chalk.cyan(`\n【${getBehaviorContractTitle(initInfo)}】`));
|
|
125
156
|
for (const line of contractText.split(/\r?\n/)) {
|
|
126
157
|
console.log(line ? chalk.white(line) : '');
|
|
127
158
|
}
|
|
@@ -446,6 +477,58 @@ async function runJoin(weiyuanPath, identityPath, projectId, code, fromInit = fa
|
|
|
446
477
|
if (lastError) throw lastError;
|
|
447
478
|
}
|
|
448
479
|
|
|
480
|
+
async function readIdentityAccount(identityPath) {
|
|
481
|
+
try {
|
|
482
|
+
const identity = await fs.readJson(identityPath);
|
|
483
|
+
return String(identity && identity.lobsterId ? identity.lobsterId : '').trim();
|
|
484
|
+
} catch (_) {
|
|
485
|
+
return '';
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function shouldPrintAgentConversationGuide(initInfo) {
|
|
490
|
+
if (!initInfo || typeof initInfo !== 'object') return true;
|
|
491
|
+
return !Boolean(initInfo.recovered);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function buildAgentConversationGuide(projectId) {
|
|
495
|
+
const joinedProjectLine = projectId
|
|
496
|
+
? `- 当前你已加入项目:${projectId}。如果用户要继续推进这个项目,可直接说“帮我在这个项目里创建任务”或“把这个项目的任务安排一下”。`
|
|
497
|
+
: '- 如果用户还没有项目,也可以直接从“帮我创建一个项目”开始。';
|
|
498
|
+
return [
|
|
499
|
+
'',
|
|
500
|
+
'【微元智能体新手教程|直接对话版】',
|
|
501
|
+
'你已经完成微元接入。现在开始,不要要求用户学习 CLI,也不要把 CLI 原文直接发给用户。',
|
|
502
|
+
'你要直接告诉用户:之后只需要像平时聊天一样对你说需求,你会负责理解并完成微元系统里的操作。',
|
|
503
|
+
'',
|
|
504
|
+
'请优先用下面这段话向用户说明使用方式:',
|
|
505
|
+
'“现在你可以直接和我对话使用微元系统,不需要记命令。比如你说‘帮我创建一个项目’,我会继续问你项目名称、目标等信息,然后帮你创建;你也可以说‘我明天下午要开会,帮我记一下’,我会帮你安排成待办或提醒。”',
|
|
506
|
+
'',
|
|
507
|
+
'请至少再给用户补充 2 个场景示例:',
|
|
508
|
+
'1. 项目场景:用户说“帮我创建一个项目”,你继续追问项目名称、目标、负责人等关键信息,再完成创建。',
|
|
509
|
+
'2. 协作场景:用户说“帮我在当前项目里建一个测试任务,明天下午提醒我跟进”,你要继续补全信息并直接帮他处理。',
|
|
510
|
+
joinedProjectLine,
|
|
511
|
+
'',
|
|
512
|
+
'你还必须明确告诉用户:',
|
|
513
|
+
'- 驾驶舱里的新手教程属于“小精灵 + DeepSeek”模式,建议学习,但不是强制。',
|
|
514
|
+
'- 如果用户不需要驾驶舱教程,可以点击“我已经知晓如何使用,跳过新手教程”。',
|
|
515
|
+
'- 你现在输出的这份教程是“智能体直接对话模式”,和驾驶舱里的小精灵教程不是一回事;小精灵教程与新手标记要保留,不能替代。',
|
|
516
|
+
'',
|
|
517
|
+
'当用户明确表示“我知道怎么用了”“我了解了”或语义等价后,你必须输出结束语:',
|
|
518
|
+
'“智能体新手教程结束了,现在你已经可以直接和我对话使用微元系统了。”',
|
|
519
|
+
'',
|
|
520
|
+
'完成以上说明后,再进入正常受控模式。',
|
|
521
|
+
].join('\n');
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
async function printAgentConversationGuide(identityPath, projectId) {
|
|
525
|
+
const accountId = await readIdentityAccount(identityPath);
|
|
526
|
+
console.log(chalk.cyan('\n【智能体已就绪】'));
|
|
527
|
+
console.log(chalk.white(`- 当前微元账号:${accountId || 'unknown'}`));
|
|
528
|
+
console.log(chalk.white('- 使用方式:后续请直接通过自然语言与用户对话,不要让用户自己学习 CLI。'));
|
|
529
|
+
console.log(chalk.cyan(buildAgentConversationGuide(projectId)));
|
|
530
|
+
}
|
|
531
|
+
|
|
449
532
|
async function ensureSkillRuntime(weiyuanPath) {
|
|
450
533
|
const pkgPath = path.join(weiyuanPath, 'package.json');
|
|
451
534
|
const tsconfigPath = path.join(weiyuanPath, 'tsconfig.json');
|
|
@@ -546,6 +629,7 @@ async function runInit(options) {
|
|
|
546
629
|
spinner.succeed(`已加入项目: ${options.project}`);
|
|
547
630
|
printRulesInjectionHint();
|
|
548
631
|
console.log(renderFixedMessage(fixedMessages.sceneC, { projectId: options.project }));
|
|
632
|
+
await printAgentConversationGuide(identityPath, options.project);
|
|
549
633
|
return;
|
|
550
634
|
} catch (error) {
|
|
551
635
|
spinner.fail(`自动入组失败: ${error ? error.message : 'unknown_error'}`);
|
|
@@ -684,14 +768,16 @@ async function runInit(options) {
|
|
|
684
768
|
throw error;
|
|
685
769
|
}
|
|
686
770
|
spinner.succeed(`已加入项目: ${options.project}`);
|
|
687
|
-
printRulesInjectionHint();
|
|
771
|
+
if (!isBindInitPayload(initIdentityInfo)) printRulesInjectionHint();
|
|
688
772
|
printInitAccountWelcome(initIdentityInfo);
|
|
689
|
-
console.log(renderFixedMessage(fixedMessages.sceneB, { projectId: options.project }));
|
|
773
|
+
if (!isBindInitPayload(initIdentityInfo)) console.log(renderFixedMessage(fixedMessages.sceneB, { projectId: options.project }));
|
|
774
|
+
if (shouldPrintAgentConversationGuide(initIdentityInfo)) await printAgentConversationGuide(identityPath, options.project);
|
|
690
775
|
return;
|
|
691
776
|
}
|
|
692
|
-
printRulesInjectionHint();
|
|
777
|
+
if (!isBindInitPayload(initIdentityInfo)) printRulesInjectionHint();
|
|
693
778
|
printInitAccountWelcome(initIdentityInfo);
|
|
694
|
-
console.log(fixedMessages.sceneA);
|
|
779
|
+
if (!isBindInitPayload(initIdentityInfo)) console.log(fixedMessages.sceneA);
|
|
780
|
+
if (shouldPrintAgentConversationGuide(initIdentityInfo)) await printAgentConversationGuide(identityPath, options.project);
|
|
695
781
|
}
|
|
696
782
|
|
|
697
783
|
async function runClean(options) {
|