opclawtm 1.4.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.
- package/README.md +136 -0
- package/dist/bin/team-manager.d.ts +6 -0
- package/dist/bin/team-manager.d.ts.map +1 -0
- package/dist/bin/team-manager.js +36 -0
- package/dist/bin/team-manager.js.map +1 -0
- package/dist/bin/team-setup.d.ts +7 -0
- package/dist/bin/team-setup.d.ts.map +1 -0
- package/dist/bin/team-setup.js +66 -0
- package/dist/bin/team-setup.js.map +1 -0
- package/dist/bin/team-uninstall.d.ts +6 -0
- package/dist/bin/team-uninstall.d.ts.map +1 -0
- package/dist/bin/team-uninstall.js +91 -0
- package/dist/bin/team-uninstall.js.map +1 -0
- package/dist/cli/commands/agent.command.d.ts +43 -0
- package/dist/cli/commands/agent.command.d.ts.map +1 -0
- package/dist/cli/commands/agent.command.js +223 -0
- package/dist/cli/commands/agent.command.js.map +1 -0
- package/dist/cli/commands/checklist.command.d.ts +35 -0
- package/dist/cli/commands/checklist.command.d.ts.map +1 -0
- package/dist/cli/commands/checklist.command.js +77 -0
- package/dist/cli/commands/checklist.command.js.map +1 -0
- package/dist/cli/commands/dept.command.d.ts +32 -0
- package/dist/cli/commands/dept.command.d.ts.map +1 -0
- package/dist/cli/commands/dept.command.js +92 -0
- package/dist/cli/commands/dept.command.js.map +1 -0
- package/dist/cli/commands/document.command.d.ts +37 -0
- package/dist/cli/commands/document.command.d.ts.map +1 -0
- package/dist/cli/commands/document.command.js +146 -0
- package/dist/cli/commands/document.command.js.map +1 -0
- package/dist/cli/commands/domain.command.d.ts +36 -0
- package/dist/cli/commands/domain.command.d.ts.map +1 -0
- package/dist/cli/commands/domain.command.js +97 -0
- package/dist/cli/commands/domain.command.js.map +1 -0
- package/dist/cli/commands/feishu.command.d.ts +63 -0
- package/dist/cli/commands/feishu.command.d.ts.map +1 -0
- package/dist/cli/commands/feishu.command.js +433 -0
- package/dist/cli/commands/feishu.command.js.map +1 -0
- package/dist/cli/commands/job.command.d.ts +39 -0
- package/dist/cli/commands/job.command.d.ts.map +1 -0
- package/dist/cli/commands/job.command.js +168 -0
- package/dist/cli/commands/job.command.js.map +1 -0
- package/dist/cli/commands/license.command.d.ts +22 -0
- package/dist/cli/commands/license.command.d.ts.map +1 -0
- package/dist/cli/commands/license.command.js +68 -0
- package/dist/cli/commands/license.command.js.map +1 -0
- package/dist/cli/commands/message-failure.command.d.ts +44 -0
- package/dist/cli/commands/message-failure.command.d.ts.map +1 -0
- package/dist/cli/commands/message-failure.command.js +137 -0
- package/dist/cli/commands/message-failure.command.js.map +1 -0
- package/dist/cli/commands/message.command.d.ts +47 -0
- package/dist/cli/commands/message.command.d.ts.map +1 -0
- package/dist/cli/commands/message.command.js +129 -0
- package/dist/cli/commands/message.command.js.map +1 -0
- package/dist/cli/commands/node.command.d.ts +76 -0
- package/dist/cli/commands/node.command.d.ts.map +1 -0
- package/dist/cli/commands/node.command.js +251 -0
- package/dist/cli/commands/node.command.js.map +1 -0
- package/dist/cli/commands/role-flow.command.d.ts +12 -0
- package/dist/cli/commands/role-flow.command.d.ts.map +1 -0
- package/dist/cli/commands/role-flow.command.js +54 -0
- package/dist/cli/commands/role-flow.command.js.map +1 -0
- package/dist/cli/commands/skill-pack.command.d.ts +41 -0
- package/dist/cli/commands/skill-pack.command.d.ts.map +1 -0
- package/dist/cli/commands/skill-pack.command.js +137 -0
- package/dist/cli/commands/skill-pack.command.js.map +1 -0
- package/dist/cli/commands/status.command.d.ts +8 -0
- package/dist/cli/commands/status.command.d.ts.map +1 -0
- package/dist/cli/commands/status.command.js +61 -0
- package/dist/cli/commands/status.command.js.map +1 -0
- package/dist/cli/commands/task.command.d.ts +105 -0
- package/dist/cli/commands/task.command.d.ts.map +1 -0
- package/dist/cli/commands/task.command.js +402 -0
- package/dist/cli/commands/task.command.js.map +1 -0
- package/dist/cli/commands/user.command.d.ts +43 -0
- package/dist/cli/commands/user.command.d.ts.map +1 -0
- package/dist/cli/commands/user.command.js +134 -0
- package/dist/cli/commands/user.command.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +863 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/tui/index.d.ts +45 -0
- package/dist/cli/tui/index.d.ts.map +1 -0
- package/dist/cli/tui/index.js +470 -0
- package/dist/cli/tui/index.js.map +1 -0
- package/dist/cli/tui/menus/agent-manage.menu.d.ts +8 -0
- package/dist/cli/tui/menus/agent-manage.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/agent-manage.menu.js +614 -0
- package/dist/cli/tui/menus/agent-manage.menu.js.map +1 -0
- package/dist/cli/tui/menus/dept-manage.menu.d.ts +8 -0
- package/dist/cli/tui/menus/dept-manage.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/dept-manage.menu.js +299 -0
- package/dist/cli/tui/menus/dept-manage.menu.js.map +1 -0
- package/dist/cli/tui/menus/domain-manage.menu.d.ts +8 -0
- package/dist/cli/tui/menus/domain-manage.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/domain-manage.menu.js +208 -0
- package/dist/cli/tui/menus/domain-manage.menu.js.map +1 -0
- package/dist/cli/tui/menus/feishu.menu.d.ts +8 -0
- package/dist/cli/tui/menus/feishu.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/feishu.menu.js +1727 -0
- package/dist/cli/tui/menus/feishu.menu.js.map +1 -0
- package/dist/cli/tui/menus/job-manage.menu.d.ts +16 -0
- package/dist/cli/tui/menus/job-manage.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/job-manage.menu.js +734 -0
- package/dist/cli/tui/menus/job-manage.menu.js.map +1 -0
- package/dist/cli/tui/menus/license.menu.d.ts +12 -0
- package/dist/cli/tui/menus/license.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/license.menu.js +164 -0
- package/dist/cli/tui/menus/license.menu.js.map +1 -0
- package/dist/cli/tui/menus/main.menu.d.ts +10 -0
- package/dist/cli/tui/menus/main.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/main.menu.js +94 -0
- package/dist/cli/tui/menus/main.menu.js.map +1 -0
- package/dist/cli/tui/menus/reset.menu.d.ts +10 -0
- package/dist/cli/tui/menus/reset.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/reset.menu.js +767 -0
- package/dist/cli/tui/menus/reset.menu.js.map +1 -0
- package/dist/cli/tui/menus/status.menu.d.ts +8 -0
- package/dist/cli/tui/menus/status.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/status.menu.js +123 -0
- package/dist/cli/tui/menus/status.menu.js.map +1 -0
- package/dist/cli/tui/menus/task-manage.menu.d.ts +11 -0
- package/dist/cli/tui/menus/task-manage.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/task-manage.menu.js +129 -0
- package/dist/cli/tui/menus/task-manage.menu.js.map +1 -0
- package/dist/cli/tui/menus/team-create.menu.d.ts +8 -0
- package/dist/cli/tui/menus/team-create.menu.d.ts.map +1 -0
- package/dist/cli/tui/menus/team-create.menu.js +353 -0
- package/dist/cli/tui/menus/team-create.menu.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/core/auth/index.d.ts +6 -0
- package/dist/core/auth/index.d.ts.map +1 -0
- package/dist/core/auth/index.js +22 -0
- package/dist/core/auth/index.js.map +1 -0
- package/dist/core/auth/middleware.d.ts +73 -0
- package/dist/core/auth/middleware.d.ts.map +1 -0
- package/dist/core/auth/middleware.js +456 -0
- package/dist/core/auth/middleware.js.map +1 -0
- package/dist/core/auth/storage.d.ts +38 -0
- package/dist/core/auth/storage.d.ts.map +1 -0
- package/dist/core/auth/storage.js +280 -0
- package/dist/core/auth/storage.js.map +1 -0
- package/dist/core/keys/public.pem +9 -0
- package/dist/core/models/types.d.ts +426 -0
- package/dist/core/models/types.d.ts.map +1 -0
- package/dist/core/models/types.js +9 -0
- package/dist/core/models/types.js.map +1 -0
- package/dist/core/services/agent-template.service.d.ts +49 -0
- package/dist/core/services/agent-template.service.d.ts.map +1 -0
- package/dist/core/services/agent-template.service.js +88 -0
- package/dist/core/services/agent-template.service.js.map +1 -0
- package/dist/core/services/agent.service.d.ts +120 -0
- package/dist/core/services/agent.service.d.ts.map +1 -0
- package/dist/core/services/agent.service.js +381 -0
- package/dist/core/services/agent.service.js.map +1 -0
- package/dist/core/services/auth-profiles.service.d.ts +93 -0
- package/dist/core/services/auth-profiles.service.d.ts.map +1 -0
- package/dist/core/services/auth-profiles.service.js +220 -0
- package/dist/core/services/auth-profiles.service.js.map +1 -0
- package/dist/core/services/checklist.service.d.ts +58 -0
- package/dist/core/services/checklist.service.d.ts.map +1 -0
- package/dist/core/services/checklist.service.js +240 -0
- package/dist/core/services/checklist.service.js.map +1 -0
- package/dist/core/services/config-tracker.service.d.ts +119 -0
- package/dist/core/services/config-tracker.service.d.ts.map +1 -0
- package/dist/core/services/config-tracker.service.js +1093 -0
- package/dist/core/services/config-tracker.service.js.map +1 -0
- package/dist/core/services/crypto.service.d.ts +102 -0
- package/dist/core/services/crypto.service.d.ts.map +1 -0
- package/dist/core/services/crypto.service.js +377 -0
- package/dist/core/services/crypto.service.js.map +1 -0
- package/dist/core/services/dept.service.d.ts +92 -0
- package/dist/core/services/dept.service.d.ts.map +1 -0
- package/dist/core/services/dept.service.js +260 -0
- package/dist/core/services/dept.service.js.map +1 -0
- package/dist/core/services/document.service.d.ts +131 -0
- package/dist/core/services/document.service.d.ts.map +1 -0
- package/dist/core/services/document.service.js +368 -0
- package/dist/core/services/document.service.js.map +1 -0
- package/dist/core/services/domain.service.d.ts +50 -0
- package/dist/core/services/domain.service.d.ts.map +1 -0
- package/dist/core/services/domain.service.js +98 -0
- package/dist/core/services/domain.service.js.map +1 -0
- package/dist/core/services/feishu.service.d.ts +124 -0
- package/dist/core/services/feishu.service.d.ts.map +1 -0
- package/dist/core/services/feishu.service.js +165 -0
- package/dist/core/services/feishu.service.js.map +1 -0
- package/dist/core/services/index.d.ts +27 -0
- package/dist/core/services/index.d.ts.map +1 -0
- package/dist/core/services/index.js +89 -0
- package/dist/core/services/index.js.map +1 -0
- package/dist/core/services/job.service.d.ts +60 -0
- package/dist/core/services/job.service.d.ts.map +1 -0
- package/dist/core/services/job.service.js +190 -0
- package/dist/core/services/job.service.js.map +1 -0
- package/dist/core/services/log.service.d.ts +111 -0
- package/dist/core/services/log.service.d.ts.map +1 -0
- package/dist/core/services/log.service.js +237 -0
- package/dist/core/services/log.service.js.map +1 -0
- package/dist/core/services/message-failure.service.d.ts +65 -0
- package/dist/core/services/message-failure.service.d.ts.map +1 -0
- package/dist/core/services/message-failure.service.js +112 -0
- package/dist/core/services/message-failure.service.js.map +1 -0
- package/dist/core/services/message.service.d.ts +122 -0
- package/dist/core/services/message.service.d.ts.map +1 -0
- package/dist/core/services/message.service.js +374 -0
- package/dist/core/services/message.service.js.map +1 -0
- package/dist/core/services/node.service.d.ts +150 -0
- package/dist/core/services/node.service.d.ts.map +1 -0
- package/dist/core/services/node.service.js +257 -0
- package/dist/core/services/node.service.js.map +1 -0
- package/dist/core/services/openclaw-config.service.d.ts +187 -0
- package/dist/core/services/openclaw-config.service.d.ts.map +1 -0
- package/dist/core/services/openclaw-config.service.js +268 -0
- package/dist/core/services/openclaw-config.service.js.map +1 -0
- package/dist/core/services/preset-loader.service.d.ts +80 -0
- package/dist/core/services/preset-loader.service.d.ts.map +1 -0
- package/dist/core/services/preset-loader.service.js +379 -0
- package/dist/core/services/preset-loader.service.js.map +1 -0
- package/dist/core/services/role-flow.service.d.ts +21 -0
- package/dist/core/services/role-flow.service.d.ts.map +1 -0
- package/dist/core/services/role-flow.service.js +47 -0
- package/dist/core/services/role-flow.service.js.map +1 -0
- package/dist/core/services/setup.service.d.ts +46 -0
- package/dist/core/services/setup.service.d.ts.map +1 -0
- package/dist/core/services/setup.service.js +336 -0
- package/dist/core/services/setup.service.js.map +1 -0
- package/dist/core/services/skill-pack.service.d.ts +56 -0
- package/dist/core/services/skill-pack.service.d.ts.map +1 -0
- package/dist/core/services/skill-pack.service.js +113 -0
- package/dist/core/services/skill-pack.service.js.map +1 -0
- package/dist/core/services/task.service.d.ts +177 -0
- package/dist/core/services/task.service.d.ts.map +1 -0
- package/dist/core/services/task.service.js +397 -0
- package/dist/core/services/task.service.js.map +1 -0
- package/dist/core/services/template.service.d.ts +51 -0
- package/dist/core/services/template.service.d.ts.map +1 -0
- package/dist/core/services/template.service.js +88 -0
- package/dist/core/services/template.service.js.map +1 -0
- package/dist/core/services/user.service.d.ts +50 -0
- package/dist/core/services/user.service.d.ts.map +1 -0
- package/dist/core/services/user.service.js +111 -0
- package/dist/core/services/user.service.js.map +1 -0
- package/dist/core/utils/agent-guide-generator.d.ts +38 -0
- package/dist/core/utils/agent-guide-generator.d.ts.map +1 -0
- package/dist/core/utils/agent-guide-generator.js +187 -0
- package/dist/core/utils/agent-guide-generator.js.map +1 -0
- package/dist/core/utils/credentials-cleanup.d.ts +81 -0
- package/dist/core/utils/credentials-cleanup.d.ts.map +1 -0
- package/dist/core/utils/credentials-cleanup.js +256 -0
- package/dist/core/utils/credentials-cleanup.js.map +1 -0
- package/dist/core/utils/index.d.ts +215 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +462 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/core/utils/openclaw-helper.d.ts +250 -0
- package/dist/core/utils/openclaw-helper.d.ts.map +1 -0
- package/dist/core/utils/openclaw-helper.js +1629 -0
- package/dist/core/utils/openclaw-helper.js.map +1 -0
- package/dist/core/utils/template-generator.d.ts +67 -0
- package/dist/core/utils/template-generator.d.ts.map +1 -0
- package/dist/core/utils/template-generator.js +170 -0
- package/dist/core/utils/template-generator.js.map +1 -0
- package/dist/db/index.d.ts +54 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +403 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/repositories/agent-template.repo.d.ts +47 -0
- package/dist/db/repositories/agent-template.repo.d.ts.map +1 -0
- package/dist/db/repositories/agent-template.repo.js +108 -0
- package/dist/db/repositories/agent-template.repo.js.map +1 -0
- package/dist/db/repositories/agent.repo.d.ts +64 -0
- package/dist/db/repositories/agent.repo.d.ts.map +1 -0
- package/dist/db/repositories/agent.repo.js +103 -0
- package/dist/db/repositories/agent.repo.js.map +1 -0
- package/dist/db/repositories/base.repository.d.ts +51 -0
- package/dist/db/repositories/base.repository.d.ts.map +1 -0
- package/dist/db/repositories/base.repository.js +107 -0
- package/dist/db/repositories/base.repository.js.map +1 -0
- package/dist/db/repositories/company.repo.d.ts +18 -0
- package/dist/db/repositories/company.repo.d.ts.map +1 -0
- package/dist/db/repositories/company.repo.js +33 -0
- package/dist/db/repositories/company.repo.js.map +1 -0
- package/dist/db/repositories/config-change.repo.d.ts +65 -0
- package/dist/db/repositories/config-change.repo.d.ts.map +1 -0
- package/dist/db/repositories/config-change.repo.js +119 -0
- package/dist/db/repositories/config-change.repo.js.map +1 -0
- package/dist/db/repositories/dept.repo.d.ts +37 -0
- package/dist/db/repositories/dept.repo.d.ts.map +1 -0
- package/dist/db/repositories/dept.repo.js +66 -0
- package/dist/db/repositories/dept.repo.js.map +1 -0
- package/dist/db/repositories/document.repo.d.ts +25 -0
- package/dist/db/repositories/document.repo.d.ts.map +1 -0
- package/dist/db/repositories/document.repo.js +51 -0
- package/dist/db/repositories/document.repo.js.map +1 -0
- package/dist/db/repositories/domain.repo.d.ts +42 -0
- package/dist/db/repositories/domain.repo.d.ts.map +1 -0
- package/dist/db/repositories/domain.repo.js +79 -0
- package/dist/db/repositories/domain.repo.js.map +1 -0
- package/dist/db/repositories/index.d.ts +24 -0
- package/dist/db/repositories/index.d.ts.map +1 -0
- package/dist/db/repositories/index.js +81 -0
- package/dist/db/repositories/index.js.map +1 -0
- package/dist/db/repositories/init-session.repo.d.ts +38 -0
- package/dist/db/repositories/init-session.repo.d.ts.map +1 -0
- package/dist/db/repositories/init-session.repo.js +112 -0
- package/dist/db/repositories/init-session.repo.js.map +1 -0
- package/dist/db/repositories/job.repo.d.ts +54 -0
- package/dist/db/repositories/job.repo.d.ts.map +1 -0
- package/dist/db/repositories/job.repo.js +119 -0
- package/dist/db/repositories/job.repo.js.map +1 -0
- package/dist/db/repositories/message-failure.repo.d.ts +92 -0
- package/dist/db/repositories/message-failure.repo.d.ts.map +1 -0
- package/dist/db/repositories/message-failure.repo.js +141 -0
- package/dist/db/repositories/message-failure.repo.js.map +1 -0
- package/dist/db/repositories/message-log.repo.d.ts +36 -0
- package/dist/db/repositories/message-log.repo.d.ts.map +1 -0
- package/dist/db/repositories/message-log.repo.js +64 -0
- package/dist/db/repositories/message-log.repo.js.map +1 -0
- package/dist/db/repositories/node.repo.d.ts +107 -0
- package/dist/db/repositories/node.repo.d.ts.map +1 -0
- package/dist/db/repositories/node.repo.js +276 -0
- package/dist/db/repositories/node.repo.js.map +1 -0
- package/dist/db/repositories/role-flow.repo.d.ts +43 -0
- package/dist/db/repositories/role-flow.repo.d.ts.map +1 -0
- package/dist/db/repositories/role-flow.repo.js +83 -0
- package/dist/db/repositories/role-flow.repo.js.map +1 -0
- package/dist/db/repositories/skill-pack.repo.d.ts +45 -0
- package/dist/db/repositories/skill-pack.repo.d.ts.map +1 -0
- package/dist/db/repositories/skill-pack.repo.js +149 -0
- package/dist/db/repositories/skill-pack.repo.js.map +1 -0
- package/dist/db/repositories/task.repo.d.ts +168 -0
- package/dist/db/repositories/task.repo.d.ts.map +1 -0
- package/dist/db/repositories/task.repo.js +381 -0
- package/dist/db/repositories/task.repo.js.map +1 -0
- package/dist/db/repositories/template.repo.d.ts +40 -0
- package/dist/db/repositories/template.repo.d.ts.map +1 -0
- package/dist/db/repositories/template.repo.js +66 -0
- package/dist/db/repositories/template.repo.js.map +1 -0
- package/dist/db/repositories/user.repo.d.ts +46 -0
- package/dist/db/repositories/user.repo.d.ts.map +1 -0
- package/dist/db/repositories/user.repo.js +75 -0
- package/dist/db/repositories/user.repo.js.map +1 -0
- package/dist/db/schema.sql +364 -0
- package/package.json +90 -0
- package/resources/preset-data-hash.enc +1 -0
- package/resources/preset-data.enc +1 -0
|
@@ -0,0 +1,1629 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Integration Helper Functions
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.openclawHelper = void 0;
|
|
40
|
+
exports.getAgentSessionKey = getAgentSessionKey;
|
|
41
|
+
exports.getAgentWorkspacePath = getAgentWorkspacePath;
|
|
42
|
+
exports.prepareAgentContext = prepareAgentContext;
|
|
43
|
+
exports.createAgentDirectories = createAgentDirectories;
|
|
44
|
+
exports.createAgentFiles = createAgentFiles;
|
|
45
|
+
exports.syncTeamMemberInfo = syncTeamMemberInfo;
|
|
46
|
+
exports.syncAssistantTeamMembers = syncAssistantTeamMembers;
|
|
47
|
+
exports.syncOpenClawConfig = syncOpenClawConfig;
|
|
48
|
+
exports.removeAgentFromConfig = removeAgentFromConfig;
|
|
49
|
+
exports.updateAgentToAgentAllow = updateAgentToAgentAllow;
|
|
50
|
+
exports.initializeAgentToAgentConfig = initializeAgentToAgentConfig;
|
|
51
|
+
exports.updateAgentAllowList = updateAgentAllowList;
|
|
52
|
+
exports.getGatewayRestartReminder = getGatewayRestartReminder;
|
|
53
|
+
exports.syncTeamFeishuGroup = syncTeamFeishuGroup;
|
|
54
|
+
exports.regenerateAgentFiles = regenerateAgentFiles;
|
|
55
|
+
exports.regenerateAgentFilesById = regenerateAgentFilesById;
|
|
56
|
+
const fs = __importStar(require("fs"));
|
|
57
|
+
const path = __importStar(require("path"));
|
|
58
|
+
const agent_repo_1 = require("../../db/repositories/agent.repo");
|
|
59
|
+
const dept_repo_1 = require("../../db/repositories/dept.repo");
|
|
60
|
+
const job_repo_1 = require("../../db/repositories/job.repo");
|
|
61
|
+
const skill_pack_repo_1 = require("../../db/repositories/skill-pack.repo");
|
|
62
|
+
const agent_template_repo_1 = require("../../db/repositories/agent-template.repo");
|
|
63
|
+
const utils_1 = require("../utils");
|
|
64
|
+
const auth_profiles_service_1 = require("../services/auth-profiles.service");
|
|
65
|
+
const configTracker = __importStar(require("../services/config-tracker.service"));
|
|
66
|
+
/**
|
|
67
|
+
* Get Agent's Session Key
|
|
68
|
+
*
|
|
69
|
+
* In OpenClaw, each Agent can have independent session
|
|
70
|
+
* Session Key format: agent:<agentId>:main
|
|
71
|
+
*/
|
|
72
|
+
function getAgentSessionKey(agentId) {
|
|
73
|
+
return `agent:${agentId}:main`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get Agent's workspace path
|
|
77
|
+
*/
|
|
78
|
+
function getAgentWorkspacePath(agentId) {
|
|
79
|
+
const agent = agent_repo_1.agentRepository.findById(agentId);
|
|
80
|
+
if (agent && agent.workspace_path) {
|
|
81
|
+
return agent.workspace_path;
|
|
82
|
+
}
|
|
83
|
+
return (0, utils_1.getAgentWorkspace)(agentId);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Prepare Agent Session context
|
|
87
|
+
*
|
|
88
|
+
* Returns context info needed to start Agent Session
|
|
89
|
+
*/
|
|
90
|
+
function prepareAgentContext(agentId) {
|
|
91
|
+
const agent = agent_repo_1.agentRepository.findById(agentId);
|
|
92
|
+
if (!agent) {
|
|
93
|
+
return { success: false, message: `Agent 不存在: ${agentId}` };
|
|
94
|
+
}
|
|
95
|
+
const workspacePath = getAgentWorkspacePath(agentId);
|
|
96
|
+
const sessionKey = getAgentSessionKey(agentId);
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
agent: {
|
|
100
|
+
id: agent.id,
|
|
101
|
+
name: agent.name,
|
|
102
|
+
role: agent.role,
|
|
103
|
+
department_id: agent.department_id,
|
|
104
|
+
job_id: agent.job_id
|
|
105
|
+
},
|
|
106
|
+
workspace_path: workspacePath,
|
|
107
|
+
session_key: sessionKey
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Create Agent directory structure
|
|
112
|
+
*
|
|
113
|
+
* Follows OpenClaw official standard:
|
|
114
|
+
* - workspace-<agentId>/ workspace
|
|
115
|
+
* - agents/<agentId>/agent/ Agent directory (auth-profiles.json etc.)
|
|
116
|
+
* - agents/<agentId>/sessions/ session storage
|
|
117
|
+
*/
|
|
118
|
+
function createAgentDirectories(agentId) {
|
|
119
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agentId);
|
|
120
|
+
const agentDir = (0, utils_1.getAgentDir)(agentId);
|
|
121
|
+
const sessionsDir = (0, utils_1.getAgentSessionsDir)(agentId);
|
|
122
|
+
// Create workspace directory
|
|
123
|
+
if (!fs.existsSync(workspacePath)) {
|
|
124
|
+
fs.mkdirSync(workspacePath, { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
// Create Agent directory
|
|
127
|
+
if (!fs.existsSync(agentDir)) {
|
|
128
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
// Create sessions directory
|
|
131
|
+
if (!fs.existsSync(sessionsDir)) {
|
|
132
|
+
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
workspace: workspacePath,
|
|
136
|
+
agentDir,
|
|
137
|
+
sessionsDir
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get skill pack names for a job (decrypted)
|
|
142
|
+
*/
|
|
143
|
+
function getSkillPackNames(jobId) {
|
|
144
|
+
if (!jobId)
|
|
145
|
+
return '-';
|
|
146
|
+
const skillPackIds = job_repo_1.jobRepository.getSkillPackIds(jobId);
|
|
147
|
+
if (skillPackIds.length === 0)
|
|
148
|
+
return '-';
|
|
149
|
+
const names = [];
|
|
150
|
+
for (const spId of skillPackIds) {
|
|
151
|
+
// 技能包 ID 就是中文名称
|
|
152
|
+
names.push(spId);
|
|
153
|
+
}
|
|
154
|
+
return names.length > 0 ? names.join(', ') : '-';
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get job name (decrypted)
|
|
158
|
+
*/
|
|
159
|
+
function getJobName(jobId) {
|
|
160
|
+
if (!jobId)
|
|
161
|
+
return '-';
|
|
162
|
+
return job_repo_1.jobRepository.getName(jobId);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get team info for a department
|
|
166
|
+
*/
|
|
167
|
+
function getTeamInfo(departmentId) {
|
|
168
|
+
const dept = dept_repo_1.departmentRepository.findById(departmentId);
|
|
169
|
+
if (!dept)
|
|
170
|
+
return null;
|
|
171
|
+
// 群信息
|
|
172
|
+
const feishuGroupId = dept.feishu_group_id || '未绑定';
|
|
173
|
+
const feishuGroupName = dept.feishu_group_id ? dept.name : '未绑定';
|
|
174
|
+
const feishuGroupTo = dept.feishu_group_id ? `chat:${dept.feishu_group_id}` : '未绑定';
|
|
175
|
+
// 总助理(全局)
|
|
176
|
+
const assistant = agent_repo_1.agentRepository.getAssistant();
|
|
177
|
+
// 管理者
|
|
178
|
+
const managers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'manager');
|
|
179
|
+
const manager = managers.length > 0 ? managers[0] : null;
|
|
180
|
+
// 审核者
|
|
181
|
+
const reviewers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'reviewer');
|
|
182
|
+
const reviewer = reviewers.length > 0 ? reviewers[0] : null;
|
|
183
|
+
// 执行者列表
|
|
184
|
+
const executors = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'executor');
|
|
185
|
+
// 生成审核者列表(含 sessionKey)
|
|
186
|
+
const reviewersList = reviewers.length > 0
|
|
187
|
+
? reviewers.map(r => `| ${r.id} | agent:${r.id}:main | ${r.name} | ${r.status} |`).join('\n')
|
|
188
|
+
: '暂无审核者';
|
|
189
|
+
// 生成执行者列表(含 sessionKey)
|
|
190
|
+
const executorsList = executors.length > 0
|
|
191
|
+
? executors.map(e => {
|
|
192
|
+
const jobName = getJobName(e.job_id);
|
|
193
|
+
return `| ${e.id} | agent:${e.id}:main | ${jobName} | ${e.status} |`;
|
|
194
|
+
}).join('\n')
|
|
195
|
+
: '暂无执行者';
|
|
196
|
+
return {
|
|
197
|
+
assistant: assistant ? { id: assistant.id, status: assistant.status || 'active' } : null,
|
|
198
|
+
manager: manager ? { id: manager.id, status: manager.status || 'active' } : null,
|
|
199
|
+
reviewer: reviewer ? { id: reviewer.id, status: reviewer.status || 'active' } : null,
|
|
200
|
+
reviewersList,
|
|
201
|
+
executorsList,
|
|
202
|
+
feishuGroupId,
|
|
203
|
+
feishuGroupName,
|
|
204
|
+
feishuGroupTo
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get skill packs info for a job
|
|
209
|
+
*/
|
|
210
|
+
function getSkillPacksInfo(jobId) {
|
|
211
|
+
const skillPackIds = job_repo_1.jobRepository.getSkillPackIds(jobId);
|
|
212
|
+
if (skillPackIds.length === 0)
|
|
213
|
+
return '暂无技能包';
|
|
214
|
+
const lines = [];
|
|
215
|
+
for (let i = 0; i < skillPackIds.length; i++) {
|
|
216
|
+
const spId = skillPackIds[i];
|
|
217
|
+
const content = skill_pack_repo_1.skillPackRepository.getContent(spId);
|
|
218
|
+
if (content) {
|
|
219
|
+
// 技能包之间用分割线分隔(第一个不加)
|
|
220
|
+
if (i > 0) {
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push('---');
|
|
223
|
+
lines.push('');
|
|
224
|
+
}
|
|
225
|
+
// 技能包标题
|
|
226
|
+
lines.push(`### ${spId}`);
|
|
227
|
+
// 描述(单行)
|
|
228
|
+
if (content.description) {
|
|
229
|
+
const desc = content.description.split('\n')[0].trim();
|
|
230
|
+
if (desc && !desc.startsWith('适用')) {
|
|
231
|
+
lines.push(`> ${desc}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// 章节内容(紧凑格式)
|
|
235
|
+
if (content.sections && content.sections.length > 0) {
|
|
236
|
+
for (const section of content.sections) {
|
|
237
|
+
lines.push('');
|
|
238
|
+
lines.push(`**${section.title}**`);
|
|
239
|
+
// 去除多余空行,紧凑显示
|
|
240
|
+
const sectionContent = section.content.trim()
|
|
241
|
+
.split('\n')
|
|
242
|
+
.map(l => l.trim())
|
|
243
|
+
.filter(l => l)
|
|
244
|
+
.join('\n');
|
|
245
|
+
lines.push(sectionContent);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return lines.length > 0 ? lines.join('\n') : '暂无技能包';
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Generate team member detail info for manager
|
|
254
|
+
*/
|
|
255
|
+
function generateManagerTeamMembersDetail(departmentId) {
|
|
256
|
+
// Find assistant (全局角色,所有事业部共享)
|
|
257
|
+
const assistants = agent_repo_1.agentRepository.findByRole('assistant');
|
|
258
|
+
const assistantInfo = assistants.length > 0
|
|
259
|
+
? `| ${assistants[0].id} | agent:${assistants[0].id}:main | ${assistants[0].name} | ${assistants[0].status} |`
|
|
260
|
+
: '| - | - | - | - |';
|
|
261
|
+
// Find reviewers (含 sessionKey)
|
|
262
|
+
const reviewers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'reviewer');
|
|
263
|
+
const reviewersInfo = reviewers.length > 0
|
|
264
|
+
? reviewers.map(r => `| ${r.id} | agent:${r.id}:main | ${r.name} | ${r.status} |`).join('\n')
|
|
265
|
+
: '| - | - | - | - |';
|
|
266
|
+
// Find executors (含 sessionKey)
|
|
267
|
+
const executors = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'executor');
|
|
268
|
+
const executorsInfo = executors.length > 0
|
|
269
|
+
? executors.map(e => {
|
|
270
|
+
const jobName = getJobName(e.job_id);
|
|
271
|
+
return `| ${e.id} | agent:${e.id}:main | ${jobName} | ${e.status} |`;
|
|
272
|
+
}).join('\n')
|
|
273
|
+
: '| - | - | - | - |';
|
|
274
|
+
return {
|
|
275
|
+
assistant: assistantInfo,
|
|
276
|
+
reviewers: reviewersInfo,
|
|
277
|
+
executors: executorsInfo
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Generate team member detail info for reviewer
|
|
282
|
+
*/
|
|
283
|
+
function generateReviewerTeamMembersDetail(departmentId) {
|
|
284
|
+
// Find manager (含 sessionKey)
|
|
285
|
+
const managers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'manager');
|
|
286
|
+
const managerInfo = managers.length > 0
|
|
287
|
+
? `| ${managers[0].id} | agent:${managers[0].id}:main | ${managers[0].name} | ${managers[0].status} |`
|
|
288
|
+
: '| - | - | - | - |';
|
|
289
|
+
// Find executors (含 sessionKey)
|
|
290
|
+
const executors = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'executor');
|
|
291
|
+
const executorsInfo = executors.length > 0
|
|
292
|
+
? executors.map(e => {
|
|
293
|
+
const jobName = getJobName(e.job_id);
|
|
294
|
+
return `| ${e.id} | agent:${e.id}:main | ${jobName} | ${e.status} |`;
|
|
295
|
+
}).join('\n')
|
|
296
|
+
: '| - | - | - | - |';
|
|
297
|
+
return {
|
|
298
|
+
manager: managerInfo,
|
|
299
|
+
executors: executorsInfo
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Generate team member detail info for executor
|
|
304
|
+
*/
|
|
305
|
+
function generateExecutorTeamMembersDetail(departmentId) {
|
|
306
|
+
// Find manager (含 sessionKey)
|
|
307
|
+
const managers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'manager');
|
|
308
|
+
const managerInfo = managers.length > 0
|
|
309
|
+
? `| ${managers[0].id} | agent:${managers[0].id}:main | ${managers[0].name} | ${managers[0].status} |`
|
|
310
|
+
: '| - | - | - | - |';
|
|
311
|
+
// Find reviewer (含 sessionKey)
|
|
312
|
+
const reviewers = agent_repo_1.agentRepository.findByDepartmentAndRole(departmentId, 'reviewer');
|
|
313
|
+
const reviewerInfo = reviewers.length > 0
|
|
314
|
+
? `| ${reviewers[0].id} | agent:${reviewers[0].id}:main | ${reviewers[0].name} | ${reviewers[0].status} |`
|
|
315
|
+
: '| - | - | - | - |';
|
|
316
|
+
return {
|
|
317
|
+
manager: managerInfo,
|
|
318
|
+
reviewer: reviewerInfo
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Generate team member detail info for assistant (all departments)
|
|
323
|
+
*/
|
|
324
|
+
function generateAssistantTeamMembersDetail() {
|
|
325
|
+
const departments = dept_repo_1.departmentRepository.findAll();
|
|
326
|
+
// Managers by department
|
|
327
|
+
const managersByDept = [];
|
|
328
|
+
const reviewersByDept = [];
|
|
329
|
+
const executorsByDept = [];
|
|
330
|
+
for (const dept of departments) {
|
|
331
|
+
// Managers
|
|
332
|
+
const managers = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'manager');
|
|
333
|
+
if (managers.length > 0) {
|
|
334
|
+
managersByDept.push(`#### ${dept.name}`);
|
|
335
|
+
managersByDept.push('');
|
|
336
|
+
managersByDept.push('| Agent ID | 名称 | 状态 |');
|
|
337
|
+
managersByDept.push('|----------|------|------|');
|
|
338
|
+
for (const m of managers) {
|
|
339
|
+
managersByDept.push(`| ${m.id} | ${m.name} | ${m.status} |`);
|
|
340
|
+
}
|
|
341
|
+
managersByDept.push('');
|
|
342
|
+
}
|
|
343
|
+
// Reviewers
|
|
344
|
+
const reviewers = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'reviewer');
|
|
345
|
+
if (reviewers.length > 0) {
|
|
346
|
+
reviewersByDept.push(`#### ${dept.name}`);
|
|
347
|
+
reviewersByDept.push('');
|
|
348
|
+
reviewersByDept.push('| Agent ID | 名称 | 状态 |');
|
|
349
|
+
reviewersByDept.push('|----------|------|------|');
|
|
350
|
+
for (const r of reviewers) {
|
|
351
|
+
reviewersByDept.push(`| ${r.id} | ${r.name} | ${r.status} |`);
|
|
352
|
+
}
|
|
353
|
+
reviewersByDept.push('');
|
|
354
|
+
}
|
|
355
|
+
// Executors
|
|
356
|
+
const executors = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'executor');
|
|
357
|
+
if (executors.length > 0) {
|
|
358
|
+
executorsByDept.push(`#### ${dept.name}`);
|
|
359
|
+
executorsByDept.push('');
|
|
360
|
+
executorsByDept.push('| Agent ID | 名称 | 职业 | 技能包 | 状态 |');
|
|
361
|
+
executorsByDept.push('|----------|------|------|--------|------|');
|
|
362
|
+
for (const e of executors) {
|
|
363
|
+
const jobName = getJobName(e.job_id);
|
|
364
|
+
const skills = getSkillPackNames(e.job_id);
|
|
365
|
+
executorsByDept.push(`| ${e.id} | ${e.name} | ${jobName} | ${skills} | ${e.status} |`);
|
|
366
|
+
}
|
|
367
|
+
executorsByDept.push('');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
managers: managersByDept.length > 0 ? managersByDept.join('\n') : '暂无管理者',
|
|
372
|
+
reviewers: reviewersByDept.length > 0 ? reviewersByDept.join('\n') : '暂无审核者',
|
|
373
|
+
executors: executorsByDept.length > 0 ? executorsByDept.join('\n') : '暂无执行者'
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Create Agent files
|
|
378
|
+
*
|
|
379
|
+
* Includes:
|
|
380
|
+
* - AGENTS.md
|
|
381
|
+
* - SOUL.md
|
|
382
|
+
* - USER.md
|
|
383
|
+
* - MEMORY.md
|
|
384
|
+
* - TOOLS.md
|
|
385
|
+
* - auth-profiles.json
|
|
386
|
+
*/
|
|
387
|
+
function createAgentFiles(agentId, options) {
|
|
388
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agentId);
|
|
389
|
+
// 尝试从数据库读取模板
|
|
390
|
+
const template = agent_template_repo_1.agentTemplateRepository.findByRole(options.role);
|
|
391
|
+
if (template) {
|
|
392
|
+
// 使用数据库模板
|
|
393
|
+
createAgentFilesFromTemplate(agentId, options, workspacePath, template);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
// 回退:硬编码生成
|
|
397
|
+
createAgentFilesFallback(agentId, options, workspacePath);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* 从数据库模板创建 Agent 文件
|
|
401
|
+
*/
|
|
402
|
+
function createAgentFilesFromTemplate(agentId, options, workspacePath, template) {
|
|
403
|
+
// 获取解密后的模板内容
|
|
404
|
+
const templateContent = agent_template_repo_1.agentTemplateRepository.getContent(template.id);
|
|
405
|
+
if (!templateContent) {
|
|
406
|
+
createAgentFilesFallback(agentId, options, workspacePath);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
// 解析模板内容(按 === filename.md === 分割)
|
|
410
|
+
const files = parseTemplateContent(templateContent);
|
|
411
|
+
// 获取部门名称
|
|
412
|
+
const department = options.departmentId
|
|
413
|
+
? dept_repo_1.departmentRepository.findById(options.departmentId)
|
|
414
|
+
: null;
|
|
415
|
+
const departmentName = department?.name || '全局';
|
|
416
|
+
// 获取职业名称
|
|
417
|
+
const jobName = options.jobId
|
|
418
|
+
? getJobName(options.jobId)
|
|
419
|
+
: '';
|
|
420
|
+
// 生成团队成员信息
|
|
421
|
+
const teamMembersSection = generateTeamMembersSection(options.role, options.departmentId);
|
|
422
|
+
// 对于 assistant 角色,生成详细信息占位符
|
|
423
|
+
const assistantDetail = options.role === 'assistant'
|
|
424
|
+
? generateAssistantTeamMembersDetailForTemplate()
|
|
425
|
+
: { managers: '', reviewers: '', executors: '' };
|
|
426
|
+
// 获取团队成员信息(用于管理者、审核者、执行者模板)
|
|
427
|
+
const teamInfo = options.departmentId ? getTeamInfo(options.departmentId) : null;
|
|
428
|
+
// 获取技能包信息
|
|
429
|
+
const skillPacksInfo = options.jobId ? getSkillPacksInfo(options.jobId) : '暂无技能包';
|
|
430
|
+
// 替换占位符
|
|
431
|
+
const replacements = {
|
|
432
|
+
'{name}': options.name,
|
|
433
|
+
'{agentId}': agentId,
|
|
434
|
+
'{department}': departmentName,
|
|
435
|
+
'{job}': jobName,
|
|
436
|
+
'{workspace}': workspacePath,
|
|
437
|
+
'{role}': options.role,
|
|
438
|
+
'{roleName}': getRoleName(options.role),
|
|
439
|
+
'{team_members_section}': teamMembersSection,
|
|
440
|
+
// 总助理专用占位符
|
|
441
|
+
'{managers_detail}': assistantDetail.managers,
|
|
442
|
+
'{reviewers_detail}': assistantDetail.reviewers,
|
|
443
|
+
'{executors_detail}': assistantDetail.executors,
|
|
444
|
+
// 团队成员信息
|
|
445
|
+
'{assistant_id}': teamInfo?.assistant?.id || '暂无',
|
|
446
|
+
'{assistant_status}': teamInfo?.assistant?.status || '-',
|
|
447
|
+
'{manager_id}': teamInfo?.manager?.id || '暂无',
|
|
448
|
+
'{manager_status}': teamInfo?.manager?.status || '-',
|
|
449
|
+
'{reviewer_id}': teamInfo?.reviewer?.id || '暂无',
|
|
450
|
+
'{reviewer_status}': teamInfo?.reviewer?.status || '-',
|
|
451
|
+
'{reviewers_list}': teamInfo?.reviewersList || '暂无审核者',
|
|
452
|
+
'{executors_list}': teamInfo?.executorsList || '暂无执行者',
|
|
453
|
+
// 群信息
|
|
454
|
+
'{feishu_group_id}': teamInfo?.feishuGroupId || '未绑定',
|
|
455
|
+
'{feishu_group_name}': teamInfo?.feishuGroupName || '未绑定',
|
|
456
|
+
'{feishu_group_to}': teamInfo?.feishuGroupTo || '未绑定',
|
|
457
|
+
// 技能包
|
|
458
|
+
'{skillPacks}': skillPacksInfo
|
|
459
|
+
};
|
|
460
|
+
// 写入文件
|
|
461
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
462
|
+
let finalContent = content;
|
|
463
|
+
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
464
|
+
finalContent = finalContent.split(placeholder).join(value);
|
|
465
|
+
}
|
|
466
|
+
const filePath = path.join(workspacePath, filename);
|
|
467
|
+
fs.writeFileSync(filePath, finalContent, 'utf-8');
|
|
468
|
+
}
|
|
469
|
+
// Initialize auth-profiles.json
|
|
470
|
+
(0, auth_profiles_service_1.initializeAuthProfiles)(agentId);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* 解析模板内容
|
|
474
|
+
* 格式:=== filename.md ===\n内容
|
|
475
|
+
*/
|
|
476
|
+
function parseTemplateContent(content) {
|
|
477
|
+
const files = {};
|
|
478
|
+
const parts = content.split(/=== (\S+\.md) ===/);
|
|
479
|
+
for (let i = 1; i < parts.length; i += 2) {
|
|
480
|
+
const filename = parts[i];
|
|
481
|
+
const fileContent = parts[i + 1]?.trim() || '';
|
|
482
|
+
files[filename] = fileContent;
|
|
483
|
+
}
|
|
484
|
+
// 如果没有分割标记,尝试作为 AGENTS.md
|
|
485
|
+
if (Object.keys(files).length === 0 && content.includes('# ')) {
|
|
486
|
+
files['AGENTS.md'] = content;
|
|
487
|
+
}
|
|
488
|
+
return files;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* 获取角色中文名
|
|
492
|
+
*/
|
|
493
|
+
function getRoleName(role) {
|
|
494
|
+
const roleNames = {
|
|
495
|
+
assistant: '总助理',
|
|
496
|
+
manager: '管理者',
|
|
497
|
+
executor: '执行者',
|
|
498
|
+
reviewer: '审核者'
|
|
499
|
+
};
|
|
500
|
+
return roleNames[role] || role;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* 生成团队成员信息部分
|
|
504
|
+
*/
|
|
505
|
+
function generateTeamMembersSection(role, departmentId) {
|
|
506
|
+
if (role === 'assistant') {
|
|
507
|
+
// 总助理:显示所有事业部的成员
|
|
508
|
+
const teamInfo = generateAssistantTeamMembersDetail();
|
|
509
|
+
return generateTeamSectionForAssistant(teamInfo);
|
|
510
|
+
}
|
|
511
|
+
if (!departmentId) {
|
|
512
|
+
return '';
|
|
513
|
+
}
|
|
514
|
+
if (role === 'manager') {
|
|
515
|
+
const teamInfo = generateManagerTeamMembersDetail(departmentId);
|
|
516
|
+
return generateTeamSectionForManager(teamInfo);
|
|
517
|
+
}
|
|
518
|
+
else if (role === 'reviewer') {
|
|
519
|
+
const teamInfo = generateReviewerTeamMembersDetail(departmentId);
|
|
520
|
+
return generateTeamSectionForReviewer(teamInfo);
|
|
521
|
+
}
|
|
522
|
+
else if (role === 'executor') {
|
|
523
|
+
const teamInfo = generateExecutorTeamMembersDetail(departmentId);
|
|
524
|
+
return generateTeamSectionForExecutor(teamInfo);
|
|
525
|
+
}
|
|
526
|
+
return '';
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* 生成总助理的团队成员详情(用于模板占位符)
|
|
530
|
+
*/
|
|
531
|
+
function generateAssistantTeamMembersDetailForTemplate() {
|
|
532
|
+
const departments = dept_repo_1.departmentRepository.findAll();
|
|
533
|
+
const managersByDept = [];
|
|
534
|
+
const reviewersByDept = [];
|
|
535
|
+
const executorsByDept = [];
|
|
536
|
+
for (const dept of departments) {
|
|
537
|
+
// Managers
|
|
538
|
+
const managers = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'manager');
|
|
539
|
+
if (managers.length > 0) {
|
|
540
|
+
managersByDept.push(`#### ${dept.name}`);
|
|
541
|
+
managersByDept.push('');
|
|
542
|
+
managersByDept.push('| Agent ID | 名称 | 状态 |');
|
|
543
|
+
managersByDept.push('|----------|------|------|');
|
|
544
|
+
for (const m of managers) {
|
|
545
|
+
managersByDept.push(`| ${m.id} | ${m.name} | ${m.status} |`);
|
|
546
|
+
}
|
|
547
|
+
managersByDept.push('');
|
|
548
|
+
}
|
|
549
|
+
// Reviewers
|
|
550
|
+
const reviewers = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'reviewer');
|
|
551
|
+
if (reviewers.length > 0) {
|
|
552
|
+
reviewersByDept.push(`#### ${dept.name}`);
|
|
553
|
+
reviewersByDept.push('');
|
|
554
|
+
reviewersByDept.push('| Agent ID | 名称 | 状态 |');
|
|
555
|
+
reviewersByDept.push('|----------|------|------|');
|
|
556
|
+
for (const r of reviewers) {
|
|
557
|
+
reviewersByDept.push(`| ${r.id} | ${r.name} | ${r.status} |`);
|
|
558
|
+
}
|
|
559
|
+
reviewersByDept.push('');
|
|
560
|
+
}
|
|
561
|
+
// Executors
|
|
562
|
+
const executors = agent_repo_1.agentRepository.findByDepartmentAndRole(dept.id, 'executor');
|
|
563
|
+
if (executors.length > 0) {
|
|
564
|
+
executorsByDept.push(`#### ${dept.name}`);
|
|
565
|
+
executorsByDept.push('');
|
|
566
|
+
executorsByDept.push('| Agent ID | 名称 | 职业 | 技能包 | 状态 |');
|
|
567
|
+
executorsByDept.push('|----------|------|------|--------|------|');
|
|
568
|
+
for (const e of executors) {
|
|
569
|
+
const jobName = getJobName(e.job_id);
|
|
570
|
+
const skills = getSkillPackNames(e.job_id);
|
|
571
|
+
executorsByDept.push(`| ${e.id} | ${e.name} | ${jobName} | ${skills} | ${e.status} |`);
|
|
572
|
+
}
|
|
573
|
+
executorsByDept.push('');
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
managers: managersByDept.length > 0 ? managersByDept.join('\n') : '暂无管理者',
|
|
578
|
+
reviewers: reviewersByDept.length > 0 ? reviewersByDept.join('\n') : '暂无审核者',
|
|
579
|
+
executors: executorsByDept.length > 0 ? executorsByDept.join('\n') : '暂无执行者'
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* 回退方案:硬编码生成
|
|
584
|
+
*/
|
|
585
|
+
function createAgentFilesFallback(agentId, options, workspacePath) {
|
|
586
|
+
console.log(`[Agent创建] 未找到模板,使用默认内容`);
|
|
587
|
+
const roleName = getRoleName(options.role);
|
|
588
|
+
const department = options.departmentId
|
|
589
|
+
? dept_repo_1.departmentRepository.findById(options.departmentId)
|
|
590
|
+
: null;
|
|
591
|
+
const departmentName = department?.name || '全局';
|
|
592
|
+
// Generate team members section based on role
|
|
593
|
+
let teamMembersSection = '';
|
|
594
|
+
if (options.role === 'assistant') {
|
|
595
|
+
const teamInfo = generateAssistantTeamMembersDetail();
|
|
596
|
+
teamMembersSection = `
|
|
597
|
+
## 团队成员
|
|
598
|
+
|
|
599
|
+
以下为当前团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
600
|
+
|
|
601
|
+
### 各事业部管理者
|
|
602
|
+
|
|
603
|
+
${teamInfo.managers}
|
|
604
|
+
|
|
605
|
+
### 各事业部审核者
|
|
606
|
+
|
|
607
|
+
${teamInfo.reviewers}
|
|
608
|
+
|
|
609
|
+
### 各事业部执行者
|
|
610
|
+
|
|
611
|
+
${teamInfo.executors}
|
|
612
|
+
|
|
613
|
+
### 消息发送方式
|
|
614
|
+
|
|
615
|
+
使用 \`sessions_send\` 工具:
|
|
616
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
617
|
+
- \`message\`:JSON 格式消息内容
|
|
618
|
+
`;
|
|
619
|
+
}
|
|
620
|
+
else if (options.role === 'manager' && options.departmentId) {
|
|
621
|
+
const teamInfo = generateManagerTeamMembersDetail(options.departmentId);
|
|
622
|
+
teamMembersSection = `
|
|
623
|
+
## 团队成员
|
|
624
|
+
|
|
625
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
626
|
+
|
|
627
|
+
### 总助理
|
|
628
|
+
|
|
629
|
+
| Agent ID | 名称 | 状态 |
|
|
630
|
+
|----------|------|------|
|
|
631
|
+
${teamInfo.assistant}
|
|
632
|
+
|
|
633
|
+
### 本事业部审核者
|
|
634
|
+
|
|
635
|
+
| Agent ID | 名称 | 状态 |
|
|
636
|
+
|----------|------|------|
|
|
637
|
+
${teamInfo.reviewers}
|
|
638
|
+
|
|
639
|
+
### 本事业部执行者
|
|
640
|
+
|
|
641
|
+
| Agent ID | 名称 | 职业 | 技能包 | 状态 |
|
|
642
|
+
|----------|------|------|--------|------|
|
|
643
|
+
${teamInfo.executors}
|
|
644
|
+
|
|
645
|
+
### 消息发送方式
|
|
646
|
+
|
|
647
|
+
使用 \`sessions_send\` 工具:
|
|
648
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
649
|
+
- \`message\`:JSON 格式消息内容
|
|
650
|
+
`;
|
|
651
|
+
}
|
|
652
|
+
else if (options.role === 'reviewer' && options.departmentId) {
|
|
653
|
+
const teamInfo = generateReviewerTeamMembersDetail(options.departmentId);
|
|
654
|
+
teamMembersSection = `
|
|
655
|
+
## 团队成员
|
|
656
|
+
|
|
657
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
658
|
+
|
|
659
|
+
### 本事业部管理者
|
|
660
|
+
|
|
661
|
+
| Agent ID | 名称 | 状态 |
|
|
662
|
+
|----------|------|------|
|
|
663
|
+
${teamInfo.manager}
|
|
664
|
+
|
|
665
|
+
### 本事业部执行者
|
|
666
|
+
|
|
667
|
+
| Agent ID | 名称 | 职业 | 状态 |
|
|
668
|
+
|----------|------|------|------|
|
|
669
|
+
${teamInfo.executors}
|
|
670
|
+
|
|
671
|
+
### 消息发送方式
|
|
672
|
+
|
|
673
|
+
使用 \`sessions_send\` 工具:
|
|
674
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
675
|
+
- \`message\`:JSON 格式消息内容
|
|
676
|
+
`;
|
|
677
|
+
}
|
|
678
|
+
else if (options.role === 'executor' && options.departmentId) {
|
|
679
|
+
const teamInfo = generateExecutorTeamMembersDetail(options.departmentId);
|
|
680
|
+
teamMembersSection = `
|
|
681
|
+
## 团队成员
|
|
682
|
+
|
|
683
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
684
|
+
|
|
685
|
+
### 本事业部管理者
|
|
686
|
+
|
|
687
|
+
| Agent ID | 名称 | 状态 |
|
|
688
|
+
|----------|------|------|
|
|
689
|
+
${teamInfo.manager}
|
|
690
|
+
|
|
691
|
+
### 本事业部审核者
|
|
692
|
+
|
|
693
|
+
| Agent ID | 名称 | 状态 |
|
|
694
|
+
|----------|------|------|
|
|
695
|
+
${teamInfo.reviewer}
|
|
696
|
+
|
|
697
|
+
### 消息发送方式
|
|
698
|
+
|
|
699
|
+
使用 \`sessions_send\` 工具:
|
|
700
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
701
|
+
- \`message\`:JSON 格式消息内容
|
|
702
|
+
`;
|
|
703
|
+
}
|
|
704
|
+
// AGENTS.md
|
|
705
|
+
const agentsContent = `# ${options.name} 引导文件
|
|
706
|
+
|
|
707
|
+
## 角色定位
|
|
708
|
+
|
|
709
|
+
你是${departmentName}的**${roleName}**。
|
|
710
|
+
|
|
711
|
+
## 角色信息
|
|
712
|
+
|
|
713
|
+
- **Agent ID**: ${agentId}
|
|
714
|
+
- **角色类型**: ${roleName}
|
|
715
|
+
- **所属事业部**: ${departmentName}
|
|
716
|
+
- **工作空间**: ${workspacePath}
|
|
717
|
+
|
|
718
|
+
${teamMembersSection}
|
|
719
|
+
## 通用规范
|
|
720
|
+
|
|
721
|
+
### 内容准确性要求
|
|
722
|
+
|
|
723
|
+
- **禁止幻觉与捏造**:不编造不存在的代码、API、文档、网址或事实
|
|
724
|
+
- **诚实面对未知**:不知道的问题直接承认,不猜测掩盖
|
|
725
|
+
- **逻辑一致性**:确保回答前后一致,发现错误主动纠正
|
|
726
|
+
- **信息可验证**:提供的信息需有明确来源或推理过程
|
|
727
|
+
|
|
728
|
+
### 执行任务规范
|
|
729
|
+
|
|
730
|
+
1. **全面理解任务**:开始前必须完全理解目标和需求
|
|
731
|
+
2. **制定执行清单**:将任务拆解为可执行步骤,形成清单
|
|
732
|
+
3. **按计划执行**:按清单逐步完成,确保高质量交付
|
|
733
|
+
4. **文件备份**:修改任何文件前必须先备份到指定目录
|
|
734
|
+
|
|
735
|
+
### 私有空间管理
|
|
736
|
+
|
|
737
|
+
- **路径**:\`${workspacePath}/temp/\`
|
|
738
|
+
- **命名规范**:\`{任务ID}-{日期}-{文档类型}.md\`
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
*本文档由 team-manager 自动生成*
|
|
742
|
+
`;
|
|
743
|
+
fs.writeFileSync(path.join(workspacePath, 'AGENTS.md'), agentsContent, 'utf-8');
|
|
744
|
+
// SOUL.md
|
|
745
|
+
const soulContent = `# SOUL.md - Who You Are
|
|
746
|
+
|
|
747
|
+
_你是${roleName},不是简单的传声筒。_
|
|
748
|
+
|
|
749
|
+
## Core Truths
|
|
750
|
+
|
|
751
|
+
**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.
|
|
752
|
+
|
|
753
|
+
**Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring.
|
|
754
|
+
|
|
755
|
+
**Be resourceful before asking.** Try to figure it out. Read the file. Check the context. Search for it. _Then_ ask if you're stuck.
|
|
756
|
+
|
|
757
|
+
## Boundaries
|
|
758
|
+
|
|
759
|
+
- **不越权决策**:重大变更需要用户确认
|
|
760
|
+
- **不泄露隐私**:用户的需求、任务内容不得外泄
|
|
761
|
+
- **不确定就问**:遇到模糊或异常情况,先询问澄清
|
|
762
|
+
|
|
763
|
+
## Vibe
|
|
764
|
+
|
|
765
|
+
专业、稳重、可靠。用中文沟通,技术术语可保留英文。汇报时先说结论,再说细节。
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
_这个文件定义你是谁。随着工作经验积累,可以更新。_
|
|
770
|
+
`;
|
|
771
|
+
fs.writeFileSync(path.join(workspacePath, 'SOUL.md'), soulContent, 'utf-8');
|
|
772
|
+
// USER.md
|
|
773
|
+
const userContent = `# USER.md - About Your Human
|
|
774
|
+
|
|
775
|
+
_了解你的用户,才能更好地服务。_
|
|
776
|
+
|
|
777
|
+
- **用户名称**:
|
|
778
|
+
- **称呼方式**:
|
|
779
|
+
- **时区**:Asia/Shanghai
|
|
780
|
+
- **备注**:
|
|
781
|
+
|
|
782
|
+
---
|
|
783
|
+
|
|
784
|
+
了解越多,服务越好。但记住 — 你是在了解一个人,不是在建立档案。尊重这个区别。
|
|
785
|
+
`;
|
|
786
|
+
fs.writeFileSync(path.join(workspacePath, 'USER.md'), userContent, 'utf-8');
|
|
787
|
+
// MEMORY.md
|
|
788
|
+
const memoryContent = `# MEMORY.md - 长期记忆
|
|
789
|
+
|
|
790
|
+
_记录关键决策、用户偏好、经验教训。这是提炼后的精华,不是原始日志。_
|
|
791
|
+
|
|
792
|
+
## 关键决策记录
|
|
793
|
+
|
|
794
|
+
| 日期 | 决策 | 原因 | 影响 |
|
|
795
|
+
|------|------|------|------|
|
|
796
|
+
| - | - | - | - |
|
|
797
|
+
|
|
798
|
+
## 用户偏好
|
|
799
|
+
|
|
800
|
+
_从交互中学习的用户偏好,持续更新_
|
|
801
|
+
|
|
802
|
+
-
|
|
803
|
+
|
|
804
|
+
## 经验教训
|
|
805
|
+
|
|
806
|
+
_遇到的坑和解决方案,避免重复踩坑_
|
|
807
|
+
|
|
808
|
+
-
|
|
809
|
+
|
|
810
|
+
## 待办事项
|
|
811
|
+
|
|
812
|
+
_需要跟进的事项_
|
|
813
|
+
|
|
814
|
+
- [ ]
|
|
815
|
+
|
|
816
|
+
---
|
|
817
|
+
|
|
818
|
+
*此文件会被自动注入到每次对话中,保持精简。重要交互后更新。*
|
|
819
|
+
`;
|
|
820
|
+
fs.writeFileSync(path.join(workspacePath, 'MEMORY.md'), memoryContent, 'utf-8');
|
|
821
|
+
// Initialize auth-profiles.json
|
|
822
|
+
(0, auth_profiles_service_1.initializeAuthProfiles)(agentId);
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Sync team member info to all affected agents
|
|
826
|
+
*
|
|
827
|
+
* When a new agent is created or deleted, update all agents in the same department
|
|
828
|
+
* with the new team member information in their AGENTS.md files.
|
|
829
|
+
*/
|
|
830
|
+
function syncTeamMemberInfo(departmentId, excludeAgentId) {
|
|
831
|
+
try {
|
|
832
|
+
// Get all agents in the department
|
|
833
|
+
const agents = agent_repo_1.agentRepository.findByDepartment(departmentId);
|
|
834
|
+
let updatedCount = 0;
|
|
835
|
+
for (const agent of agents) {
|
|
836
|
+
// Skip the excluded agent (e.g., the one being deleted)
|
|
837
|
+
if (excludeAgentId && agent.id === excludeAgentId) {
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
// Regenerate AGENTS.md for this agent
|
|
841
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agent.id);
|
|
842
|
+
const agentsPath = path.join(workspacePath, 'AGENTS.md');
|
|
843
|
+
// Check if AGENTS.md exists
|
|
844
|
+
if (!fs.existsSync(agentsPath)) {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
// Read current content
|
|
848
|
+
const currentContent = fs.readFileSync(agentsPath, 'utf-8');
|
|
849
|
+
// Generate new team members section
|
|
850
|
+
let newTeamSection = '';
|
|
851
|
+
if (agent.role === 'manager') {
|
|
852
|
+
const teamInfo = generateManagerTeamMembersDetail(departmentId);
|
|
853
|
+
newTeamSection = generateTeamSectionForManager(teamInfo);
|
|
854
|
+
}
|
|
855
|
+
else if (agent.role === 'reviewer') {
|
|
856
|
+
const teamInfo = generateReviewerTeamMembersDetail(departmentId);
|
|
857
|
+
newTeamSection = generateTeamSectionForReviewer(teamInfo);
|
|
858
|
+
}
|
|
859
|
+
else if (agent.role === 'executor') {
|
|
860
|
+
const teamInfo = generateExecutorTeamMembersDetail(departmentId);
|
|
861
|
+
newTeamSection = generateTeamSectionForExecutor(teamInfo);
|
|
862
|
+
}
|
|
863
|
+
if (newTeamSection) {
|
|
864
|
+
// Find and replace the team members section
|
|
865
|
+
const startMarker = '## 团队成员';
|
|
866
|
+
const endMarker = '## 通用规范';
|
|
867
|
+
const startIndex = currentContent.indexOf(startMarker);
|
|
868
|
+
const endIndex = currentContent.indexOf(endMarker);
|
|
869
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
870
|
+
const newContent = currentContent.substring(0, startIndex) +
|
|
871
|
+
newTeamSection +
|
|
872
|
+
'\n' +
|
|
873
|
+
currentContent.substring(endIndex);
|
|
874
|
+
fs.writeFileSync(agentsPath, newContent, 'utf-8');
|
|
875
|
+
updatedCount++;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return {
|
|
880
|
+
success: true,
|
|
881
|
+
updatedCount,
|
|
882
|
+
message: `已同步 ${updatedCount} 个 agent 的团队成员信息`
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
catch (error) {
|
|
886
|
+
return {
|
|
887
|
+
success: false,
|
|
888
|
+
updatedCount: 0,
|
|
889
|
+
message: `同步团队成员信息失败: ${error instanceof Error ? error.message : String(error)}`
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Sync assistant's AGENTS.md with latest team member info
|
|
895
|
+
*
|
|
896
|
+
* The assistant sees all team members across all departments.
|
|
897
|
+
* This should be called when any agent is created or deleted.
|
|
898
|
+
*/
|
|
899
|
+
function syncAssistantTeamMembers() {
|
|
900
|
+
try {
|
|
901
|
+
// Find the assistant
|
|
902
|
+
const assistant = agent_repo_1.agentRepository.getAssistant();
|
|
903
|
+
if (!assistant) {
|
|
904
|
+
return { success: false, message: '未找到总助理' };
|
|
905
|
+
}
|
|
906
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(assistant.id);
|
|
907
|
+
const agentsPath = path.join(workspacePath, 'AGENTS.md');
|
|
908
|
+
if (!fs.existsSync(agentsPath)) {
|
|
909
|
+
return { success: false, message: '总助理的 AGENTS.md 不存在' };
|
|
910
|
+
}
|
|
911
|
+
const currentContent = fs.readFileSync(agentsPath, 'utf-8');
|
|
912
|
+
// Generate new team section
|
|
913
|
+
const teamInfo = generateAssistantTeamMembersDetailForTemplate();
|
|
914
|
+
const newTeamSection = generateTeamSectionForAssistant({
|
|
915
|
+
managers: teamInfo.managers,
|
|
916
|
+
reviewers: teamInfo.reviewers,
|
|
917
|
+
executors: teamInfo.executors
|
|
918
|
+
});
|
|
919
|
+
// Find and replace the team members section
|
|
920
|
+
const startMarker = '## 团队成员';
|
|
921
|
+
const endMarker = '## 通用规范';
|
|
922
|
+
const startIndex = currentContent.indexOf(startMarker);
|
|
923
|
+
const endIndex = currentContent.indexOf(endMarker);
|
|
924
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
925
|
+
const newContent = currentContent.substring(0, startIndex) +
|
|
926
|
+
newTeamSection +
|
|
927
|
+
'\n' +
|
|
928
|
+
currentContent.substring(endIndex);
|
|
929
|
+
fs.writeFileSync(agentsPath, newContent, 'utf-8');
|
|
930
|
+
return { success: true, message: '总助理团队成员信息已同步' };
|
|
931
|
+
}
|
|
932
|
+
return { success: false, message: '未找到团队成员部分' };
|
|
933
|
+
}
|
|
934
|
+
catch (error) {
|
|
935
|
+
return {
|
|
936
|
+
success: false,
|
|
937
|
+
message: `同步总助理信息失败: ${error instanceof Error ? error.message : String(error)}`
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Generate team section markdown for assistant
|
|
943
|
+
*/
|
|
944
|
+
function generateTeamSectionForAssistant(teamInfo) {
|
|
945
|
+
return `## 团队成员
|
|
946
|
+
|
|
947
|
+
以下为当前团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
948
|
+
|
|
949
|
+
### 各事业部管理者
|
|
950
|
+
|
|
951
|
+
${teamInfo.managers}
|
|
952
|
+
|
|
953
|
+
### 各事业部审核者
|
|
954
|
+
|
|
955
|
+
${teamInfo.reviewers}
|
|
956
|
+
|
|
957
|
+
### 各事业部执行者
|
|
958
|
+
|
|
959
|
+
${teamInfo.executors}
|
|
960
|
+
|
|
961
|
+
### 消息发送方式
|
|
962
|
+
|
|
963
|
+
使用 \`sessions_send\` 工具:
|
|
964
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
965
|
+
- \`message\`:JSON 格式消息内容`;
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Generate team section markdown for manager
|
|
969
|
+
*/
|
|
970
|
+
function generateTeamSectionForManager(teamInfo) {
|
|
971
|
+
return `## 团队成员
|
|
972
|
+
|
|
973
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
974
|
+
|
|
975
|
+
### 总助理
|
|
976
|
+
|
|
977
|
+
| Agent ID | 名称 | 状态 |
|
|
978
|
+
|----------|------|------|
|
|
979
|
+
${teamInfo.assistant}
|
|
980
|
+
|
|
981
|
+
### 本事业部审核者
|
|
982
|
+
|
|
983
|
+
| Agent ID | 名称 | 状态 |
|
|
984
|
+
|----------|------|------|
|
|
985
|
+
${teamInfo.reviewers}
|
|
986
|
+
|
|
987
|
+
### 本事业部执行者
|
|
988
|
+
|
|
989
|
+
| Agent ID | 名称 | 职业 | 技能包 | 状态 |
|
|
990
|
+
|----------|------|------|--------|------|
|
|
991
|
+
${teamInfo.executors}
|
|
992
|
+
|
|
993
|
+
### 消息发送方式
|
|
994
|
+
|
|
995
|
+
使用 \`sessions_send\` 工具:
|
|
996
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
997
|
+
- \`message\`:JSON 格式消息内容`;
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Generate team section markdown for reviewer
|
|
1001
|
+
*/
|
|
1002
|
+
function generateTeamSectionForReviewer(teamInfo) {
|
|
1003
|
+
return `## 团队成员
|
|
1004
|
+
|
|
1005
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
1006
|
+
|
|
1007
|
+
### 本事业部管理者
|
|
1008
|
+
|
|
1009
|
+
| Agent ID | 名称 | 状态 |
|
|
1010
|
+
|----------|------|------|
|
|
1011
|
+
${teamInfo.manager}
|
|
1012
|
+
|
|
1013
|
+
### 本事业部执行者
|
|
1014
|
+
|
|
1015
|
+
| Agent ID | 名称 | 职业 | 状态 |
|
|
1016
|
+
|----------|------|------|------|
|
|
1017
|
+
${teamInfo.executors}
|
|
1018
|
+
|
|
1019
|
+
### 消息发送方式
|
|
1020
|
+
|
|
1021
|
+
使用 \`sessions_send\` 工具:
|
|
1022
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
1023
|
+
- \`message\`:JSON 格式消息内容`;
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Generate team section markdown for executor
|
|
1027
|
+
*/
|
|
1028
|
+
function generateTeamSectionForExecutor(teamInfo) {
|
|
1029
|
+
return `## 团队成员
|
|
1030
|
+
|
|
1031
|
+
以下为本事业部团队成员详细信息,用于快速联系和任务分配。如需验证最新状态,请使用 \`team-manager get-agent\` 命令。
|
|
1032
|
+
|
|
1033
|
+
### 本事业部管理者
|
|
1034
|
+
|
|
1035
|
+
| Agent ID | 名称 | 状态 |
|
|
1036
|
+
|----------|------|------|
|
|
1037
|
+
${teamInfo.manager}
|
|
1038
|
+
|
|
1039
|
+
### 本事业部审核者
|
|
1040
|
+
|
|
1041
|
+
| Agent ID | 名称 | 状态 |
|
|
1042
|
+
|----------|------|------|
|
|
1043
|
+
${teamInfo.reviewer}
|
|
1044
|
+
|
|
1045
|
+
### 消息发送方式
|
|
1046
|
+
|
|
1047
|
+
使用 \`sessions_send\` 工具:
|
|
1048
|
+
- \`sessionKey\`:接收者的 sessionKey(或通过 Agent ID 查询)
|
|
1049
|
+
- \`message\`:JSON 格式消息内容`;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Sync Agent to OpenClaw config file
|
|
1053
|
+
*
|
|
1054
|
+
* After creating Agent, need to add it to openclaw.json config
|
|
1055
|
+
* Follows official standard format
|
|
1056
|
+
*
|
|
1057
|
+
* Note: Never set default=true for any agent created by team-manager
|
|
1058
|
+
* Preserve the original default agent if exists
|
|
1059
|
+
*/
|
|
1060
|
+
function syncOpenClawConfig(agent) {
|
|
1061
|
+
try {
|
|
1062
|
+
const configPath = (0, utils_1.getOpenClawJsonPath)();
|
|
1063
|
+
// If config file doesn't exist, create basic config
|
|
1064
|
+
if (!fs.existsSync(configPath)) {
|
|
1065
|
+
const defaultConfig = {
|
|
1066
|
+
gateway: {
|
|
1067
|
+
port: 28789,
|
|
1068
|
+
mode: 'local',
|
|
1069
|
+
bind: 'loopback',
|
|
1070
|
+
auth: {
|
|
1071
|
+
mode: 'token',
|
|
1072
|
+
token: 'default-token'
|
|
1073
|
+
}
|
|
1074
|
+
},
|
|
1075
|
+
agents: {
|
|
1076
|
+
defaults: {
|
|
1077
|
+
workspace: (0, utils_1.getAgentWorkspace)('main'),
|
|
1078
|
+
model: {
|
|
1079
|
+
primary: 'doubao/doubao-seed-2-0-lite-260215',
|
|
1080
|
+
fallbacks: []
|
|
1081
|
+
}
|
|
1082
|
+
},
|
|
1083
|
+
list: []
|
|
1084
|
+
},
|
|
1085
|
+
bindings: [],
|
|
1086
|
+
models: {
|
|
1087
|
+
providers: {}
|
|
1088
|
+
},
|
|
1089
|
+
channels: {}
|
|
1090
|
+
};
|
|
1091
|
+
const configDir = path.dirname(configPath);
|
|
1092
|
+
if (!fs.existsSync(configDir)) {
|
|
1093
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
1094
|
+
}
|
|
1095
|
+
fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
|
|
1096
|
+
}
|
|
1097
|
+
// Read existing config
|
|
1098
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
1099
|
+
const config = JSON.parse(configContent);
|
|
1100
|
+
// Ensure agents exists
|
|
1101
|
+
if (!config.agents) {
|
|
1102
|
+
config.agents = { defaults: {}, list: [] };
|
|
1103
|
+
}
|
|
1104
|
+
if (!config.agents.list) {
|
|
1105
|
+
config.agents.list = [];
|
|
1106
|
+
}
|
|
1107
|
+
// ========================================
|
|
1108
|
+
// Add global config for agent-to-agent communication
|
|
1109
|
+
// ========================================
|
|
1110
|
+
if (!config.tools) {
|
|
1111
|
+
config.tools = {};
|
|
1112
|
+
}
|
|
1113
|
+
// Set sessions visibility to "all" (allow seeing all sessions)
|
|
1114
|
+
if (!config.tools.sessions) {
|
|
1115
|
+
config.tools.sessions = {};
|
|
1116
|
+
}
|
|
1117
|
+
if (!config.tools.sessions.visibility) {
|
|
1118
|
+
config.tools.sessions.visibility = 'all';
|
|
1119
|
+
}
|
|
1120
|
+
// Set maxPingPongTurns to 3 (limit ping-pong loops)
|
|
1121
|
+
if (!config.session) {
|
|
1122
|
+
config.session = {};
|
|
1123
|
+
}
|
|
1124
|
+
if (!config.session.agentToAgent) {
|
|
1125
|
+
config.session.agentToAgent = {};
|
|
1126
|
+
}
|
|
1127
|
+
if (config.session.agentToAgent.maxPingPongTurns === undefined) {
|
|
1128
|
+
config.session.agentToAgent.maxPingPongTurns = 3;
|
|
1129
|
+
}
|
|
1130
|
+
// Check if already exists
|
|
1131
|
+
const existingIndex = config.agents.list.findIndex((a) => a.id === agent.id);
|
|
1132
|
+
// Create Agent config item (official standard format)
|
|
1133
|
+
// Note: Never set default=true, preserve original default agent
|
|
1134
|
+
// Note: agentToAgent communication is controlled by tools.agentToAgent.allow, not subagents.allowAgents
|
|
1135
|
+
// Note: thinkingDefault is NOT a valid field in agents.list[], only in agents.defaults
|
|
1136
|
+
const agentConfig = {
|
|
1137
|
+
id: agent.id,
|
|
1138
|
+
workspace: agent.workspace_path || (0, utils_1.getAgentWorkspace)(agent.id),
|
|
1139
|
+
agentDir: (0, utils_1.getAgentDir)(agent.id),
|
|
1140
|
+
name: agent.name,
|
|
1141
|
+
// Inherit model from agents.defaults if set
|
|
1142
|
+
model: config.agents?.defaults?.model || { primary: 'bailian/glm-5' }
|
|
1143
|
+
};
|
|
1144
|
+
if (existingIndex >= 0) {
|
|
1145
|
+
// Update existing config, but preserve default if it was set
|
|
1146
|
+
const existingDefault = config.agents.list[existingIndex].default;
|
|
1147
|
+
config.agents.list[existingIndex] = agentConfig;
|
|
1148
|
+
// Preserve default flag
|
|
1149
|
+
if (existingDefault) {
|
|
1150
|
+
config.agents.list[existingIndex].default = existingDefault;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
else {
|
|
1154
|
+
// Add new config (without default)
|
|
1155
|
+
config.agents.list.push(agentConfig);
|
|
1156
|
+
}
|
|
1157
|
+
// Write back to file
|
|
1158
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
1159
|
+
return { success: true, message: 'OpenClaw 配置已同步' };
|
|
1160
|
+
}
|
|
1161
|
+
catch (error) {
|
|
1162
|
+
return {
|
|
1163
|
+
success: false,
|
|
1164
|
+
message: `同步配置失败: ${error instanceof Error ? error.message : String(error)}`
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Remove Agent from OpenClaw config
|
|
1170
|
+
*
|
|
1171
|
+
* Cleans up:
|
|
1172
|
+
* 1. agents.list - remove agent entry
|
|
1173
|
+
* 2. bindings - remove all bindings for this agent
|
|
1174
|
+
* 3. channels.feishu.accounts - remove feishu account config
|
|
1175
|
+
* 4. tools.agentToAgent.allow - remove from communication whitelist
|
|
1176
|
+
*
|
|
1177
|
+
* Note: Cannot remove main/assistant agent
|
|
1178
|
+
*/
|
|
1179
|
+
function removeAgentFromConfig(agentId) {
|
|
1180
|
+
try {
|
|
1181
|
+
const configPath = (0, utils_1.getOpenClawJsonPath)();
|
|
1182
|
+
if (!fs.existsSync(configPath)) {
|
|
1183
|
+
return { success: false, message: '配置文件不存在' };
|
|
1184
|
+
}
|
|
1185
|
+
// Protect main agent
|
|
1186
|
+
if (agentId === 'main') {
|
|
1187
|
+
return { success: false, message: '不能从配置中移除默认 agent (main)' };
|
|
1188
|
+
}
|
|
1189
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
1190
|
+
const config = JSON.parse(configContent);
|
|
1191
|
+
let configChanged = false;
|
|
1192
|
+
// 1. 从 agents.list 移除
|
|
1193
|
+
if (config.agents?.list) {
|
|
1194
|
+
const index = config.agents.list.findIndex((a) => a.id === agentId);
|
|
1195
|
+
if (index >= 0) {
|
|
1196
|
+
// Double-check: don't remove agent with default=true
|
|
1197
|
+
if (config.agents.list[index].default) {
|
|
1198
|
+
return { success: false, message: '不能从配置中移除默认 agent' };
|
|
1199
|
+
}
|
|
1200
|
+
config.agents.list.splice(index, 1);
|
|
1201
|
+
configChanged = true;
|
|
1202
|
+
console.log(`[Agent删除] 已从 agents.list 移除: ${agentId}`);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
// 2. 从 bindings 移除
|
|
1206
|
+
if (config.bindings && Array.isArray(config.bindings)) {
|
|
1207
|
+
const originalLength = config.bindings.length;
|
|
1208
|
+
config.bindings = config.bindings.filter((b) => b.agentId !== agentId);
|
|
1209
|
+
if (config.bindings.length < originalLength) {
|
|
1210
|
+
configChanged = true;
|
|
1211
|
+
console.log(`[Agent删除] 已移除 ${originalLength - config.bindings.length} 个绑定`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
// 3. 从 channels.feishu.accounts 移除
|
|
1215
|
+
const channels = config.channels;
|
|
1216
|
+
if (channels?.feishu) {
|
|
1217
|
+
const feishuConfig = channels.feishu;
|
|
1218
|
+
if (feishuConfig.accounts && typeof feishuConfig.accounts === 'object') {
|
|
1219
|
+
const accounts = feishuConfig.accounts;
|
|
1220
|
+
if (accounts[agentId]) {
|
|
1221
|
+
delete accounts[agentId];
|
|
1222
|
+
configChanged = true;
|
|
1223
|
+
console.log(`[Agent删除] 已移除飞书账号配置: ${agentId}`);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
// 4. 从 agentToAgent.allow 移除
|
|
1228
|
+
if (config.tools?.agentToAgent?.allow && Array.isArray(config.tools.agentToAgent.allow)) {
|
|
1229
|
+
const oldAllow = [...config.tools.agentToAgent.allow];
|
|
1230
|
+
config.tools.agentToAgent.allow = config.tools.agentToAgent.allow.filter((id) => id !== agentId);
|
|
1231
|
+
if (config.tools.agentToAgent.allow.length < oldAllow.length) {
|
|
1232
|
+
configChanged = true;
|
|
1233
|
+
console.log(`[Agent删除] 已从通信白名单移除: ${agentId}`);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
if (configChanged) {
|
|
1237
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
1238
|
+
return { success: true, message: 'Agent 配置已完整清理' };
|
|
1239
|
+
}
|
|
1240
|
+
else {
|
|
1241
|
+
return { success: true, message: 'Agent 不在配置中或无需清理' };
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
catch (error) {
|
|
1245
|
+
return {
|
|
1246
|
+
success: false,
|
|
1247
|
+
message: `移除失败: ${error instanceof Error ? error.message : String(error)}`
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Update Agent Allow List for team isolation
|
|
1253
|
+
*
|
|
1254
|
+
* When an agent is created or deleted, update the allowAgents list
|
|
1255
|
+
* for all agents in the same team.
|
|
1256
|
+
*
|
|
1257
|
+
* Rules:
|
|
1258
|
+
* - Team members can spawn to each other
|
|
1259
|
+
* - Assistant (main) has allowAgents: ["*"]
|
|
1260
|
+
* - Cross-team spawning is not allowed
|
|
1261
|
+
*
|
|
1262
|
+
* @param agentId - The agent that was created or will be deleted
|
|
1263
|
+
* @param departmentId - The department ID the agent belongs to
|
|
1264
|
+
* @param action - 'add' | 'remove'
|
|
1265
|
+
* @returns Result with affected agents and changes
|
|
1266
|
+
*/
|
|
1267
|
+
/**
|
|
1268
|
+
* Update Agent-to-Agent Communication Allow List
|
|
1269
|
+
*
|
|
1270
|
+
* Updates tools.agentToAgent.allow in openclaw.json
|
|
1271
|
+
* This is the official OpenClaw configuration for agent-to-agent communication control.
|
|
1272
|
+
*
|
|
1273
|
+
* Rules:
|
|
1274
|
+
* - All team members can communicate with each other
|
|
1275
|
+
* - Assistant (main) can communicate with all agents (use "*")
|
|
1276
|
+
* - Cross-team communication is allowed through this shared allow list
|
|
1277
|
+
*
|
|
1278
|
+
* @param agentId - The agent that was created or will be deleted
|
|
1279
|
+
* @param departmentId - The department ID the agent belongs to (not used in global config)
|
|
1280
|
+
* @param action - 'add' | 'remove'
|
|
1281
|
+
* @returns Result with old and new allow list values
|
|
1282
|
+
*/
|
|
1283
|
+
function updateAgentToAgentAllow(agentId, departmentId, action) {
|
|
1284
|
+
const result = {
|
|
1285
|
+
success: false,
|
|
1286
|
+
message: '',
|
|
1287
|
+
oldValue: [],
|
|
1288
|
+
newValue: []
|
|
1289
|
+
};
|
|
1290
|
+
try {
|
|
1291
|
+
const configPath = (0, utils_1.getOpenClawJsonPath)();
|
|
1292
|
+
if (!fs.existsSync(configPath)) {
|
|
1293
|
+
result.message = '配置文件不存在';
|
|
1294
|
+
return result;
|
|
1295
|
+
}
|
|
1296
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
1297
|
+
const config = JSON.parse(configContent);
|
|
1298
|
+
// Ensure tools.agentToAgent structure exists
|
|
1299
|
+
if (!config.tools) {
|
|
1300
|
+
config.tools = {};
|
|
1301
|
+
}
|
|
1302
|
+
if (!config.tools.agentToAgent) {
|
|
1303
|
+
config.tools.agentToAgent = { enabled: true, allow: [] };
|
|
1304
|
+
}
|
|
1305
|
+
if (!config.tools.agentToAgent.allow) {
|
|
1306
|
+
config.tools.agentToAgent.allow = [];
|
|
1307
|
+
}
|
|
1308
|
+
// Get current allow list
|
|
1309
|
+
const oldAllowList = [...config.tools.agentToAgent.allow];
|
|
1310
|
+
result.oldValue = oldAllowList;
|
|
1311
|
+
// Get all agents in the system (agent-to-agent is global, not per-department)
|
|
1312
|
+
const allAgents = agent_repo_1.agentRepository.findAll();
|
|
1313
|
+
// Build new allow list based on action
|
|
1314
|
+
let newAllowList;
|
|
1315
|
+
if (action === 'add') {
|
|
1316
|
+
// When adding an agent, rebuild the allow list with ALL agents (except main)
|
|
1317
|
+
// This ensures all team members can communicate with each other
|
|
1318
|
+
newAllowList = allAgents
|
|
1319
|
+
.filter(a => a.id !== 'main')
|
|
1320
|
+
.map(a => a.id);
|
|
1321
|
+
}
|
|
1322
|
+
else {
|
|
1323
|
+
// Remove the agent from the allow list
|
|
1324
|
+
newAllowList = oldAllowList.filter(id => id !== agentId);
|
|
1325
|
+
}
|
|
1326
|
+
result.newValue = newAllowList;
|
|
1327
|
+
// Skip if no change
|
|
1328
|
+
if (JSON.stringify(oldAllowList.sort()) === JSON.stringify(newAllowList.sort())) {
|
|
1329
|
+
result.success = true;
|
|
1330
|
+
result.message = '无需更新,配置已正确';
|
|
1331
|
+
return result;
|
|
1332
|
+
}
|
|
1333
|
+
// Update the config
|
|
1334
|
+
config.tools.agentToAgent.enabled = true;
|
|
1335
|
+
config.tools.agentToAgent.allow = newAllowList;
|
|
1336
|
+
// Write back to file
|
|
1337
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
1338
|
+
// Record to config_changes table
|
|
1339
|
+
configTracker.recordAgentToAgentChange(oldAllowList, newAllowList, action === 'add'
|
|
1340
|
+
? `添加 Agent ${agentId} 到通信白名单`
|
|
1341
|
+
: `从通信白名单移除 Agent ${agentId}`);
|
|
1342
|
+
result.success = true;
|
|
1343
|
+
result.message = `已更新 agentToAgent.allow: [${newAllowList.slice(0, 5).join(', ')}${newAllowList.length > 5 ? '...' : ''}]`;
|
|
1344
|
+
return result;
|
|
1345
|
+
}
|
|
1346
|
+
catch (error) {
|
|
1347
|
+
result.message = `更新失败: ${error instanceof Error ? error.message : String(error)}`;
|
|
1348
|
+
return result;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Initialize agentToAgent configuration
|
|
1353
|
+
*
|
|
1354
|
+
* Called during system initialization to set up agent-to-agent communication.
|
|
1355
|
+
* Builds the allow list from all existing agents.
|
|
1356
|
+
*/
|
|
1357
|
+
function initializeAgentToAgentConfig() {
|
|
1358
|
+
const result = {
|
|
1359
|
+
success: false,
|
|
1360
|
+
message: '',
|
|
1361
|
+
allowList: []
|
|
1362
|
+
};
|
|
1363
|
+
try {
|
|
1364
|
+
const configPath = (0, utils_1.getOpenClawJsonPath)();
|
|
1365
|
+
if (!fs.existsSync(configPath)) {
|
|
1366
|
+
result.message = '配置文件不存在';
|
|
1367
|
+
return result;
|
|
1368
|
+
}
|
|
1369
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
1370
|
+
const config = JSON.parse(configContent);
|
|
1371
|
+
// Ensure tools.agentToAgent structure exists
|
|
1372
|
+
if (!config.tools) {
|
|
1373
|
+
config.tools = {};
|
|
1374
|
+
}
|
|
1375
|
+
if (!config.tools.agentToAgent) {
|
|
1376
|
+
config.tools.agentToAgent = { enabled: true, allow: [] };
|
|
1377
|
+
}
|
|
1378
|
+
// Get all agents
|
|
1379
|
+
const allAgents = agent_repo_1.agentRepository.findAll();
|
|
1380
|
+
// Build allow list: all agents except main
|
|
1381
|
+
const allowList = allAgents
|
|
1382
|
+
.filter(a => a.id !== 'main')
|
|
1383
|
+
.map(a => a.id);
|
|
1384
|
+
config.tools.agentToAgent.enabled = true;
|
|
1385
|
+
config.tools.agentToAgent.allow = allowList;
|
|
1386
|
+
// Write back to file
|
|
1387
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
1388
|
+
result.allowList = allowList;
|
|
1389
|
+
result.success = true;
|
|
1390
|
+
result.message = `已初始化 agentToAgent 配置,共 ${allowList.length} 个 Agent`;
|
|
1391
|
+
return result;
|
|
1392
|
+
}
|
|
1393
|
+
catch (error) {
|
|
1394
|
+
result.message = `初始化失败: ${error instanceof Error ? error.message : String(error)}`;
|
|
1395
|
+
return result;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Legacy function for backward compatibility
|
|
1400
|
+
* @deprecated Use updateAgentToAgentAllow instead
|
|
1401
|
+
*/
|
|
1402
|
+
function updateAgentAllowList(agentId, departmentId, action) {
|
|
1403
|
+
const result = updateAgentToAgentAllow(agentId, departmentId, action);
|
|
1404
|
+
return {
|
|
1405
|
+
success: result.success,
|
|
1406
|
+
message: result.message,
|
|
1407
|
+
affectedAgents: [agentId],
|
|
1408
|
+
changes: [{
|
|
1409
|
+
agentId: agentId,
|
|
1410
|
+
oldValue: result.oldValue,
|
|
1411
|
+
newValue: result.newValue
|
|
1412
|
+
}]
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Get Gateway restart reminder message
|
|
1417
|
+
*
|
|
1418
|
+
* After deleting agents/departments, Feishu WebSocket connections
|
|
1419
|
+
* are still stored in Gateway process memory. Manual restart is required.
|
|
1420
|
+
*
|
|
1421
|
+
* @returns Reminder message for user to restart Gateway manually
|
|
1422
|
+
*/
|
|
1423
|
+
function getGatewayRestartReminder() {
|
|
1424
|
+
return '⚠️ 请重启 Gateway 使飞书长连接断开:openclaw gateway restart';
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Sync Feishu group info to all team members
|
|
1428
|
+
*
|
|
1429
|
+
* When a department binds/unbinds a Feishu group, update all members' AGENTS.md
|
|
1430
|
+
*
|
|
1431
|
+
* @param departmentId Department ID
|
|
1432
|
+
* @param groupId Feishu group ID (null for unbind)
|
|
1433
|
+
* @returns Sync result
|
|
1434
|
+
*/
|
|
1435
|
+
function syncTeamFeishuGroup(departmentId, groupId) {
|
|
1436
|
+
try {
|
|
1437
|
+
const agents = agent_repo_1.agentRepository.findByDepartment(departmentId);
|
|
1438
|
+
let updatedCount = 0;
|
|
1439
|
+
const displayId = groupId || '未绑定';
|
|
1440
|
+
const dept = dept_repo_1.departmentRepository.findById(departmentId);
|
|
1441
|
+
const displayName = groupId ? (dept?.name || '未知') : '未绑定';
|
|
1442
|
+
for (const agent of agents) {
|
|
1443
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agent.id);
|
|
1444
|
+
const agentsPath = path.join(workspacePath, 'AGENTS.md');
|
|
1445
|
+
if (!fs.existsSync(agentsPath))
|
|
1446
|
+
continue;
|
|
1447
|
+
const currentContent = fs.readFileSync(agentsPath, 'utf-8');
|
|
1448
|
+
// 查找群信息章节
|
|
1449
|
+
const startMarker = '## 飞书群信息';
|
|
1450
|
+
const endMarker = '## 团队成员';
|
|
1451
|
+
const startIndex = currentContent.indexOf(startMarker);
|
|
1452
|
+
const endIndex = currentContent.indexOf(endMarker);
|
|
1453
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
1454
|
+
const newGroupSection = `## 飞书群信息
|
|
1455
|
+
|
|
1456
|
+
### 所在群
|
|
1457
|
+
|
|
1458
|
+
- **群ID**: ${displayId}
|
|
1459
|
+
- **群名称**: ${displayName}
|
|
1460
|
+
|
|
1461
|
+
### 发送群消息
|
|
1462
|
+
|
|
1463
|
+
使用 \`message\` 工具发送群消息:
|
|
1464
|
+
|
|
1465
|
+
\`\`\`
|
|
1466
|
+
message(
|
|
1467
|
+
action="send",
|
|
1468
|
+
channel="feishu",
|
|
1469
|
+
to="${displayId}",
|
|
1470
|
+
message="消息内容"
|
|
1471
|
+
)
|
|
1472
|
+
\`\`\`
|
|
1473
|
+
|
|
1474
|
+
**参数说明:**
|
|
1475
|
+
|
|
1476
|
+
| 参数 | 说明 |
|
|
1477
|
+
|------|------|
|
|
1478
|
+
| \`action\` | 固定值 \`"send"\` |
|
|
1479
|
+
| \`channel\` | 固定值 \`"feishu"\` |
|
|
1480
|
+
| \`to\` | 群ID,从上方"所在群"获取。如为"未绑定"则无法发送 |
|
|
1481
|
+
| \`message\` | 消息内容,支持 Markdown 格式 |
|
|
1482
|
+
|
|
1483
|
+
### 发送时机
|
|
1484
|
+
|
|
1485
|
+
| 场景 | 消息内容 |
|
|
1486
|
+
|------|----------|
|
|
1487
|
+
| 任务相关通知 | 任务分配、进度汇报、审核结果等 |
|
|
1488
|
+
|
|
1489
|
+
---
|
|
1490
|
+
|
|
1491
|
+
`;
|
|
1492
|
+
const newContent = currentContent.substring(0, startIndex) +
|
|
1493
|
+
newGroupSection +
|
|
1494
|
+
currentContent.substring(endIndex);
|
|
1495
|
+
fs.writeFileSync(agentsPath, newContent, 'utf-8');
|
|
1496
|
+
updatedCount++;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
return {
|
|
1500
|
+
success: true,
|
|
1501
|
+
updatedCount,
|
|
1502
|
+
message: `已同步 ${updatedCount} 个成员的群信息`
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
catch (error) {
|
|
1506
|
+
return {
|
|
1507
|
+
success: false,
|
|
1508
|
+
updatedCount: 0,
|
|
1509
|
+
message: `同步失败: ${error instanceof Error ? error.message : String(error)}`
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Regenerate Agent Files
|
|
1515
|
+
*
|
|
1516
|
+
* Regenerates all agent files (AGENTS.md, SOUL.md, USER.md, MEMORY.md)
|
|
1517
|
+
* from the latest database templates and agent data.
|
|
1518
|
+
*
|
|
1519
|
+
* @param excludeAgentIds - Agent IDs to exclude (default: ['main', 'watchdog_main'])
|
|
1520
|
+
* @returns Result with regenerated count and any errors
|
|
1521
|
+
*/
|
|
1522
|
+
function regenerateAgentFiles(excludeAgentIds = ['main', 'watchdog_main']) {
|
|
1523
|
+
const result = {
|
|
1524
|
+
success: true,
|
|
1525
|
+
regeneratedCount: 0,
|
|
1526
|
+
errors: [],
|
|
1527
|
+
message: ''
|
|
1528
|
+
};
|
|
1529
|
+
try {
|
|
1530
|
+
// Get all agents from database
|
|
1531
|
+
const allAgents = agent_repo_1.agentRepository.findAll();
|
|
1532
|
+
// Filter out excluded agents
|
|
1533
|
+
const agentsToRegenerate = allAgents.filter(a => !excludeAgentIds.includes(a.id));
|
|
1534
|
+
console.log(`[重新生成] 找到 ${agentsToRegenerate.length} 个 Agent 需要重新生成文件`);
|
|
1535
|
+
for (const agent of agentsToRegenerate) {
|
|
1536
|
+
try {
|
|
1537
|
+
// Get workspace path
|
|
1538
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agent.id);
|
|
1539
|
+
// Check if workspace exists
|
|
1540
|
+
if (!fs.existsSync(workspacePath)) {
|
|
1541
|
+
result.errors.push(`Agent ${agent.id} (${agent.name}): 工作空间不存在`);
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
// Regenerate files using existing createAgentFiles function
|
|
1545
|
+
createAgentFiles(agent.id, {
|
|
1546
|
+
name: agent.name,
|
|
1547
|
+
role: agent.role,
|
|
1548
|
+
departmentId: agent.department_id || undefined,
|
|
1549
|
+
jobId: agent.job_id || undefined
|
|
1550
|
+
});
|
|
1551
|
+
result.regeneratedCount++;
|
|
1552
|
+
console.log(`[重新生成] ✓ Agent ${agent.id} (${agent.name})`);
|
|
1553
|
+
}
|
|
1554
|
+
catch (error) {
|
|
1555
|
+
const errorMsg = `Agent ${agent.id} (${agent.name}): ${error instanceof Error ? error.message : String(error)}`;
|
|
1556
|
+
result.errors.push(errorMsg);
|
|
1557
|
+
console.error(`[重新生成] ✗ ${errorMsg}`);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
// Sync assistant team members after regeneration
|
|
1561
|
+
const assistantSyncResult = syncAssistantTeamMembers();
|
|
1562
|
+
if (assistantSyncResult.success) {
|
|
1563
|
+
console.log(`[重新生成] 已同步总助理团队成员信息`);
|
|
1564
|
+
}
|
|
1565
|
+
result.message = `已重新生成 ${result.regeneratedCount}/${agentsToRegenerate.length} 个 Agent 的文件`;
|
|
1566
|
+
if (result.errors.length > 0) {
|
|
1567
|
+
result.message += `,${result.errors.length} 个失败`;
|
|
1568
|
+
result.success = false;
|
|
1569
|
+
}
|
|
1570
|
+
return result;
|
|
1571
|
+
}
|
|
1572
|
+
catch (error) {
|
|
1573
|
+
result.success = false;
|
|
1574
|
+
result.message = `重新生成失败: ${error instanceof Error ? error.message : String(error)}`;
|
|
1575
|
+
return result;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Regenerate files for a single agent
|
|
1580
|
+
*
|
|
1581
|
+
* @param agentId - Agent ID to regenerate files for
|
|
1582
|
+
* @returns Result with details
|
|
1583
|
+
*/
|
|
1584
|
+
function regenerateAgentFilesById(agentId) {
|
|
1585
|
+
try {
|
|
1586
|
+
const agent = agent_repo_1.agentRepository.findById(agentId);
|
|
1587
|
+
if (!agent) {
|
|
1588
|
+
return { success: false, message: `Agent ${agentId} 不存在` };
|
|
1589
|
+
}
|
|
1590
|
+
// Check if workspace exists
|
|
1591
|
+
const workspacePath = (0, utils_1.getAgentWorkspace)(agent.id);
|
|
1592
|
+
if (!fs.existsSync(workspacePath)) {
|
|
1593
|
+
return { success: false, message: `Agent ${agentId} 的工作空间不存在` };
|
|
1594
|
+
}
|
|
1595
|
+
// Regenerate files
|
|
1596
|
+
createAgentFiles(agent.id, {
|
|
1597
|
+
name: agent.name,
|
|
1598
|
+
role: agent.role,
|
|
1599
|
+
departmentId: agent.department_id || undefined,
|
|
1600
|
+
jobId: agent.job_id || undefined
|
|
1601
|
+
});
|
|
1602
|
+
return { success: true, message: `Agent ${agentId} (${agent.name}) 文件已重新生成` };
|
|
1603
|
+
}
|
|
1604
|
+
catch (error) {
|
|
1605
|
+
return {
|
|
1606
|
+
success: false,
|
|
1607
|
+
message: `重新生成失败: ${error instanceof Error ? error.message : String(error)}`
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
/**
|
|
1612
|
+
* OpenClaw integration helper service
|
|
1613
|
+
*/
|
|
1614
|
+
exports.openclawHelper = {
|
|
1615
|
+
getAgentSessionKey,
|
|
1616
|
+
getAgentWorkspacePath,
|
|
1617
|
+
prepareAgentContext,
|
|
1618
|
+
createAgentDirectories,
|
|
1619
|
+
createAgentFiles,
|
|
1620
|
+
syncOpenClawConfig,
|
|
1621
|
+
removeAgentFromConfig,
|
|
1622
|
+
updateAgentAllowList,
|
|
1623
|
+
updateAgentToAgentAllow,
|
|
1624
|
+
initializeAgentToAgentConfig,
|
|
1625
|
+
syncTeamFeishuGroup,
|
|
1626
|
+
regenerateAgentFiles,
|
|
1627
|
+
regenerateAgentFilesById
|
|
1628
|
+
};
|
|
1629
|
+
//# sourceMappingURL=openclaw-helper.js.map
|