evolcore 0.0.20 → 0.0.22

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 (147) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +58 -9
  3. package/bin/codex-managed-hook.mjs +3 -0
  4. package/bin/install-codex-managed-hooks.mjs +3 -1
  5. package/dist/agents/baseagent.js +10 -6
  6. package/dist/agents/claude-runner.js +393 -108
  7. package/dist/agents/codex-app-server-client.js +41 -7
  8. package/dist/agents/codex-runner.js +1292 -220
  9. package/dist/agents/ecagent-runner.js +171 -61
  10. package/dist/agents/gemini-runner.js +130 -30
  11. package/dist/agents/request-identity.js +25 -0
  12. package/dist/agents/runner-types.js +19 -0
  13. package/dist/aun/aid/agentmd.js +59 -2
  14. package/dist/aun/aid/identity.js +4 -1
  15. package/dist/aun/aid/index.js +1 -1
  16. package/dist/aun/msg/group.js +72 -6
  17. package/dist/aun/msg/history.js +213 -36
  18. package/dist/aun/msg/managed-operation.js +58 -9
  19. package/dist/aun/msg/p2p.js +5 -0
  20. package/dist/aun/outbox.js +189 -80
  21. package/dist/aun/service-proxy.js +43 -25
  22. package/dist/channels/aun.js +618 -123
  23. package/dist/channels/daemon.js +6 -1
  24. package/dist/cli/agent-command.js +4 -3
  25. package/dist/cli/agent.js +66 -56
  26. package/dist/cli/aun-commands.js +177 -42
  27. package/dist/cli/command-log.js +10 -11
  28. package/dist/cli/contact.js +1 -0
  29. package/dist/cli/daemon-commands.js +98 -123
  30. package/dist/cli/init.js +27 -15
  31. package/dist/cli/task-context.js +50 -0
  32. package/dist/cli/trigger-command.js +14 -5
  33. package/dist/cli/watch-logs.js +10 -3
  34. package/dist/config/builtin-roles.js +1 -0
  35. package/dist/config/config-field-policy.js +19 -5
  36. package/dist/config/config-manager.js +167 -22
  37. package/dist/config/contact-book-store.js +25 -3
  38. package/dist/config/contact-operation-service.js +32 -1
  39. package/dist/config/contact-request-service.js +44 -0
  40. package/dist/config/daemon-services.js +186 -0
  41. package/dist/config/gateway-config.js +20 -9
  42. package/dist/config/role-service.js +54 -3
  43. package/dist/config/schema-migration.js +550 -0
  44. package/dist/config-store.js +151 -9
  45. package/dist/core/agent-application-service.js +279 -0
  46. package/dist/core/audit/log-integrity.js +102 -0
  47. package/dist/core/auth/agent-delegation.js +43 -1
  48. package/dist/core/auth/auth-gateway.js +41 -4
  49. package/dist/core/auth/authorization-audit.js +216 -8
  50. package/dist/core/auth/operation-authorizer.js +41 -1
  51. package/dist/core/auth/operation-catalog.js +9 -1
  52. package/dist/core/bootstrap-messages.js +8 -0
  53. package/dist/core/bootstrap-service.js +99 -27
  54. package/dist/core/causation/aun-association.js +7 -4
  55. package/dist/core/command/agent-control.js +56 -16
  56. package/dist/core/command/command-handler.js +311 -44
  57. package/dist/core/command/connect-menu.js +3 -4
  58. package/dist/core/command/group-menu.js +5 -7
  59. package/dist/core/command/menu-handler.js +288 -80
  60. package/dist/core/command/menu-protocol.js +1 -1
  61. package/dist/core/command/role-menu.js +21 -11
  62. package/dist/core/command/slash-gate.js +85 -18
  63. package/dist/core/command/slash-handler.js +377 -36
  64. package/dist/core/data-migration.js +11 -1
  65. package/dist/core/event-catalog.js +37 -0
  66. package/dist/core/evolagent.js +4 -0
  67. package/dist/core/handoff/dispatcher.js +4 -0
  68. package/dist/core/handoff/runtime.js +33 -3
  69. package/dist/core/handoff/store.js +32 -9
  70. package/dist/core/inference/text-inference.js +7 -15
  71. package/dist/core/message/im-renderer.js +90 -87
  72. package/dist/core/message/{inbound-admission.js → message-admission.js} +51 -1
  73. package/dist/core/message/message-bridge.js +184 -12
  74. package/dist/core/message/message-log.js +47 -7
  75. package/dist/core/message/message-queue.js +227 -16
  76. package/dist/core/message/message-utils.js +12 -5
  77. package/dist/core/message/response-engine.js +658 -109
  78. package/dist/core/message/send-receipt.js +1 -0
  79. package/dist/core/message/stream-debouncer.js +9 -2
  80. package/dist/core/model/model-catalog.js +23 -15
  81. package/dist/core/model/model-diagnostics.js +28 -10
  82. package/dist/core/permission/approval-gateway.js +180 -6
  83. package/dist/core/permission/ec-command-parser.js +627 -69
  84. package/dist/core/permission/mode.js +18 -3
  85. package/dist/core/{protected-paths.js → permission/protected-paths.js} +27 -14
  86. package/dist/core/permission/readonly-shell-query.js +263 -9
  87. package/dist/core/permission/sandbox-runtime.js +159 -1
  88. package/dist/core/permission/tool-error-code.js +12 -0
  89. package/dist/core/permission/tool-policy.js +618 -23
  90. package/dist/core/session/session-fs-store.js +154 -5
  91. package/dist/core/session/session-manager.js +329 -30
  92. package/dist/core/session/session-renew.js +37 -13
  93. package/dist/core/session/session-turn-coordinator.js +16 -5
  94. package/dist/eck/kit-renderer.js +1 -1
  95. package/dist/index.js +316 -50
  96. package/dist/ipc.js +459 -29
  97. package/dist/paths.js +82 -7
  98. package/dist/response-system/context-builder.js +1 -7
  99. package/dist/response-system/engines/v1/proactive-flow.js +7 -2
  100. package/dist/stats/price-resolver.js +4 -0
  101. package/dist/trigger/anomaly-store.js +1 -0
  102. package/dist/trigger/feedback.js +70 -7
  103. package/dist/trigger/history.js +79 -4
  104. package/dist/trigger/legacy-session-history.js +2 -2
  105. package/dist/trigger/parser.js +13 -3
  106. package/dist/trigger/scheduler.js +20 -3
  107. package/dist/trigger/validation.js +6 -1
  108. package/dist/utils/atomic-write.js +27 -0
  109. package/dist/utils/ecweb-utils.js +16 -2
  110. package/dist/utils/error-utils.js +4 -1
  111. package/dist/utils/logger.js +30 -6
  112. package/dist/utils/process-tree-stats.js +24 -4
  113. package/dist/utils/process-tree-worker.js +31 -0
  114. package/dist/utils/project-path.js +1 -2
  115. package/dist/utils/tool-summary.js +59 -0
  116. package/dist/utils/windows-shell-trust.js +201 -0
  117. package/kits/docs/INDEX.md +1 -1
  118. package/kits/docs/evolcore/INDEX.md +3 -3
  119. package/kits/docs/evolcore/agent-create.md +146 -0
  120. package/kits/docs/evolcore/agent.md +6 -0
  121. package/kits/docs/evolcore/contact.md +7 -1
  122. package/kits/docs/evolcore/group-collaboration.md +251 -0
  123. package/kits/docs/evolcore/group-rules.md +1 -19
  124. package/kits/docs/evolcore/group.md +3 -1
  125. package/kits/docs/evolcore/msg.md +16 -0
  126. package/kits/docs/evolcore/trigger.md +6 -3
  127. package/kits/docs/prompt-loading-architecture.md +6 -0
  128. package/kits/eck_message_manifest.json +6 -6
  129. package/kits/schemas/_meta.json +7 -4
  130. package/kits/schemas/agent-config.schema.11.json +13 -0
  131. package/kits/schemas/agent-config.schema.12.json +427 -0
  132. package/kits/schemas/daemon.schema.5.json +0 -1
  133. package/kits/schemas/daemon.schema.6.json +131 -0
  134. package/kits/schemas/defaults.schema.5.json +15 -3
  135. package/kits/schemas/migrations/README.md +3 -1
  136. package/kits/schemas/relation-config.schema.8.json +13 -0
  137. package/kits/schemas/role-config.schema.1.json +1 -2
  138. package/kits/schemas/single-session.schema.3.json +32 -0
  139. package/kits/templates/message-fragments/item.md +1 -1
  140. package/kits/templates/roles/admin.json +1 -0
  141. package/kits/templates/roles/member.json +1 -0
  142. package/kits/templates/roles/visitor.json +1 -0
  143. package/kits/templates/system-fragments/bootstrap.md +2 -1
  144. package/kits/templates/system-fragments/commands.md +2 -2
  145. package/package.json +6 -3
  146. package/skills/eclink/SKILL.md +2 -0
  147. package/dist/config/aun-gateway-config.js +0 -2
@@ -5,7 +5,6 @@ import { isTransientProtocolMessage, messageLogPath } from '../message/message-l
5
5
  import { readAllJsonlLines } from './session-fs-store.js';
6
6
  import { ResponseModeRegistry } from '../../response-system/registry.js';
7
7
  import { registerBuiltinModes } from '../../response-system/modes/index.js';
8
- import { resolveEffectiveResponseModeConfig } from '../../response-system/config-resolver.js';
9
8
  import { normalizeBaseagent } from '../../agents/baseagent.js';
10
9
  const DEFAULT_AFTER_HOURS = 24;
11
10
  const DEFAULT_FALLBACK = 'continue';
@@ -14,6 +13,9 @@ const MAX_CONTEXT_CHARS = 16_000;
14
13
  const MAX_MESSAGE_CHARS = 2_000;
15
14
  const MODEL_TIMEOUT_MS = 10_000;
16
15
  const RECENT_DECISION_TTL_MS = 30_000;
16
+ const FRESH_EMPTY_SESSION_TTL_MS = 30_000;
17
+ const RENEWED_AT_METADATA_KEY = '__sessionRenewedAt';
18
+ const CREATED_AT_METADATA_KEY = '__sessionCreatedAt';
17
19
  const NEW_CONFIDENCE_THRESHOLD = 0.85;
18
20
  const AUXILIARY_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'max']);
19
21
  const EXPLICIT_NEW_RE = /^(?:新话题|换个话题|重新开始|新开会话|新会话)[::,,;;。!!\n]/;
@@ -92,7 +94,9 @@ export class SessionRenewService {
92
94
  const routeKey = this.routeKey(request);
93
95
  return await this.withLock(routeKey, async () => {
94
96
  const cached = this.recentDecisions.get(routeKey);
95
- if (cached && cached.candidateSessionId === request.session.id && cached.expiresAt > this.now()) {
97
+ if (cached
98
+ && cached.expiresAt > this.now()
99
+ && (cached.candidateSessionId === request.session.id || cached.selectedSessionId === request.session.id)) {
96
100
  const selected = cached.selectedSessionId === request.session.id
97
101
  ? request.session
98
102
  : await this.sessionManager.getSessionById(cached.selectedSessionId);
@@ -122,6 +126,18 @@ export class SessionRenewService {
122
126
  if (!last) {
123
127
  if (request.isNewSession)
124
128
  return { session: request.session, renewed: false };
129
+ // A renewed session is intentionally created before its first inbound
130
+ // message is appended. A concurrent message can therefore observe an
131
+ // empty, freshly-created session. Treat that state as already renewed;
132
+ // do not create a second logical session for the same route.
133
+ const metadata = request.session.metadata;
134
+ const renewedAt = Number(metadata?.[RENEWED_AT_METADATA_KEY] ?? metadata?.[CREATED_AT_METADATA_KEY]);
135
+ const sessionAgeMs = Number.isFinite(renewedAt)
136
+ ? Math.max(0, this.now() - renewedAt)
137
+ : Number.POSITIVE_INFINITY;
138
+ if (Number.isFinite(renewedAt) && renewedAt <= this.now() && sessionAgeMs <= FRESH_EMPTY_SESSION_TTL_MS) {
139
+ return { session: request.session, renewed: false, decision: 'continue', source: 'missing_history' };
140
+ }
125
141
  const idleMs = this.now() - request.session.updatedAt;
126
142
  return await this.finishDecision(routeKey, request, 'new', 'missing_history', idleMs, evaluationStartedAt);
127
143
  }
@@ -230,23 +246,31 @@ export class SessionRenewService {
230
246
  }, { cache: true, expand: true });
231
247
  }
232
248
  resolveAuxiliaryConfig(config, baseagent) {
233
- const resolved = resolveEffectiveResponseModeConfig(this.responseModeRegistry, config);
234
- const rawModel = resolved.modeConfig.auxiliaryModel;
235
249
  const canonicalBaseagent = normalizeBaseagent(baseagent).canonical;
236
- const selectedModel = typeof rawModel === 'string'
237
- ? rawModel
238
- : rawModel && typeof rawModel === 'object' && !Array.isArray(rawModel)
239
- ? rawModel[canonicalBaseagent]
240
- : undefined;
241
- const model = typeof selectedModel === 'string' && selectedModel.trim()
242
- ? selectedModel.trim()
250
+ const baseagentConfig = canonicalBaseagent !== 'unknown'
251
+ ? config.baseagents?.[canonicalBaseagent]
252
+ : undefined;
253
+ const rawBaseagentConfig = baseagentConfig && typeof baseagentConfig === 'object'
254
+ ? baseagentConfig
255
+ : undefined;
256
+ // Auxiliary inference is owned exclusively by the selected baseagent. Old
257
+ // response-mode bucket values must be migrated before they can take effect.
258
+ const configuredMode = typeof config.responseMode === 'string' && config.responseMode.trim()
259
+ ? config.responseMode.trim()
260
+ : undefined;
261
+ const responseMode = configuredMode && this.responseModeRegistry.has(configuredMode)
262
+ ? configuredMode
263
+ : this.responseModeRegistry.getPreferredId() ?? 'single-session';
264
+ const rawModel = rawBaseagentConfig?.auxiliaryModel;
265
+ const rawEffort = rawBaseagentConfig?.auxiliaryEffort;
266
+ const model = typeof rawModel === 'string' && rawModel.trim()
267
+ ? rawModel.trim()
243
268
  : undefined;
244
- const rawEffort = resolved.modeConfig.auxiliaryEffort;
245
269
  const effort = typeof rawEffort === 'string' && AUXILIARY_EFFORTS.has(rawEffort)
246
270
  ? rawEffort
247
271
  : undefined;
248
272
  return {
249
- responseMode: resolved.mode.id,
273
+ responseMode,
250
274
  model,
251
275
  effort,
252
276
  invalidEffort: rawEffort !== undefined && effort === undefined,
@@ -48,10 +48,14 @@ export class SessionTurnCoordinator {
48
48
  && state.lastTerminal.taskId === lease.taskId
49
49
  && state.lastTerminal.generation === lease.generation;
50
50
  }
51
- invalidate(sessionId, reason) {
51
+ invalidate(sessionId, reason, expected) {
52
52
  const state = this.states.get(sessionId);
53
53
  if (!state)
54
54
  return undefined;
55
+ if (expected?.taskId && state.active?.taskId !== expected.taskId)
56
+ return undefined;
57
+ if (expected?.generation !== undefined && state.active?.generation !== expected.generation)
58
+ return undefined;
55
59
  if (state.active?.status === 'interrupting' && state.active.cancelReason === reason) {
56
60
  return cloneTurnMetadata(state);
57
61
  }
@@ -208,9 +212,16 @@ export class SessionTurnCoordinator {
208
212
  return true;
209
213
  }
210
214
  async persist(session, state) {
211
- const metadata = { ...(session.metadata ?? {}), turnState: cloneTurnMetadata(state) };
212
- session.metadata = metadata;
213
- this.states.set(session.id, cloneTurnMetadata(state));
214
- await this.sessionManager.updateSession(session.id, { metadata });
215
+ const next = cloneTurnMetadata(state);
216
+ session.metadata = { ...(session.metadata ?? {}), turnState: next };
217
+ this.states.set(session.id, next);
218
+ if (typeof this.sessionManager.updateTurnState === 'function') {
219
+ await this.sessionManager.updateTurnState(session.id, next);
220
+ }
221
+ else {
222
+ // Compatibility for minimal test doubles and pre-patch adapters. Real
223
+ // SessionManager instances always expose updateTurnState.
224
+ await this.sessionManager.updateSession(session.id, { metadata: { turnState: next } });
225
+ }
215
226
  }
216
227
  }
@@ -254,7 +254,7 @@ const PARAM_DESCRIPTIONS = {
254
254
  proactiveSendTargetLabel: 'proactive 发送目标标签(对方/群里)',
255
255
  readonly: '是否只读模式',
256
256
  evolcoreMode: 'evolcore 运行模式(dev=源码仓库可直接修改 | install=全局安装包只读)',
257
- baseAgent: 'base agent 规范值(claude/codex/gemini/hermes)',
257
+ baseAgent: 'base agent 规范值(claude/codex/gemini/ecagent)',
258
258
  baseAgentName: 'base agent 显示名',
259
259
  baseAgentModel: 'base agent 引擎底座模型(evolcore 作用域无配置时的兜底)',
260
260
  effectiveModel: '当前实际生效模型(关系级 > agent级 > 全局 优先级解析结果)',