evolcore 0.0.32 → 0.0.34
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/CHANGELOG.md +61 -0
- package/bin/ec.js +3 -2
- package/bin/install-codex-managed-hooks.mjs +135 -37
- package/dist/agents/baseagent-availability.js +20 -36
- package/dist/agents/claude-runner.js +111 -15
- package/dist/agents/codex/app-server-client.js +3 -0
- package/dist/agents/codex/diagnostics.js +112 -54
- package/dist/agents/codex-runner.js +241 -63
- package/dist/agents/ecagent-runner.js +78 -33
- package/dist/agents/runner-types.js +5 -6
- package/dist/aun/aid/identity.js +1 -1
- package/dist/aun/group/operations.js +0 -1
- package/dist/aun/msg/history.js +1 -0
- package/dist/aun/msg/p2p.js +0 -1
- package/dist/aun/outbox.js +50 -1
- package/dist/channels/aun.js +44 -8
- package/dist/channels/daemon.js +261 -3
- package/dist/cli/agent-command.js +58 -24
- package/dist/cli/agent.js +1 -1
- package/dist/cli/aun-commands.js +368 -31
- package/dist/cli/contact.js +8 -2
- package/dist/cli/ctl-command.js +3 -1
- package/dist/cli/daemon-commands.js +197 -27
- package/dist/cli/debug-mode.js +154 -0
- package/dist/cli/fs-command.js +2 -1
- package/dist/cli/handoff-command.js +3 -0
- package/dist/cli/index.js +98 -67
- package/dist/cli/init.js +2 -2
- package/dist/cli/integrity-command.js +196 -0
- package/dist/cli/managed-command-guard.js +5 -0
- package/dist/cli/memory-command.js +166 -146
- package/dist/cli/queue-command.js +9 -4
- package/dist/cli/session-command.js +194 -0
- package/dist/cli/skill-command.js +78 -2
- package/dist/cli/task-context.js +1 -0
- package/dist/cli/thread-command.js +622 -0
- package/dist/cli/trigger-command.js +10 -3
- package/dist/config/builtin-roles.js +1 -0
- package/dist/config/config-field-policy.js +6 -3
- package/dist/config/config-manager.js +26 -2
- package/dist/config/contact-book-store.js +5 -0
- package/dist/config/resolved-config-op.js +3 -0
- package/dist/config/role-service.js +13 -0
- package/dist/config/runtime-env.js +16 -0
- package/dist/config-store.js +45 -0
- package/dist/core/audit/log-integrity.js +3 -1
- package/dist/core/auth/agent-delegation.js +133 -36
- package/dist/core/auth/debug-context.js +139 -0
- package/dist/core/auth/delegation-diagnostics.js +414 -0
- package/dist/core/auth/operation-authorizer.js +25 -2
- package/dist/core/auth/operation-catalog.js +49 -0
- package/dist/core/background-session/session-cleanup.js +212 -0
- package/dist/core/background-session/types.js +10 -0
- package/dist/core/bootstrap-messages.js +1 -1
- package/dist/core/bootstrap-service.js +6 -3
- package/dist/core/command/agent-control.js +18 -26
- package/dist/core/command/command-handler.js +197 -27
- package/dist/core/command/daemon-diagnostics.js +1 -0
- package/dist/core/command/memory-slash.js +6 -2
- package/dist/core/command/menu-catalog.js +51 -1
- package/dist/core/command/menu-handler.js +114 -23
- package/dist/core/command/menu-protocol.js +25 -1
- package/dist/core/command/skill-slash.js +322 -0
- package/dist/core/command/slash-gate.js +6 -4
- package/dist/core/command/slash-handler.js +195 -13
- package/dist/core/command/topic-slash.js +528 -0
- package/dist/core/daemon-bootstrap.js +4 -7
- package/dist/core/evolagent-registry.js +20 -5
- package/dist/core/file-integrity/read.js +61 -0
- package/dist/core/file-integrity/store.js +262 -0
- package/dist/core/handoff/runtime.js +5 -11
- package/dist/core/handoff/store.js +5 -0
- package/dist/core/ipc-registration.js +175 -3
- package/dist/core/memory/batch-meta.js +132 -0
- package/dist/core/memory/consolidation-context.js +83 -29
- package/dist/core/memory/consolidation-ops-records.js +49 -16
- package/dist/core/memory/consolidation-queue-format.js +21 -0
- package/dist/core/memory/consolidation.js +264 -205
- package/dist/core/memory/index-manager.js +19 -28
- package/dist/core/memory/memory-admin.js +19 -14
- package/dist/core/memory/memory-document.js +53 -9
- package/dist/core/memory/memory-writer.js +30 -15
- package/dist/core/message/aun-ipc-sender.js +161 -6
- package/dist/core/message/im-renderer.js +169 -10
- package/dist/core/message/message-bridge.js +15 -4
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/peer-mode.js +6 -1
- package/dist/core/message/response-engine.js +929 -110
- package/dist/core/message/subtask-tool-projection.js +140 -0
- package/dist/core/model/catalog-service.js +17 -12
- package/dist/core/permission/ec-command-parser.js +217 -9
- package/dist/core/permission/protected-paths.js +5 -1
- package/dist/core/permission/readonly-shell-query.js +43 -5
- package/dist/core/permission/session-path-grants.js +334 -0
- package/dist/core/permission/tool-canonical.js +226 -0
- package/dist/core/permission/tool-policy.js +30 -62
- package/dist/core/role/runtime-policy.js +21 -10
- package/dist/core/session/session-fs-store.js +123 -8
- package/dist/core/session/session-idle-monitor.js +249 -22
- package/dist/core/session/session-manager.js +129 -14
- package/dist/core/skill/command-parser.js +13 -0
- package/dist/core/skill/index-generator.js +21 -4
- package/dist/core/skill/startup.js +41 -0
- package/dist/core/skill/switch-resolver.js +55 -29
- package/dist/core/system-session/grants.js +40 -0
- package/dist/core/system-session/memory.js +222 -0
- package/dist/core/system-session/registry.js +74 -0
- package/dist/core/system-session/types.js +14 -0
- package/dist/core/thread/command-parser.js +125 -0
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +95 -0
- package/dist/core/thread/thread-context-storage.js +131 -0
- package/dist/core/thread/thread-operation.js +258 -0
- package/dist/core/thread/thread-route.js +33 -0
- package/dist/core/thread/thread-service.js +770 -0
- package/dist/core/thread/types.js +1 -0
- package/dist/eck/kit-renderer.js +7 -2
- package/dist/eck/manifest-engine.js +24 -4
- package/dist/eck/message-renderer.js +35 -0
- package/dist/index.js +19 -7
- package/dist/ipc.js +140 -50
- package/dist/paths.js +93 -0
- package/dist/response-system/engines/v1/proactive-flow.js +169 -80
- package/dist/stats/billing.js +20 -8
- package/dist/trigger/authorization.js +57 -28
- package/dist/trigger/feedback.js +13 -2
- package/dist/trigger/parser.js +70 -1
- package/dist/trigger/system-definitions.js +3 -3
- package/dist/trigger/validation.js +14 -0
- package/dist/utils/cross-platform.js +11 -2
- package/dist/utils/error-dict.json +18 -4
- package/dist/utils/error-utils.js +143 -1
- package/dist/utils/instance-registry.js +13 -8
- package/dist/utils/log-writer.js +12 -0
- package/dist/utils/process-introspect.js +11 -0
- package/kits/docs/context-assembly.md +1 -1
- package/kits/docs/evolcore/INDEX.md +1 -0
- package/kits/docs/evolcore/agent-create.md +40 -28
- package/kits/docs/evolcore/agent.md +21 -6
- package/kits/docs/evolcore/config.md +2 -2
- package/kits/docs/evolcore/ctl.md +2 -2
- package/kits/docs/evolcore/ec-capabilities.md +5 -1
- package/kits/docs/evolcore/fs-architecture.md +4 -5
- package/kits/docs/evolcore/fs.md +1 -1
- package/kits/docs/evolcore/group-collaboration.md +4 -6
- package/kits/docs/evolcore/group.md +11 -12
- package/kits/docs/evolcore/memory-architecture.md +4 -5
- package/kits/docs/evolcore/memory-consolidation.md +19 -15
- package/kits/docs/evolcore/memory-tags.md +3 -1
- package/kits/docs/evolcore/memory.md +24 -12
- package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
- package/kits/docs/evolcore/menu-protocol.md +7 -0
- package/kits/docs/evolcore/model.md +16 -0
- package/kits/docs/evolcore/msg.md +8 -11
- package/kits/docs/evolcore/thread-chain.md +267 -0
- package/kits/docs/prompt-loading-architecture.md +1 -1
- package/kits/eck_manifest.json +55 -40
- package/kits/eck_manifest.memory.json +0 -12
- package/kits/eck_message_manifest.json +169 -10
- package/kits/rules/01-overview.md +11 -0
- package/kits/rules/03-identity.md +6 -3
- package/kits/rules/05-venue.md +1 -1
- package/kits/rules/06-channel.md +1 -1
- package/kits/rules/07-memory-and-thread.md +199 -0
- package/kits/schemas/_meta.json +7 -1
- package/kits/schemas/agent-config.schema.13.json +1 -1
- package/kits/schemas/daemon.schema.7.json +140 -0
- package/kits/schemas/relation-config.schema.9.json +18 -3
- package/kits/schemas/role-config.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.2.json +6 -6
- package/kits/schemas/single-session.schema.3.json +6 -6
- package/kits/skills/.switches.json +12 -1
- package/kits/skills/ec-group/SKILL.md +234 -0
- package/kits/skills/ec-skill/SKILL.md +10 -1
- package/kits/skills/ec-skill/scripts/cli.mjs +16 -2
- package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
- package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
- package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
- package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
- package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
- package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
- package/kits/skills/thread-ops/SKILL.md +492 -0
- package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
- package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
- package/kits/skills/wechat-article-reader/SKILL.md +97 -0
- package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
- package/kits/templates/bootstrap-welcome.md +7 -7
- package/kits/templates/memory-consolidation/forget.md +7 -2
- package/kits/templates/memory-consolidation/generalize.md +9 -4
- package/kits/templates/memory-consolidation/notes.md +11 -11
- package/kits/templates/memory-consolidation/profile.md +8 -3
- package/kits/templates/memory-consolidation/promote.md +8 -3
- package/kits/templates/memory-consolidation/workflow.md +6 -6
- package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
- package/kits/templates/message-fragments/item.md +2 -1
- package/kits/templates/message-fragments/thread-context.md +6 -0
- package/kits/templates/message-fragments/trigger-session.md +2 -0
- package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
- package/kits/templates/roles/member.json +2 -0
- package/kits/templates/roles/visitor.json +2 -0
- package/kits/templates/system-fragments/bootstrap.md +67 -72
- package/kits/templates/system-fragments/channel.md +3 -6
- package/kits/templates/system-fragments/commands.md +1 -0
- package/kits/templates/system-fragments/managed-runtime.md +15 -0
- package/kits/templates/system-fragments/memory.md +16 -9
- package/kits/templates/system-fragments/reply.md +7 -6
- package/kits/templates/system-fragments/session.md +5 -14
- package/package.json +6 -3
- package/dist/core/memory/memory-session-policy.js +0 -41
- package/dist/core/memory/memory-signature.js +0 -257
- package/kits/docs/evolcore/group-fs.md +0 -17
- package/kits/docs/venues/aun-group.md +0 -45
- package/kits/docs/venues/group.md +0 -43
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session-cleanup.ts — 独立后台会话(bg-session)和 trigger 会话的清理机制
|
|
3
|
+
*
|
|
4
|
+
* 三种自动清理模式:
|
|
5
|
+
* immediate — 会话结束时同步清理
|
|
6
|
+
* on_next_launch — 下次同 kind 会话启动时清理上一次的残留(默认)
|
|
7
|
+
* expire — 会话结束时写登记表,启动时扫描到期条目清理
|
|
8
|
+
*
|
|
9
|
+
* 登记表路径:$EVOLCORE_HOME/data/session-cleanup/expire-<YYYYMMDD>.jsonl
|
|
10
|
+
* 详见 docs/background-session/session-cleanup-policy.md
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { resolveRoot } from '../../paths.js';
|
|
15
|
+
import { logger } from '../../utils/logger.js';
|
|
16
|
+
// ── 登记表工具 ──────────────────────────────────────────────────────────────
|
|
17
|
+
function cleanupDir() {
|
|
18
|
+
return path.join(resolveRoot(), 'data', 'session-cleanup');
|
|
19
|
+
}
|
|
20
|
+
function expireFilePath(date) {
|
|
21
|
+
const y = date.getFullYear();
|
|
22
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
23
|
+
const d = String(date.getDate()).padStart(2, '0');
|
|
24
|
+
return path.join(cleanupDir(), `expire-${y}${m}${d}.jsonl`);
|
|
25
|
+
}
|
|
26
|
+
function doneFilePath(expirePath) {
|
|
27
|
+
return expirePath.replace(/\.jsonl$/, '.done.jsonl');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 把一条超期记录写进今天的登记表。
|
|
31
|
+
* 幂等:同一 channelId 写多次无害,runExpireCleanup 会逐条处理。
|
|
32
|
+
*/
|
|
33
|
+
export function appendExpireEntry(entry) {
|
|
34
|
+
try {
|
|
35
|
+
const dir = cleanupDir();
|
|
36
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
37
|
+
const filePath = expireFilePath(new Date(entry.expireAt));
|
|
38
|
+
fs.appendFileSync(filePath, JSON.stringify(entry) + '\n', 'utf-8');
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
logger.warn(`[SessionCleanup] 写入超期登记表失败: ${e?.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 清理一条 evolcore session 记录(移入 _trash/)。
|
|
46
|
+
* runner 侧日志不在这里处理(runner 接口尚未提供 deleteSession)。
|
|
47
|
+
*/
|
|
48
|
+
export async function cleanupSessionRecord(target, cleaner) {
|
|
49
|
+
try {
|
|
50
|
+
await cleaner.softDeleteSession(target.channelId);
|
|
51
|
+
logger.debug(`[SessionCleanup] 已清理 session 记录: channelId=${target.channelId}` +
|
|
52
|
+
`${target.agentAid ? ` aid=${target.agentAid}` : ''}`);
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
logger.warn(`[SessionCleanup] 清理 session 记录失败 channelId=${target.channelId}: ${e?.message}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ── expire 模式:启动时扫描 ──────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* 扫描 data/session-cleanup/ 下所有登记表,清理已到期的条目。
|
|
61
|
+
* 在任意 bg-session 或 trigger 会话启动时调用,成本低(只读少量小文件)。
|
|
62
|
+
*/
|
|
63
|
+
export async function runExpireCleanup(cleaner, now = Date.now()) {
|
|
64
|
+
const dir = cleanupDir();
|
|
65
|
+
if (!fs.existsSync(dir))
|
|
66
|
+
return;
|
|
67
|
+
let files;
|
|
68
|
+
try {
|
|
69
|
+
files = fs.readdirSync(dir).filter(f => /^expire-\d{8}\.jsonl$/.test(f));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const todayStr = (() => {
|
|
75
|
+
const d = new Date(now);
|
|
76
|
+
const y = d.getFullYear();
|
|
77
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
78
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
79
|
+
return `expire-${y}${m}${day}.jsonl`;
|
|
80
|
+
})();
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
// 跳过未来日期的文件(expireAt 不可能到期)
|
|
83
|
+
const fileDate = file.slice(7, 15); // expire-YYYYMMDD.jsonl → YYYYMMDD
|
|
84
|
+
const todayDate = todayStr.slice(7, 15);
|
|
85
|
+
if (fileDate > todayDate)
|
|
86
|
+
continue;
|
|
87
|
+
const filePath = path.join(dir, file);
|
|
88
|
+
const donePath = doneFilePath(filePath);
|
|
89
|
+
let lines;
|
|
90
|
+
try {
|
|
91
|
+
lines = fs.readFileSync(filePath, 'utf-8').split('\n').filter(l => l.trim());
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// 读取已处理的 channelId 集合
|
|
97
|
+
const doneIds = new Set();
|
|
98
|
+
if (fs.existsSync(donePath)) {
|
|
99
|
+
try {
|
|
100
|
+
for (const line of fs.readFileSync(donePath, 'utf-8').split('\n').filter(l => l.trim())) {
|
|
101
|
+
const entry = JSON.parse(line);
|
|
102
|
+
if (entry.channelId)
|
|
103
|
+
doneIds.add(entry.channelId);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch { /* 损坏的 done 文件,跳过去重,重复清理幂等 */ }
|
|
107
|
+
}
|
|
108
|
+
let processedCount = 0;
|
|
109
|
+
// 文件里是否还有未到期条目;有则保留文件,下次再扫
|
|
110
|
+
let hasPending = false;
|
|
111
|
+
for (const line of lines) {
|
|
112
|
+
let entry;
|
|
113
|
+
try {
|
|
114
|
+
entry = JSON.parse(line);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (!entry.channelId || !entry.expireAt)
|
|
120
|
+
continue;
|
|
121
|
+
if (entry.expireAt > now) {
|
|
122
|
+
hasPending = true;
|
|
123
|
+
continue;
|
|
124
|
+
} // 未到期
|
|
125
|
+
if (doneIds.has(entry.channelId))
|
|
126
|
+
continue; // 已处理
|
|
127
|
+
await cleanupSessionRecord({ sessionId: entry.sessionId, channelId: entry.channelId, agentAid: entry.agentAid }, cleaner);
|
|
128
|
+
// 标记已处理
|
|
129
|
+
try {
|
|
130
|
+
fs.appendFileSync(donePath, JSON.stringify({ channelId: entry.channelId, ts: now }) + '\n', 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
catch { /* 写失败无妨,下次会重复处理,cleanupSessionRecord 幂等 */ }
|
|
133
|
+
doneIds.add(entry.channelId);
|
|
134
|
+
processedCount++;
|
|
135
|
+
}
|
|
136
|
+
if (processedCount > 0) {
|
|
137
|
+
logger.debug(`[SessionCleanup] expire 扫描:清理 ${processedCount} 条到期记录(${file})`);
|
|
138
|
+
}
|
|
139
|
+
// 整天文件全部处理完时,删除两个文件。
|
|
140
|
+
// 不能用 doneIds.size 与行数比较:同一 channelId 重复登记时两者永远不等,文件会残留。
|
|
141
|
+
if (!hasPending) {
|
|
142
|
+
try {
|
|
143
|
+
fs.unlinkSync(filePath);
|
|
144
|
+
}
|
|
145
|
+
catch { /* ignore */ }
|
|
146
|
+
try {
|
|
147
|
+
fs.unlinkSync(donePath);
|
|
148
|
+
}
|
|
149
|
+
catch { /* ignore */ }
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ── on_next_launch 模式:按 kind 清理历史会话 ────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* 记录一条 on_next_launch 清理登记,供下次启动时使用。
|
|
156
|
+
* 存在一个独立的 JSONL 文件中,按 kind 分文件存储。
|
|
157
|
+
*/
|
|
158
|
+
function nextLaunchFilePath(kind) {
|
|
159
|
+
const safeKind = kind.replace(/[^a-zA-Z0-9\-_]/g, '_');
|
|
160
|
+
return path.join(cleanupDir(), `next-launch-${safeKind}.jsonl`);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 记录一条「下次启动时清理」的会话信息。
|
|
164
|
+
* 在会话正常或异常结束时调用。
|
|
165
|
+
*/
|
|
166
|
+
export function recordNextLaunchCleanup(kind, entry) {
|
|
167
|
+
try {
|
|
168
|
+
const dir = cleanupDir();
|
|
169
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
170
|
+
const filePath = nextLaunchFilePath(kind);
|
|
171
|
+
fs.appendFileSync(filePath, JSON.stringify(entry) + '\n', 'utf-8');
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
logger.warn(`[SessionCleanup] 写入 on_next_launch 登记失败 kind=${kind}: ${e?.message}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 清理同 kind 的所有历史会话记录,然后清空登记文件。
|
|
179
|
+
* 在新会话启动前调用(on_next_launch 模式)。
|
|
180
|
+
*/
|
|
181
|
+
export async function cleanupPreviousByKind(kind, cleaner) {
|
|
182
|
+
const filePath = nextLaunchFilePath(kind);
|
|
183
|
+
if (!fs.existsSync(filePath))
|
|
184
|
+
return;
|
|
185
|
+
let lines;
|
|
186
|
+
try {
|
|
187
|
+
lines = fs.readFileSync(filePath, 'utf-8').split('\n').filter(l => l.trim());
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
for (const line of lines) {
|
|
193
|
+
let entry;
|
|
194
|
+
try {
|
|
195
|
+
entry = JSON.parse(line);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (!entry.channelId)
|
|
201
|
+
continue;
|
|
202
|
+
await cleanupSessionRecord({ sessionId: entry.sessionId, channelId: entry.channelId, agentAid: entry.agentAid }, cleaner);
|
|
203
|
+
}
|
|
204
|
+
// 清空登记文件(下一次重新积累)
|
|
205
|
+
try {
|
|
206
|
+
fs.unlinkSync(filePath);
|
|
207
|
+
}
|
|
208
|
+
catch { /* ignore */ }
|
|
209
|
+
if (lines.length > 0) {
|
|
210
|
+
logger.debug(`[SessionCleanup] on_next_launch:已清理 ${lines.length} 条历史记录(kind=${kind})`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -53,7 +53,7 @@ export function renderPostBootstrapWelcome(aid, owner, ownerName) {
|
|
|
53
53
|
}
|
|
54
54
|
const config = loadAgent(aid);
|
|
55
55
|
if (config && resolveAgentLifecycle(config) === 'bootstrapping' && config.initialization?.mode !== 'supplied') {
|
|
56
|
-
throw new Error('WELCOME_REQUIRED:
|
|
56
|
+
throw new Error('WELCOME_REQUIRED: Agent-prepared welcome.md is required before activation');
|
|
57
57
|
}
|
|
58
58
|
return generateWelcomeMessage({
|
|
59
59
|
channelType: 'aun',
|
|
@@ -25,14 +25,17 @@ export async function completeBootstrapWithWelcome(service, aid, welcome, sessio
|
|
|
25
25
|
}
|
|
26
26
|
if (lifecycle === 'bootstrapping') {
|
|
27
27
|
// Existing per-Owner records are immutable retry snapshots. New interactive
|
|
28
|
-
// Bootstrap completions require the text
|
|
28
|
+
// Bootstrap completions require the welcome text prepared by the Agent.
|
|
29
29
|
const config = loadAgent(aid);
|
|
30
30
|
const deliveries = config?.owners?.length ? postBootstrapWelcomeStatus(aid, config.owners).deliveries : [];
|
|
31
31
|
const alreadyPrepared = deliveries.length > 0 && deliveries.every(delivery => delivery.status !== 'not_prepared');
|
|
32
32
|
if (config?.initialization?.mode !== 'supplied' && !alreadyPrepared) {
|
|
33
33
|
try {
|
|
34
34
|
if (readAgentWelcomeTemplate(aid) === null) {
|
|
35
|
-
return {
|
|
35
|
+
return {
|
|
36
|
+
ok: false, code: 'WELCOME_REQUIRED', reloaded: false,
|
|
37
|
+
error: '请先自主生成正式欢迎文案并保存 welcome.md,无需 Owner 确认',
|
|
38
|
+
};
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
catch (error) {
|
|
@@ -446,7 +449,7 @@ export class BootstrapService {
|
|
|
446
449
|
const templatePath = path.join(kitsTemplatesDir(), 'bootstrap-welcome.md');
|
|
447
450
|
const template = fs.existsSync(templatePath)
|
|
448
451
|
? fs.readFileSync(templatePath, 'utf-8')
|
|
449
|
-
: '你好,我是 {{agentName}}
|
|
452
|
+
: '你好,我是 {{agentName}}。已有的有效基础信息会直接沿用;请补充缺失的显示名、简介或标签。persona 和头像可选,之后也可以完善。';
|
|
450
453
|
return renderTemplate(template, vars).trim();
|
|
451
454
|
}
|
|
452
455
|
resolveAgentDisplayName(aid) {
|
|
@@ -583,9 +583,24 @@ export async function execAgentUpdate(args, subject) {
|
|
|
583
583
|
if (p.channels !== undefined && p.channelOwners !== undefined) {
|
|
584
584
|
return { error: 'channels 与 channelOwners 不能同时提交', code: 'INVALID_ARGS' };
|
|
585
585
|
}
|
|
586
|
-
const config = cfgRead(ConfigTarget.Agent, { self: a.aid });
|
|
586
|
+
const config = cfgRead(ConfigTarget.Agent, { self: a.aid }, { cache: false });
|
|
587
587
|
if (!config)
|
|
588
588
|
return { error: `Agent "${a.aid}" not found`, code: 'NOT_FOUND' };
|
|
589
|
+
if (p.fullaccess !== undefined) {
|
|
590
|
+
if (!p.fullaccess || typeof p.fullaccess !== 'object' || Array.isArray(p.fullaccess)) {
|
|
591
|
+
return { error: 'fullaccess 必须是对象', code: 'INVALID_ARGS' };
|
|
592
|
+
}
|
|
593
|
+
const fullaccess = p.fullaccess;
|
|
594
|
+
if (Object.keys(fullaccess).some(key => key !== 'enabled')) {
|
|
595
|
+
return { error: 'fullaccess 只支持 enabled 字段', code: 'INVALID_ARGS' };
|
|
596
|
+
}
|
|
597
|
+
if (typeof fullaccess.enabled !== 'boolean') {
|
|
598
|
+
return { error: 'fullaccess.enabled 必须是布尔值', code: 'INVALID_ARGS' };
|
|
599
|
+
}
|
|
600
|
+
const denied = agentFullAccessWriteError(a.aid, subject);
|
|
601
|
+
if (denied)
|
|
602
|
+
return { error: denied, code: 'FORBIDDEN' };
|
|
603
|
+
}
|
|
589
604
|
// Legacy App requests share the canonical validation, storage and agent.md publication flow.
|
|
590
605
|
if (Object.hasOwn(p, 'avatar'))
|
|
591
606
|
return execAidAvatar({ aid: a.aid, data: p.avatar });
|
|
@@ -640,27 +655,7 @@ export async function execAgentUpdate(args, subject) {
|
|
|
640
655
|
touched = true;
|
|
641
656
|
}
|
|
642
657
|
if (p.fullaccess !== undefined) {
|
|
643
|
-
|
|
644
|
-
return { error: 'fullaccess 必须是对象', code: 'INVALID_ARGS' };
|
|
645
|
-
}
|
|
646
|
-
const fullaccess = p.fullaccess;
|
|
647
|
-
if (Object.keys(fullaccess).some(key => key !== 'enabled')) {
|
|
648
|
-
return { error: 'fullaccess 只支持 enabled 字段', code: 'INVALID_ARGS' };
|
|
649
|
-
}
|
|
650
|
-
if (fullaccess.enabled !== undefined && typeof fullaccess.enabled !== 'boolean') {
|
|
651
|
-
return { error: 'fullaccess.enabled 必须是布尔值', code: 'INVALID_ARGS' };
|
|
652
|
-
}
|
|
653
|
-
if (typeof fullaccess.enabled !== 'boolean')
|
|
654
|
-
return { error: 'fullaccess.enabled is required', code: 'INVALID_ARGS' };
|
|
655
|
-
const denied = agentFullAccessWriteError({
|
|
656
|
-
daemonOwner: subject?.isDaemonOwner === true,
|
|
657
|
-
ecwebManagement: subject?.ecwebManagement === true,
|
|
658
|
-
delegated: subject?.canApprovePersistentFullAccess === false || subject?.chatType === 'group',
|
|
659
|
-
enabled: fullaccess.enabled,
|
|
660
|
-
});
|
|
661
|
-
if (denied)
|
|
662
|
-
return { error: denied, code: 'FORBIDDEN' };
|
|
663
|
-
config.fullaccess = { enabled: fullaccess.enabled };
|
|
658
|
+
config.fullaccess = { enabled: p.fullaccess.enabled };
|
|
664
659
|
touched = true;
|
|
665
660
|
}
|
|
666
661
|
if (p.chatmode !== undefined) {
|
|
@@ -747,10 +742,7 @@ export async function execAgentQuery(args, service, subject) {
|
|
|
747
742
|
safeConfig,
|
|
748
743
|
fullaccessStatus: {
|
|
749
744
|
...fullaccessStatus,
|
|
750
|
-
canConfigure: subject
|
|
751
|
-
&& subject?.isDaemonOwner === true
|
|
752
|
-
&& subject.canApprovePersistentFullAccess !== false
|
|
753
|
-
&& subject.chatType !== 'group',
|
|
745
|
+
canConfigure: agentFullAccessWriteError(aid, subject) === undefined,
|
|
754
746
|
},
|
|
755
747
|
};
|
|
756
748
|
// 叠加构建进度(create 受理后、ready 前可见;ready 后文件仍在,可反映软失败 warn)
|