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
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* consolidation-context.ts — 整理上下文 MD 文档序列化(v3)
|
|
3
3
|
*
|
|
4
|
-
* 把一次整理所需的全部信息序列化成 Markdown
|
|
5
|
-
* -
|
|
6
|
-
*
|
|
4
|
+
* 把一次整理所需的全部信息序列化成 Markdown,写一处:
|
|
5
|
+
* - $EVOLCORE_HOME/memory/consolidation-batches/<批次目录>/context.md
|
|
6
|
+
*
|
|
7
|
+
* 任务书只有一个落点。此前另写一份到会话运行目录(sessionRuntimeDir,缺省回落
|
|
8
|
+
* $EVOLCORE_HOME/tmp),导致落点随触发路径漂移,且该目录的读取范围不由任务书所在
|
|
9
|
+
* 的整理会话决定——整理会话读自己的任务书会被只读判定拦成 workspace_escape。
|
|
10
|
+
* 见 docs/memory/session-profile-design.md §5.1。
|
|
7
11
|
*
|
|
8
12
|
* 批次目录命名:<YYYYMMDDTHHmmss>-<selfAid>-<mode>/
|
|
9
13
|
* 批次目录内:context.md(任务书)、ops.jsonl(操作流水)、threads/(话题快照)
|
|
@@ -15,6 +19,8 @@ import { resolveRoot, resolvePaths } from '../../paths.js';
|
|
|
15
19
|
import { DEFAULT_FORGET_AFTER_DAYS, collectCandidates, isDueForReview } from './staleness.js';
|
|
16
20
|
import { chatDirPath } from '../session/session-fs-store.js';
|
|
17
21
|
import { getMemoryArray, getMemoryString, parseMemoryDocument } from './memory-document.js';
|
|
22
|
+
import { writeBatchMeta } from './batch-meta.js';
|
|
23
|
+
import { feedbackFilePath } from './consolidation-ops-records.js';
|
|
18
24
|
export const CONSOLIDATION_MODES = ['notes', 'generalize', 'promote', 'profile', 'forget'];
|
|
19
25
|
/**
|
|
20
26
|
* 模式 → 允许写入的作用域(不含 forget)。
|
|
@@ -34,7 +40,14 @@ export const MODE_SCOPE = {
|
|
|
34
40
|
// 超期判据集中在 staleness.ts;这里做转发,保证 trigger 与 context 用同一套规则
|
|
35
41
|
export { DEFAULT_FORGET_AFTER_DAYS, LONG_TERM_REVIEW_DAYS } from './staleness.js';
|
|
36
42
|
// ── Checkpoint 读写 ──────────────────────────────────────────────────────────
|
|
37
|
-
const
|
|
43
|
+
const LEGACY_CHECKPOINT_FILE = 'consolidation-checkpoint.json';
|
|
44
|
+
/** C1: checkpoint file name per mode; forget uses scopeOverride suffix. */
|
|
45
|
+
function checkpointFileName(mode, scopeOverride) {
|
|
46
|
+
if (mode === 'forget' && scopeOverride) {
|
|
47
|
+
return `consolidation-checkpoint-forget-${scopeOverride}.json`;
|
|
48
|
+
}
|
|
49
|
+
return `consolidation-checkpoint-${mode}.json`;
|
|
50
|
+
}
|
|
38
51
|
/**
|
|
39
52
|
* Move the pre-0.0.29 consolidation artifact root to its new name. Existing
|
|
40
53
|
* batches are user data, so conflicts are preserved under a legacy suffix
|
|
@@ -70,22 +83,37 @@ export function migrateLegacyConsolidationBatches() {
|
|
|
70
83
|
fs.rmSync(legacyRoot, { recursive: true, force: true });
|
|
71
84
|
}
|
|
72
85
|
/** 读上次整理时间戳(毫秒)。文件不存在或解析失败返回 0(取全量历史)。 */
|
|
73
|
-
export function readCheckpoint(chatDir) {
|
|
86
|
+
export function readCheckpoint(chatDir, mode, scopeOverride) {
|
|
87
|
+
const filePath = path.join(chatDir, checkpointFileName(mode, scopeOverride));
|
|
74
88
|
try {
|
|
75
|
-
const raw = fs.readFileSync(
|
|
89
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
76
90
|
const parsed = JSON.parse(raw);
|
|
77
91
|
const v = Number(parsed.lastConsolidatedAt);
|
|
78
|
-
|
|
92
|
+
if (Number.isFinite(v))
|
|
93
|
+
return v;
|
|
79
94
|
}
|
|
80
|
-
catch {
|
|
81
|
-
|
|
95
|
+
catch { /* 新文件不存在,尝试迁移旧文件 */ }
|
|
96
|
+
// 向后兼容: notes 模式读旧的 consolidation-checkpoint.json,成功后自动迁移
|
|
97
|
+
if (mode === 'notes') {
|
|
98
|
+
try {
|
|
99
|
+
const legacyPath = path.join(chatDir, LEGACY_CHECKPOINT_FILE);
|
|
100
|
+
const raw = fs.readFileSync(legacyPath, 'utf-8');
|
|
101
|
+
const parsed = JSON.parse(raw);
|
|
102
|
+
const v = Number(parsed.lastConsolidatedAt);
|
|
103
|
+
if (Number.isFinite(v)) {
|
|
104
|
+
writeCheckpoint(chatDir, v, mode, scopeOverride);
|
|
105
|
+
return v;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch { /* ignore */ }
|
|
82
109
|
}
|
|
110
|
+
return 0;
|
|
83
111
|
}
|
|
84
112
|
/** 写整理完成时间戳。由 index.ts 在整理会话完成后调用。 */
|
|
85
|
-
export function writeCheckpoint(chatDir, lastConsolidatedAt) {
|
|
113
|
+
export function writeCheckpoint(chatDir, lastConsolidatedAt, mode, scopeOverride) {
|
|
86
114
|
try {
|
|
87
115
|
fs.mkdirSync(chatDir, { recursive: true });
|
|
88
|
-
fs.writeFileSync(path.join(chatDir,
|
|
116
|
+
fs.writeFileSync(path.join(chatDir, checkpointFileName(mode, scopeOverride)), JSON.stringify({ lastConsolidatedAt }, null, 2) + '\n', 'utf-8');
|
|
89
117
|
}
|
|
90
118
|
catch { /* 失败静默 */ }
|
|
91
119
|
}
|
|
@@ -276,7 +304,7 @@ function shortTime(time) {
|
|
|
276
304
|
*
|
|
277
305
|
* 返回生成的文件路径列表(空列表表示无增量消息或读取失败)。
|
|
278
306
|
*/
|
|
279
|
-
function buildThreadSnapshots(historyJsonlPath, sinceMs, threadsDir) {
|
|
307
|
+
function buildThreadSnapshots(historyJsonlPath, sinceMs, threadsDir, throughMs) {
|
|
280
308
|
const rawLines = fs.readFileSync(historyJsonlPath, 'utf-8').split('\n');
|
|
281
309
|
// 第一遍:扫全量行(不限 sinceMs)收集会话元信息
|
|
282
310
|
let chatType = 'private';
|
|
@@ -312,7 +340,7 @@ function buildThreadSnapshots(historyJsonlPath, sinceMs, threadsDir) {
|
|
|
312
340
|
try {
|
|
313
341
|
const entry = JSON.parse(line);
|
|
314
342
|
const ts = typeof entry.ts === 'number' ? entry.ts : 0;
|
|
315
|
-
if (ts
|
|
343
|
+
if (ts <= sinceMs || ts > throughMs)
|
|
316
344
|
continue;
|
|
317
345
|
const content = typeof entry.content === 'string' ? entry.content.trim() : '';
|
|
318
346
|
if (!content)
|
|
@@ -399,8 +427,6 @@ export function serializeConsolidationContext(input) {
|
|
|
399
427
|
migrateLegacyConsolidationBatches();
|
|
400
428
|
const scopes = resolveScopeContexts(input);
|
|
401
429
|
const now = new Date();
|
|
402
|
-
// 会话内文件名用:去掉所有分隔符,无 T,14 字符(YYYYMMDDHHmmss)
|
|
403
|
-
const ts = now.toISOString().replace(/[-:T]/g, '').slice(0, 14);
|
|
404
430
|
const forgetAfterDays = input.forgetAfterDays ?? DEFAULT_FORGET_AFTER_DAYS;
|
|
405
431
|
for (const ctx of scopes) {
|
|
406
432
|
fillCandidates(ctx, input.mode, forgetAfterDays);
|
|
@@ -410,26 +436,39 @@ export function serializeConsolidationContext(input) {
|
|
|
410
436
|
const selfAid = input.taskCtx.selfAid ?? 'unknown';
|
|
411
437
|
// 目录名:YYYYMMDDTHHmmss-<selfAid>-<mode>
|
|
412
438
|
const prettyTs = now.toISOString().replace(/[-:]/g, '').slice(0, 15);
|
|
413
|
-
|
|
439
|
+
fs.mkdirSync(batchRoot, { recursive: true });
|
|
440
|
+
const batchDir = fs.mkdtempSync(path.join(batchRoot, `${prettyTs}-${selfAid}-${input.mode}-`));
|
|
414
441
|
fs.mkdirSync(batchDir, { recursive: true });
|
|
442
|
+
// 反馈文件的父目录先建好:整理会话只被授权写这一个文件,无权建目录,
|
|
443
|
+
// 而各 runner 的补丁器 / 文件写入工具在父目录不存在时会失败。
|
|
444
|
+
fs.mkdirSync(path.dirname(feedbackFilePath(batchDir)), { recursive: true });
|
|
415
445
|
// ── 话题快照(notes / compress / session-new 模式,有 peerId 时生成)───────
|
|
416
446
|
let historyJsonlPath;
|
|
417
447
|
let threadFiles;
|
|
418
448
|
let chatDir;
|
|
419
|
-
|
|
449
|
+
// C2: generate thread snapshots for all modes that operate on relation-level memories
|
|
450
|
+
const needsThreadSnapshots = (input.mode === 'notes'
|
|
451
|
+
|| input.mode === 'generalize'
|
|
452
|
+
|| input.mode === 'promote'
|
|
453
|
+
|| input.mode === 'profile'
|
|
454
|
+
|| (input.mode === 'forget' && input.scopeOverride === 'relation')
|
|
455
|
+
|| input.triggeredBy === 'compress'
|
|
456
|
+
|| input.triggeredBy === 'session-new');
|
|
457
|
+
if (needsThreadSnapshots
|
|
420
458
|
&& input.taskCtx.channel
|
|
421
459
|
&& input.taskCtx.peerId
|
|
422
460
|
&& input.taskCtx.selfAid) {
|
|
423
461
|
try {
|
|
424
462
|
const sessionsDir = resolvePaths().sessionsDir;
|
|
425
|
-
|
|
463
|
+
const peerId = input.taskCtx.chatType === 'group' ? input.taskCtx.channelId || input.taskCtx.peerId : input.taskCtx.peerId;
|
|
464
|
+
chatDir = chatDirPath(sessionsDir, input.taskCtx.channel, peerId, input.taskCtx.selfAid, input.taskCtx.channelKey);
|
|
426
465
|
const rawJsonlPath = path.join(chatDir, 'messages.jsonl');
|
|
427
466
|
if (fs.existsSync(rawJsonlPath)) {
|
|
428
467
|
historyJsonlPath = rawJsonlPath;
|
|
429
|
-
const sinceMs = readCheckpoint(chatDir);
|
|
468
|
+
const sinceMs = readCheckpoint(chatDir, input.mode, input.scopeOverride);
|
|
430
469
|
const threadsDir = path.join(batchDir, 'threads');
|
|
431
470
|
try {
|
|
432
|
-
const files = buildThreadSnapshots(rawJsonlPath, sinceMs, threadsDir);
|
|
471
|
+
const files = buildThreadSnapshots(rawJsonlPath, sinceMs, threadsDir, now.getTime());
|
|
433
472
|
if (files.length > 0)
|
|
434
473
|
threadFiles = files;
|
|
435
474
|
}
|
|
@@ -480,21 +519,36 @@ export function serializeConsolidationContext(input) {
|
|
|
480
519
|
lines.push('', '---', '');
|
|
481
520
|
}
|
|
482
521
|
lines.push('请按照本次会话注入的模式手册完成整理。');
|
|
522
|
+
lines.push('');
|
|
523
|
+
lines.push('整理结束后,用文件写入工具(Write / Edit)把本次整理的整体反馈写入以下**反馈文件路径**:');
|
|
524
|
+
lines.push('');
|
|
525
|
+
lines.push(`\`${feedbackFilePath(batchDir)}\``);
|
|
526
|
+
lines.push('');
|
|
527
|
+
lines.push('这是本次会话唯一可以写的文件(文件已建好,直接写即可);写别的路径会被拒绝。');
|
|
528
|
+
lines.push('未写入则收尾时回退到默认统计模板(模式、触发方式、耗时、新建/更新/归档条数等)。');
|
|
483
529
|
const text = lines.join('\n');
|
|
484
|
-
// ──
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
fs.mkdirSync(tmpDir, { recursive: true });
|
|
489
|
-
const filePath = path.join(tmpDir, `memory-consolidation-${ts}.md`);
|
|
490
|
-
fs.writeFileSync(filePath, text, 'utf-8');
|
|
491
|
-
// ── 写批次目录(长期留存)────────────────────────────────────────────────
|
|
530
|
+
// ── 写批次目录(任务书唯一落点)────────────────────────────────────────────
|
|
531
|
+
// 不再写会话运行目录:任务书落在 $EVOLCORE_HOME/tmp 或 %TEMP%/ec-session-<hash>/
|
|
532
|
+
// 会同时踩两个坑——落点随触发路径而变,且会话运行时目录的读取范围不由任务书
|
|
533
|
+
// 所在的会话决定(见 docs/memory/session-profile-design.md §5.1)。
|
|
492
534
|
const contextFilePath = path.join(batchDir, 'context.md');
|
|
493
535
|
try {
|
|
494
536
|
fs.writeFileSync(contextFilePath, text, 'utf-8');
|
|
495
537
|
}
|
|
496
538
|
catch { /* 批次任务书写入失败不影响整理 */ }
|
|
497
|
-
|
|
539
|
+
// 写入初始 batch.md 元数据
|
|
540
|
+
writeBatchMeta(batchDir, {
|
|
541
|
+
selfAid: input.taskCtx.selfAid ?? 'unknown',
|
|
542
|
+
...(input.taskCtx.peerKey ? { peerKey: input.taskCtx.peerKey } : {}),
|
|
543
|
+
...(input.ownerAid ? { ownerAid: input.ownerAid } : {}),
|
|
544
|
+
...(input.taskCtx.baseagent ? { baseagent: input.taskCtx.baseagent } : {}),
|
|
545
|
+
mode: input.mode,
|
|
546
|
+
triggeredBy: input.triggeredBy,
|
|
547
|
+
startedAt: now.toISOString(),
|
|
548
|
+
status: 'running',
|
|
549
|
+
});
|
|
550
|
+
return { filePath: contextFilePath, batchDir, contextFilePath, scopes, historyJsonlPath, threadFiles, chatDir,
|
|
551
|
+
...(threadFiles?.length ? { snapshotThroughTs: now.getTime() } : {}) };
|
|
498
552
|
}
|
|
499
553
|
/** 会话结束后回填本次产出,追加到任务书末尾。 */
|
|
500
554
|
export function recordBatchOutcome(contextFilePath, outcome) {
|
|
@@ -38,7 +38,7 @@ export function summarizeOpsRecords(batchDir) {
|
|
|
38
38
|
try {
|
|
39
39
|
for (const line of fs.readFileSync(filePath, 'utf-8').split('\n').filter(Boolean)) {
|
|
40
40
|
const entry = JSON.parse(line);
|
|
41
|
-
if (entry.op === 'summary' || entry.op === 'session-start' || entry.op === 'session-end'
|
|
41
|
+
if (entry.op === 'summary' || entry.op === 'session-start' || entry.op === 'session-end')
|
|
42
42
|
continue;
|
|
43
43
|
if (!entry.ok) {
|
|
44
44
|
summary.errors++;
|
|
@@ -56,25 +56,23 @@ export function summarizeOpsRecords(batchDir) {
|
|
|
56
56
|
return summary;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
59
|
+
* 整理会话的反馈文件路径。任务书给出的路径、系统会话模块声明的唯一可写文件、
|
|
60
|
+
* 收尾读取与清理都以此为准,不要在别处重新拼接。
|
|
61
|
+
*/
|
|
62
|
+
export function feedbackFilePath(batchDir) {
|
|
63
|
+
return path.join(batchDir, 'scratch', 'feedback.txt');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 读整理会话写入的反馈文本:<batchDir>/scratch/feedback.txt。
|
|
67
|
+
* 文件不存在或内容为空时返回 undefined,收尾回退默认统计模板。
|
|
61
68
|
*/
|
|
62
69
|
export function readFeedbackText(batchDir) {
|
|
63
|
-
const filePath = path.join(batchDir, 'ops.jsonl');
|
|
64
|
-
if (!fs.existsSync(filePath))
|
|
65
|
-
return undefined;
|
|
66
70
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (entry.op === 'feedback-set') {
|
|
71
|
-
const text = entry.text;
|
|
72
|
-
if (typeof text === 'string' && text.trim())
|
|
73
|
-
return text;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
71
|
+
const text = fs.readFileSync(feedbackFilePath(batchDir), 'utf-8').trim();
|
|
72
|
+
if (text)
|
|
73
|
+
return text;
|
|
76
74
|
}
|
|
77
|
-
catch { /*
|
|
75
|
+
catch { /* 未写反馈属正常情况 */ }
|
|
78
76
|
return undefined;
|
|
79
77
|
}
|
|
80
78
|
/**
|
|
@@ -122,3 +120,38 @@ export function readRollbackRecords(batchDir) {
|
|
|
122
120
|
return [];
|
|
123
121
|
}
|
|
124
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* 统计 batchDir/threads/ 下所有快照文件里的消息条数。
|
|
125
|
+
* 每个 .md 文件里以 "L" 开头(后跟数字)的行就是一条消息。
|
|
126
|
+
* 文件不存在或为空时返回 0。
|
|
127
|
+
*/
|
|
128
|
+
export function countInputMessages(batchDir) {
|
|
129
|
+
const threadsDir = path.join(batchDir, 'threads');
|
|
130
|
+
if (!fs.existsSync(threadsDir))
|
|
131
|
+
return 0;
|
|
132
|
+
let total = 0;
|
|
133
|
+
try {
|
|
134
|
+
for (const f of fs.readdirSync(threadsDir)) {
|
|
135
|
+
if (!f.endsWith('.md'))
|
|
136
|
+
continue;
|
|
137
|
+
const content = fs.readFileSync(path.join(threadsDir, f), 'utf-8');
|
|
138
|
+
for (const line of content.split('\n')) {
|
|
139
|
+
if (/^L\d+\s/.test(line))
|
|
140
|
+
total++;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch { /* ignore */ }
|
|
145
|
+
return total;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 读取 batchDir/context.md 的字节数。文件不存在返回 0。
|
|
149
|
+
*/
|
|
150
|
+
export function readContextBytes(batchDir) {
|
|
151
|
+
try {
|
|
152
|
+
return fs.statSync(path.join(batchDir, 'context.md')).size;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 整理请求入队时的提示文案。CLI(ec memory consolidate)和 /memory consolidate 共用。
|
|
3
|
+
* 不依赖其他模块,CLI 侧引入不会拖进 daemon 代码。
|
|
4
|
+
*/
|
|
5
|
+
/** 入队原因:本 agent 已有整理会话在跑,或全局并发已满 */
|
|
6
|
+
export function queueReason(q) {
|
|
7
|
+
if (q.agentBusy)
|
|
8
|
+
return '当前 agent 已有整理会话在运行';
|
|
9
|
+
if (q.activeCount >= q.maxConcurrent)
|
|
10
|
+
return `全局并发已满(${q.activeCount}/${q.maxConcurrent})`;
|
|
11
|
+
return '前面还有待处理的整理请求';
|
|
12
|
+
}
|
|
13
|
+
/** 多行明细,每行一个字段 */
|
|
14
|
+
export function formatQueueDetails(q) {
|
|
15
|
+
return [
|
|
16
|
+
`原因: ${queueReason(q)}`,
|
|
17
|
+
`本 agent 排队: 第 ${q.position} 位 / 共 ${q.agentQueueLength} 个`,
|
|
18
|
+
`全局运行中: ${q.activeCount}/${q.maxConcurrent}`,
|
|
19
|
+
`全局排队: ${q.totalQueued} 个`,
|
|
20
|
+
];
|
|
21
|
+
}
|