evolcore 0.0.10 → 0.0.12

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.
Files changed (131) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +3 -3
  3. package/bin/codex-managed-hook.mjs +80 -0
  4. package/dist/agents/baseagent.js +4 -0
  5. package/dist/agents/claude-runner.js +158 -44
  6. package/dist/agents/codex-app-server-client.js +153 -23
  7. package/dist/agents/codex-runner.js +331 -43
  8. package/dist/agents/ecagent-runner.js +53 -6
  9. package/dist/agents/gemini-runner.js +1 -0
  10. package/dist/agents/request-identity.js +55 -0
  11. package/dist/aun/aid/client.js +11 -21
  12. package/dist/aun/aid/managed-operation.js +107 -0
  13. package/dist/aun/msg/group.js +81 -12
  14. package/dist/aun/msg/managed-operation.js +804 -0
  15. package/dist/aun/msg/mention-schema.js +20 -0
  16. package/dist/aun/msg/p2p.js +7 -0
  17. package/dist/aun/outbox.js +28 -31
  18. package/dist/channels/aun.js +418 -235
  19. package/dist/channels/daemon.js +13 -0
  20. package/dist/cli/agent-command.js +72 -17
  21. package/dist/cli/agent.js +249 -22
  22. package/dist/cli/aun-commands.js +270 -69
  23. package/dist/cli/bench.js +12 -3
  24. package/dist/cli/daemon-commands.js +52 -33
  25. package/dist/cli/fs-command.js +60 -0
  26. package/dist/cli/handoff-command.js +3 -0
  27. package/dist/cli/index.js +106 -63
  28. package/dist/cli/init-cancel.js +208 -0
  29. package/dist/cli/init-channel.js +343 -195
  30. package/dist/cli/init.js +21 -9
  31. package/dist/cli/managed-command-guard.js +41 -0
  32. package/dist/cli/model.js +11 -4
  33. package/dist/cli/queue-command.js +11 -1
  34. package/dist/cli/response.js +71 -0
  35. package/dist/cli/restart-monitor.js +4 -18
  36. package/dist/cli/trigger-command.js +4 -0
  37. package/dist/config/builtin-roles.js +5 -0
  38. package/dist/config/contact-book-store.js +11 -3
  39. package/dist/config/contact-request-service.js +161 -15
  40. package/dist/config/gateway-config.js +26 -10
  41. package/dist/config/mention-mode.js +8 -24
  42. package/dist/core/agent-reload-coordinator.js +53 -0
  43. package/dist/core/auth/agent-delegation.js +0 -1
  44. package/dist/core/auth/operation-authorizer.js +62 -154
  45. package/dist/core/auth/operation-catalog.js +264 -22
  46. package/dist/core/bootstrap-messages.js +68 -0
  47. package/dist/core/bootstrap-service.js +144 -10
  48. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  49. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  50. package/dist/core/capability/skill-discovery.js +55 -0
  51. package/dist/core/channel-loader.js +24 -7
  52. package/dist/core/command/agent-control.js +14 -11
  53. package/dist/core/command/cli-intent-parser.js +9 -0
  54. package/dist/core/command/command-handler.js +467 -6
  55. package/dist/core/command/connect-menu.js +15 -0
  56. package/dist/core/command/group-menu.js +4 -4
  57. package/dist/core/command/menu-catalog.js +366 -0
  58. package/dist/core/command/menu-handler.js +213 -110
  59. package/dist/core/command/menu-protocol.js +71 -0
  60. package/dist/core/command/slash-gate.js +5 -2
  61. package/dist/core/command/slash-handler.js +45 -25
  62. package/dist/core/daemon-file-cache.js +2 -1
  63. package/dist/core/data-migration.js +9 -2
  64. package/dist/core/evolagent-registry.js +125 -35
  65. package/dist/core/evolagent.js +12 -5
  66. package/dist/core/handoff/dispatcher.js +5 -2
  67. package/dist/core/handoff/runtime.js +145 -21
  68. package/dist/core/handoff/store.js +24 -0
  69. package/dist/core/handoff/types.js +1 -0
  70. package/dist/core/inference/text-inference.js +38 -4
  71. package/dist/core/message/logical-queue-bridge.js +1 -0
  72. package/dist/core/message/mention-schema.js +126 -0
  73. package/dist/core/message/message-bridge.js +237 -79
  74. package/dist/core/message/message-log.js +23 -0
  75. package/dist/core/message/message-queue.js +20 -4
  76. package/dist/core/message/response-engine.js +54 -36
  77. package/dist/core/model/model-catalog.js +143 -24
  78. package/dist/core/model/model-diagnostics.js +28 -10
  79. package/dist/core/permission/ec-command-parser.js +156 -10
  80. package/dist/core/permission/index.js +1 -0
  81. package/dist/core/permission/readonly-shell-query.js +532 -0
  82. package/dist/core/permission/sandbox-runtime.js +22 -1
  83. package/dist/core/permission/shell-environment.js +46 -0
  84. package/dist/core/permission/tool-policy.js +292 -111
  85. package/dist/core/protected-paths.js +17 -9
  86. package/dist/core/runner-reload-transaction.js +57 -0
  87. package/dist/core/session/session-manager.js +21 -2
  88. package/dist/eck/manifest-engine.js +39 -13
  89. package/dist/index.js +644 -180
  90. package/dist/ipc.js +246 -19
  91. package/dist/response-system/coordinator.js +6 -4
  92. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  93. package/dist/response-system/modes/single-session/index.js +14 -1
  94. package/dist/response-system/selector.js +6 -5
  95. package/dist/trigger/anomaly-store.js +4 -0
  96. package/dist/trigger/script-executor.js +1 -0
  97. package/dist/utils/aid-bind.js +3 -8
  98. package/dist/utils/codex-app-server-registry.js +90 -0
  99. package/dist/utils/codex-cli.js +5 -1
  100. package/dist/utils/cross-platform.js +15 -0
  101. package/dist/utils/log-writer.js +6 -10
  102. package/dist/utils/logger.js +5 -5
  103. package/dist/utils/npm-ops.js +5 -12
  104. package/dist/utils/tool-summary.js +11 -0
  105. package/kits/docs/channels/aun.md +1 -1
  106. package/kits/docs/context-assembly.md +2 -2
  107. package/kits/docs/evolcore/agent.md +11 -6
  108. package/kits/docs/evolcore/aid.md +14 -0
  109. package/kits/docs/evolcore/msg.md +13 -0
  110. package/kits/docs/prompt-loading-architecture.md +1 -2
  111. package/kits/docs/venues/group.md +1 -1
  112. package/kits/eck_manifest.json +0 -12
  113. package/kits/rules/01-overview.md +9 -0
  114. package/kits/rules/04-relation.md +1 -1
  115. package/kits/rules/05-venue.md +2 -2
  116. package/kits/schemas/agent-config.schema.3.json +1 -1
  117. package/kits/schemas/agent-config.schema.4.json +1 -1
  118. package/kits/schemas/relation-config.schema.2.json +1 -1
  119. package/kits/schemas/role-config.schema.1.json +1 -1
  120. package/kits/schemas/single-session.schema.1.json +3 -3
  121. package/kits/schemas/single-session.schema.2.json +3 -3
  122. package/kits/templates/roles/admin.json +27 -0
  123. package/kits/templates/roles/member.json +44 -0
  124. package/kits/templates/roles/visitor.json +40 -2
  125. package/kits/templates/system-fragments/bootstrap.md +12 -6
  126. package/kits/templates/system-fragments/channel.md +6 -0
  127. package/kits/templates/system-fragments/session.md +2 -0
  128. package/package.json +3 -2
  129. package/skills/eclink/SKILL.md +15 -3
  130. package/skills/eclink/agents/openai.yaml +3 -3
  131. package/dist/core/command/evol-menu-version-gate.js +0 -39
@@ -0,0 +1,57 @@
1
+ export async function disposeAgentInstances(instances, onError) {
2
+ await Promise.allSettled(instances.map(async (instance) => {
3
+ try {
4
+ await instance.agent.dispose?.();
5
+ }
6
+ catch (error) {
7
+ onError?.(instance, error);
8
+ }
9
+ }));
10
+ }
11
+ export function createRunnerReloadTransaction(input) {
12
+ const prefix = `${input.aid}::`;
13
+ const previous = [...input.agentMap.entries()]
14
+ .filter(([key]) => key.startsWith(prefix))
15
+ .map(([key, agent]) => {
16
+ const split = key.lastIndexOf('::');
17
+ return {
18
+ evolagentName: key.slice(0, split),
19
+ baseagent: key.slice(split + 2),
20
+ agent,
21
+ };
22
+ });
23
+ let committed = false;
24
+ let stagedDisposed = false;
25
+ const disposeStaged = async () => {
26
+ if (stagedDisposed)
27
+ return;
28
+ stagedDisposed = true;
29
+ await disposeAgentInstances(input.staged, input.onDisposeError);
30
+ };
31
+ return {
32
+ commit() {
33
+ if (committed)
34
+ return;
35
+ for (const instance of previous)
36
+ input.agentMap.delete(`${instance.evolagentName}::${instance.baseagent}`);
37
+ for (const instance of input.staged)
38
+ input.agentMap.set(`${instance.evolagentName}::${instance.baseagent}`, instance.agent);
39
+ committed = true;
40
+ },
41
+ async rollback() {
42
+ if (committed) {
43
+ for (const instance of input.staged)
44
+ input.agentMap.delete(`${instance.evolagentName}::${instance.baseagent}`);
45
+ for (const instance of previous)
46
+ input.agentMap.set(`${instance.evolagentName}::${instance.baseagent}`, instance.agent);
47
+ committed = false;
48
+ }
49
+ await disposeStaged();
50
+ },
51
+ async finalize() {
52
+ if (!committed)
53
+ return;
54
+ await disposeAgentInstances(previous, input.onDisposeError);
55
+ },
56
+ };
57
+ }
@@ -11,7 +11,7 @@ import fs from 'fs';
11
11
  import os from 'os';
12
12
  function newSessionStableMetadata(chatType, ...sources) {
13
13
  const keys = chatType === 'group'
14
- ? ['channelKey', 'groupId', 'groupName', 'dispatchMode']
14
+ ? ['channelKey', 'groupId', 'groupName', 'mentionMode']
15
15
  : ['channelKey', 'peerId', 'peerName', 'peerType'];
16
16
  const metadata = {};
17
17
  for (const source of sources) {
@@ -1135,6 +1135,10 @@ export class SessionManager {
1135
1135
  if (!baseagent) {
1136
1136
  throw new Error(`[SessionManager] createNewSession: baseagent is empty for channel=${channel} channelId=${channelId}`);
1137
1137
  }
1138
+ const metadata = newSessionStableMetadata(inheritedChatType, activeMetadata, identityMetadata);
1139
+ if (identityMetadata?.sessionBoundaryOperationId) {
1140
+ metadata.sessionBoundaryOperationId = identityMetadata.sessionBoundaryOperationId;
1141
+ }
1138
1142
  const session = {
1139
1143
  id: generateSessionId(),
1140
1144
  channel,
@@ -1146,7 +1150,7 @@ export class SessionManager {
1146
1150
  baseagent,
1147
1151
  sessionKey: formatSessionKey(channelType, channelId, DEFAULT_THREAD_ID),
1148
1152
  chatType: inheritedChatType,
1149
- metadata: newSessionStableMetadata(inheritedChatType, activeMetadata, identityMetadata),
1153
+ metadata,
1150
1154
  name: name || '默认会话',
1151
1155
  createdAt: Date.now(),
1152
1156
  updatedAt: Date.now(),
@@ -1163,6 +1167,21 @@ export class SessionManager {
1163
1167
  });
1164
1168
  return session;
1165
1169
  }
1170
+ /**
1171
+ * Create and activate one fresh main session for a durable system operation.
1172
+ * Replaying the same operation returns the already-created session.
1173
+ */
1174
+ async ensureNewMainSessionForOperation(opts) {
1175
+ const active = this.getActiveSessionSync(opts.channel, opts.channelId);
1176
+ if (active?.metadata?.sessionBoundaryOperationId === opts.operationId) {
1177
+ return { session: active, created: false };
1178
+ }
1179
+ const session = await this.createNewSession(opts.channel, opts.channelId, opts.projectPath, undefined, opts.baseagent, {
1180
+ ...(opts.identityMetadata ?? {}),
1181
+ sessionBoundaryOperationId: opts.operationId,
1182
+ });
1183
+ return { session, created: true };
1184
+ }
1166
1185
  async createForkedSession(sourceSession, forkedAgentSessionId, name) {
1167
1186
  const channelType = sourceSession.channelType || sourceSession.channel;
1168
1187
  const threadId = sourceSession.threadId || '';
@@ -55,6 +55,10 @@ function loadAndMergeManifest(filename) {
55
55
  for (const s of base.sections)
56
56
  merged.set(s.id, { ...s });
57
57
  for (const s of override.sections) {
58
+ if (s.id === 'relation-group-profile' && merged.has('peer-profile')) {
59
+ logger.warn('[ManifestEngine] Ignoring deprecated patch section "relation-group-profile"; use "peer-profile" instead');
60
+ continue;
61
+ }
58
62
  const existing = merged.get(s.id);
59
63
  merged.set(s.id, existing ? { ...existing, ...s } : s);
60
64
  }
@@ -320,15 +324,35 @@ function resolvePath(rawPath, vars) {
320
324
  const r = resolvePathWithDiag(rawPath, vars);
321
325
  return r.status === 'ok' ? r.resolved : null;
322
326
  }
327
+ function isWithinDirectory(filePath, directory) {
328
+ const relative = path.relative(path.resolve(directory), path.resolve(filePath));
329
+ return relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`));
330
+ }
331
+ /**
332
+ * 随包发布的 kits 内容只在 reload/重启后刷新;personal/relations 及用户自定义
333
+ * manifest 路径属于运行时数据,必须用 mtime 检查,否则同一 daemon 内会长期陈旧。
334
+ */
335
+ function sectionCacheOptions(resolvedPath, vars) {
336
+ if (isWithinDirectory(resolvedPath, kitsDir())) {
337
+ return { policy: 'on-reload', group: 'kits' };
338
+ }
339
+ const personalDir = typeof vars.PERSONAL_DIR === 'string' ? vars.PERSONAL_DIR : null;
340
+ const selfAid = typeof vars.selfAid === 'string' ? vars.selfAid : null;
341
+ if (personalDir && selfAid && isWithinDirectory(resolvedPath, personalDir)) {
342
+ return { policy: 'mtime', group: `agent-files:${selfAid}` };
343
+ }
344
+ return { policy: 'mtime', group: 'eck-runtime' };
345
+ }
323
346
  /** 加载 loop 的 child 子模板文件内容(路径解析 + fileCache)。找不到返回 null。 */
324
347
  export function loadChildTemplate(childFile, vars) {
325
348
  const resolved = resolvePath(childFile, vars);
326
349
  if (!resolved)
327
350
  return null;
328
- return fileCache.getText(resolved, { policy: 'on-reload', group: 'kits' });
351
+ return fileCache.getText(resolved, sectionCacheOptions(resolved, vars));
329
352
  }
330
353
  /**
331
- * 返回 [filePath, rawContent][];按 sessionId 缓存已读文件内容。
354
+ * 返回 [filePath, rawContent][]。kits 文件跨 session 缓存到 reload;运行时文件
355
+ * (personal/relations/用户自定义路径)每次按 mtime 检查。
332
356
  * 若传入 overflowOut 且目录段触发单目录限额(maxFiles/maxBytes),
333
357
  * 会把溢出信息写入 overflowOut.value(不传则不启用限额收集,行为同旧版但仍应用默认上限)。
334
358
  */
@@ -343,7 +367,7 @@ export function loadSectionFiles(section, vars, sessionCache, overflowOut) {
343
367
  return [];
344
368
  const maxFiles = section.maxFiles ?? DIR_MAX_FILES;
345
369
  const maxBytes = section.maxBytes ?? DIR_MAX_BYTES;
346
- const { files, overflow } = readDirectoryFiles(resolved, section.pattern, maxFiles, maxBytes);
370
+ const { files, overflow } = readDirectoryFiles(resolved, section.pattern, maxFiles, maxBytes, vars);
347
371
  if (overflow && overflowOut)
348
372
  overflowOut.value = overflow;
349
373
  return files.map(([name, content]) => [path.join(resolved, name), content]);
@@ -351,31 +375,33 @@ export function loadSectionFiles(section, vars, sessionCache, overflowOut) {
351
375
  return [];
352
376
  }
353
377
  function loadFileSection(filePath, vars, sessionCache) {
354
- void sessionCache; // 内容跨 session 共享,改走全局 fileCache(on-reload)
378
+ void sessionCache; // 内容跨 session 共享,统一走全局 fileCache
355
379
  const resolved = resolvePath(filePath, vars);
356
380
  if (!resolved)
357
381
  return null;
358
- // 内容跨 session 共享:用全局 fileCache(on-reload,reload/重启时失效),
359
- // 不再按 session 重复缓存同一文件内容。
360
- const content = fileCache.getText(resolved, { policy: 'on-reload', group: 'kits' });
382
+ const content = fileCache.getText(resolved, sectionCacheOptions(resolved, vars));
361
383
  return content === null ? null : [resolved, content];
362
384
  }
363
385
  /**
364
386
  * 读取目录下匹配文件,受单目录限额(maxFiles/maxBytes)约束。
365
387
  * 返回已加载文件 + 溢出信息(超限时)。按 fileCache 缓存目录列表与文件内容。
366
388
  */
367
- function readDirectoryFiles(dirPath, pattern, maxFiles, maxBytes) {
389
+ function readDirectoryFiles(dirPath, pattern, maxFiles, maxBytes, vars) {
368
390
  const glob = pattern || '*.md';
369
- // 目录列表 + 各文件内容均走 fileCache(on-reload)。目录列表以 "<dir>|<glob>"
370
- // 为键缓存文件名数组;各文件内容走 fileCache.getText 共享。
371
- const names = fileCache.get(`${dirPath} ${glob}`, () => {
391
+ const cacheOptions = sectionCacheOptions(dirPath, vars);
392
+ const readNames = () => {
372
393
  try {
373
394
  return fs.readdirSync(dirPath).filter(f => matchGlob(f, glob)).sort();
374
395
  }
375
396
  catch {
376
397
  return [];
377
398
  }
378
- }, { policy: 'on-reload', group: 'kits' });
399
+ };
400
+ // synthetic cache key 无法用文件 mtime 门控。kits 目录结构只在 reload 后刷新;
401
+ // 运行时目录直接重扫,确保新增/删除文件在同一 session 内可见。
402
+ const names = cacheOptions.policy === 'on-reload'
403
+ ? fileCache.get(`${dirPath} ${glob}`, readNames, cacheOptions)
404
+ : readNames();
379
405
  const out = [];
380
406
  let usedBytes = 0;
381
407
  let overflow;
@@ -387,7 +413,7 @@ function readDirectoryFiles(dirPath, pattern, maxFiles, maxBytes) {
387
413
  break;
388
414
  }
389
415
  const fp = path.join(dirPath, f);
390
- const content = fileCache.getText(fp, { policy: 'on-reload', group: 'kits' });
416
+ const content = fileCache.getText(fp, sectionCacheOptions(fp, vars));
391
417
  if (content === null)
392
418
  continue;
393
419
  // 字节限额(至少加载一个文件,避免单个超大文件导致空目录)