evolcore 0.0.2 → 0.0.4

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 (206) hide show
  1. package/CHANGELOG.md +93 -778
  2. package/README.md +45 -10
  3. package/bin/ec-safe-output.js +89 -24
  4. package/dist/agents/baseagent.js +46 -0
  5. package/dist/agents/claude-runner.js +198 -48
  6. package/dist/agents/codex-app-server-client.js +68 -0
  7. package/dist/agents/codex-runner.js +203 -8
  8. package/dist/agents/runner-types.js +2 -2
  9. package/dist/aun/aid/agentmd.js +79 -0
  10. package/dist/aun/aid/encryption-seed-policy.js +29 -0
  11. package/dist/aun/aid/index.js +1 -1
  12. package/dist/aun/aid/store.js +2 -5
  13. package/dist/aun/outbox.js +8 -0
  14. package/dist/channels/aun.js +241 -116
  15. package/dist/channels/daemon.js +18 -4
  16. package/dist/channels/dingtalk.js +1005 -260
  17. package/dist/channels/feishu.js +184 -56
  18. package/dist/channels/qqbot.js +23 -1
  19. package/dist/channels/wechat.js +303 -155
  20. package/dist/channels/wecom.js +1132 -164
  21. package/dist/cli/agent-command.js +2 -1
  22. package/dist/cli/aun-commands.js +98 -43
  23. package/dist/cli/bench.js +2 -2
  24. package/dist/cli/contact.js +71 -0
  25. package/dist/cli/ctl-command.js +2 -2
  26. package/dist/cli/daemon-commands.js +77 -214
  27. package/dist/cli/handoff-command.js +4 -3
  28. package/dist/cli/help.js +9 -5
  29. package/dist/cli/index.js +132 -116
  30. package/dist/cli/init-channel.js +242 -129
  31. package/dist/cli/init.js +70 -31
  32. package/dist/cli/model.js +2 -1
  33. package/dist/cli/net-check.js +2 -2
  34. package/dist/cli/queue-command.js +30 -6
  35. package/dist/cli/raw-key-input.js +25 -0
  36. package/dist/cli/response.js +5 -6
  37. package/dist/cli/restart-monitor.js +25 -1
  38. package/dist/cli/stats.js +6 -4
  39. package/dist/cli/trigger-command.js +146 -25
  40. package/dist/cli/version.js +6 -1
  41. package/dist/config/access-policy-domain.js +38 -0
  42. package/dist/config/access-policy.js +134 -0
  43. package/dist/config/builtin-role-templates.js +42 -17
  44. package/dist/config/builtin-roles.js +31 -6
  45. package/dist/config/config-field-policy.js +17 -5
  46. package/dist/config/config-manager.js +409 -29
  47. package/dist/config/config-operation-service.js +35 -38
  48. package/dist/config/contact-alias.js +68 -0
  49. package/dist/config/contact-bind-code.js +274 -0
  50. package/dist/config/contact-book-store.js +622 -0
  51. package/dist/config/contact-book-v2-startup.js +35 -0
  52. package/dist/config/contact-book.js +185 -300
  53. package/dist/config/contact-operation-service.js +116 -0
  54. package/dist/config/contact-request-service.js +331 -0
  55. package/dist/config/peer-role-resolver.js +136 -55
  56. package/dist/config/role-ranks.js +18 -0
  57. package/dist/config/role-service.js +16 -19
  58. package/dist/config/role-store.js +16 -5
  59. package/dist/config/roles.js +10 -1
  60. package/dist/config/schema-registry.js +49 -24
  61. package/dist/config-store.js +14 -4
  62. package/dist/core/auth/agent-delegation.js +105 -11
  63. package/dist/core/auth/authorization-audit.js +16 -1
  64. package/dist/core/auth/operation-authorizer.js +10 -0
  65. package/dist/core/auth/operation-catalog.js +105 -1
  66. package/dist/core/auth/trigger-authorization.js +15 -0
  67. package/dist/core/bootstrap-service.js +2 -9
  68. package/dist/core/channel-loader.js +6 -2
  69. package/dist/core/command/command-handler.js +113 -21
  70. package/dist/core/command/connect-menu.js +599 -0
  71. package/dist/core/command/evol-menu-version-gate.js +38 -0
  72. package/dist/core/command/group-menu.js +421 -0
  73. package/dist/core/command/menu-handler.js +382 -100
  74. package/dist/core/command/menu-protocol.js +8 -2
  75. package/dist/core/command/menu-token-store.js +102 -0
  76. package/dist/core/command/role-menu.js +128 -29
  77. package/dist/core/command/slash-gate.js +1 -1
  78. package/dist/core/command/slash-handler.js +186 -49
  79. package/dist/core/daemon-file-cache.js +40 -6
  80. package/dist/core/event-catalog.js +99 -0
  81. package/dist/core/evolagent-registry.js +4 -40
  82. package/dist/core/evolagent.js +20 -9
  83. package/dist/core/handoff/runtime.js +162 -37
  84. package/dist/core/handoff/store.js +46 -2
  85. package/dist/core/handoff/types.js +1 -0
  86. package/dist/core/inference/text-inference.js +16 -74
  87. package/dist/core/message/file-markers.js +7 -0
  88. package/dist/core/message/im-renderer.js +20 -14
  89. package/dist/core/message/inbound-admission.js +124 -0
  90. package/dist/core/message/message-bridge.js +670 -57
  91. package/dist/core/message/message-log.js +1 -0
  92. package/dist/core/message/message-queue.js +195 -10
  93. package/dist/core/message/message-utils.js +8 -2
  94. package/dist/core/message/peer-mode.js +7 -8
  95. package/dist/core/message/response-engine.js +642 -96
  96. package/dist/core/message/send-receipt.js +24 -0
  97. package/dist/core/message/stream-debouncer.js +11 -2
  98. package/dist/core/permission/approval-gateway.js +17 -10
  99. package/dist/core/permission/ec-command-parser.js +101 -46
  100. package/dist/core/permission/tool-policy.js +115 -38
  101. package/dist/core/protected-paths.js +38 -11
  102. package/dist/core/session/session-fs-store.js +44 -3
  103. package/dist/core/session/session-manager.js +86 -8
  104. package/dist/core/session/session-mapper.js +2 -0
  105. package/dist/core/session/session-renew.js +125 -69
  106. package/dist/core/session/session-turn-coordinator.js +5 -1
  107. package/dist/eck/kit-renderer.js +12 -1
  108. package/dist/eck/message-renderer.js +79 -1
  109. package/dist/index.js +285 -94
  110. package/dist/ipc.js +114 -8
  111. package/dist/paths.js +3 -0
  112. package/dist/response-system/config-resolver.js +29 -0
  113. package/dist/response-system/coordinator.js +8 -32
  114. package/dist/response-system/engines/v1/proactive-flow.js +1 -1
  115. package/dist/response-system/index.js +1 -0
  116. package/dist/response-system/modes/single-session/index.js +7 -4
  117. package/dist/stats/billing.js +20 -8
  118. package/dist/trigger/manager.js +3 -0
  119. package/dist/trigger/parser.js +126 -11
  120. package/dist/trigger/patch.js +12 -2
  121. package/dist/trigger/scheduler.js +444 -40
  122. package/dist/trigger/validation.js +13 -0
  123. package/dist/utils/aid-bind.js +43 -29
  124. package/dist/utils/error-dict.json +7 -0
  125. package/dist/utils/evolcore-version.js +21 -0
  126. package/dist/utils/instance-registry.js +14 -7
  127. package/dist/utils/log-writer.js +46 -0
  128. package/dist/utils/logger.js +2 -2
  129. package/dist/utils/media-cache.js +4 -1
  130. package/dist/utils/model-prices.jsonl +6 -3
  131. package/dist/utils/restart-safety.js +31 -0
  132. package/dist/utils/stable-semver.js +21 -0
  133. package/dist/utils/stats.js +33 -9
  134. package/dist/utils/system-memory.js +62 -0
  135. package/kits/docs/INDEX.md +2 -1
  136. package/kits/docs/channels/aun.md +4 -13
  137. package/kits/docs/evolcore/INDEX.md +5 -3
  138. package/kits/docs/evolcore/agent.md +9 -1
  139. package/kits/docs/evolcore/aid.md +5 -2
  140. package/kits/docs/evolcore/config.md +47 -2
  141. package/kits/docs/evolcore/contact.md +61 -0
  142. package/kits/docs/evolcore/fs.md +9 -0
  143. package/kits/docs/evolcore/group-rules.md +46 -4
  144. package/kits/docs/evolcore/group.md +15 -6
  145. package/kits/docs/evolcore/model.md +4 -1
  146. package/kits/docs/evolcore/msg.md +12 -6
  147. package/kits/docs/evolcore/response.md +16 -21
  148. package/kits/docs/evolcore/rpc.md +2 -0
  149. package/kits/docs/evolcore/stats.md +15 -2
  150. package/kits/docs/evolcore/storage.md +1 -0
  151. package/kits/docs/evolcore/trigger.md +42 -10
  152. package/kits/docs/path-registry.md +36 -17
  153. package/kits/eck_manifest.json +12 -0
  154. package/kits/eck_message_manifest.json +12 -1
  155. package/kits/migrations/migrate-contact-book-v2.mjs +754 -0
  156. package/kits/rules/01-overview.md +17 -7
  157. package/kits/rules/02-navigation.md +38 -18
  158. package/kits/rules/03-identity.md +28 -24
  159. package/kits/rules/04-relation.md +44 -28
  160. package/kits/rules/05-venue.md +31 -15
  161. package/kits/rules/06-channel.md +11 -7
  162. package/kits/schemas/_meta.json +21 -7
  163. package/kits/schemas/agent-config.schema.6.json +322 -0
  164. package/kits/schemas/agent-config.schema.7.json +303 -0
  165. package/kits/schemas/agent-config.schema.8.json +304 -0
  166. package/kits/schemas/agent-config.schema.9.json +374 -0
  167. package/kits/schemas/contact-book.schema.2.json +43 -0
  168. package/kits/schemas/contact-book.schema.3.json +67 -0
  169. package/kits/schemas/daemon.schema.1.json +3 -2
  170. package/kits/schemas/daemon.schema.2.json +101 -0
  171. package/kits/schemas/daemon.schema.3.json +123 -0
  172. package/kits/schemas/defaults.schema.2.json +85 -0
  173. package/kits/schemas/defaults.schema.3.json +73 -0
  174. package/kits/schemas/relation-config.schema.5.json +47 -0
  175. package/kits/schemas/relation-config.schema.6.json +46 -0
  176. package/kits/schemas/relation-config.schema.7.json +59 -0
  177. package/kits/schemas/role-config.schema.1.json +1 -0
  178. package/kits/schemas/role-registry.schema.1.json +2 -2
  179. package/kits/schemas/single-session.schema.2.json +57 -0
  180. package/kits/templates/message-fragments/handoff-context-to-target.md +9 -0
  181. package/kits/templates/message-fragments/handoff-request-to-target.md +14 -8
  182. package/kits/templates/message-fragments/handoff-response-to-origin.md +5 -6
  183. package/kits/templates/roles/admin.json +47 -0
  184. package/kits/templates/roles/member.json +5 -0
  185. package/kits/templates/roles/owner.json +1 -0
  186. package/kits/templates/roles/visitor.json +5 -0
  187. package/kits/templates/system-fragments/channel.md +12 -2
  188. package/kits/templates/system-fragments/commands.md +3 -1
  189. package/kits/templates/system-fragments/identity.md +3 -1
  190. package/kits/templates/system-fragments/relation.md +1 -1
  191. package/kits/templates/system-fragments/session.md +6 -2
  192. package/package.json +7 -5
  193. package/MIGRATION-0.5.0.md +0 -378
  194. package/ROLE_ACCESS_CONTROL.md +0 -174
  195. package/assets/brand/evolcore/README.md +0 -19
  196. package/assets/brand/evolcore/evolcore-app-icon.png +0 -0
  197. package/assets/brand/evolcore/evolcore-app-icon.svg +0 -13
  198. package/assets/brand/evolcore/evolcore-brand-board.png +0 -0
  199. package/assets/brand/evolcore/evolcore-brand-board.svg +0 -126
  200. package/assets/brand/evolcore/evolcore-logo-kit.zip +0 -0
  201. package/assets/brand/evolcore/evolcore-logo-reverse.png +0 -0
  202. package/assets/brand/evolcore/evolcore-logo-reverse.svg +0 -14
  203. package/assets/brand/evolcore/evolcore-logo.png +0 -0
  204. package/assets/brand/evolcore/evolcore-logo.svg +0 -14
  205. package/assets/brand/evolcore/evolcore-mark.png +0 -0
  206. package/assets/brand/evolcore/evolcore-mark.svg +0 -10
@@ -1,6 +1,6 @@
1
1
  import { logger } from '../../utils/logger.js';
2
2
  import { summarizeToolInput } from '../../utils/tool-summary.js';
3
- import { CONTEXT_TOO_LONG_PATTERN, getErrorMessage, isContextTooLongText } from '../../utils/error-utils.js';
3
+ import { getErrorMessage, isContextTooLongText } from '../../utils/error-utils.js';
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
6
  import { resolvePaths } from '../../paths.js';
@@ -289,6 +289,22 @@ export class IMRenderer {
289
289
  this.messageTimestamps.push(Date.now());
290
290
  this.scheduleFlush();
291
291
  }
292
+ /** interactive 下,以普通非最终文本发送用户需要看到的运行状态。 */
293
+ async sendOperationalNoticeAsText(text) {
294
+ if (!this.opts.operationalNoticesAsText || this.opts.envelope.chatmode === 'proactive' || !text)
295
+ return false;
296
+ // 保持与流式正文的到达顺序:先发出已缓冲的正文,再投影运行状态。
297
+ await this.flushText();
298
+ const payload = { kind: 'result.text', text, isFinal: false };
299
+ this.sentContent = true;
300
+ this.sendChain = this.sendChain
301
+ .then(() => this.opts.send(payload))
302
+ .catch(e => logger.warn('[IMRenderer] notice text send failed:', e));
303
+ await this.sendChain;
304
+ this.lastFlush = Date.now();
305
+ this.flushCount++;
306
+ return true;
307
+ }
292
308
  // ── 内部:interactive 模式聚合窗口 ──
293
309
  synthCallId() {
294
310
  return `synth-${this.opts.envelope.taskId}-${++this.syntheticCallSeq}`;
@@ -387,18 +403,6 @@ export class IMRenderer {
387
403
  item.text = item.text.replace(this.opts.fileMarkerPattern, '');
388
404
  }
389
405
  }
390
- if (isFinal) {
391
- // 上下文错误短语过滤:剔除错误关键词本身,保留前后内容。
392
- // 只在最终 flush 清理,避免中间定时 flush trim 掉 Markdown 块级换行。
393
- const ctxErrPattern = new RegExp(CONTEXT_TOO_LONG_PATTERN.source, 'gi');
394
- const stripCtxErr = (s) => s.replace(ctxErrPattern, '').trim();
395
- this.textBuffer = stripCtxErr(this.textBuffer);
396
- this.allText = stripCtxErr(this.allText);
397
- for (const item of this.itemsQueue) {
398
- if (item.kind === 'text')
399
- item.text = stripCtxErr(item.text);
400
- }
401
- }
402
406
  // 清掉空 text items
403
407
  const items = this.itemsQueue.filter(it => {
404
408
  if (it.kind === 'text')
@@ -419,7 +423,7 @@ export class IMRenderer {
419
423
  });
420
424
  }
421
425
  // 1. interactive 模式下:不发 text items(由 result.text 统一发送最终文本)
422
- let itemsForBatch = this.suppressActivityItems() ? [] : items.filter(it => it.kind !== 'text');
426
+ const itemsForBatch = this.suppressActivityItems() ? [] : items.filter(it => it.kind !== 'text');
423
427
  if (itemsForBatch.length > 0) {
424
428
  const payload = { kind: 'activity.batch', items: itemsForBatch };
425
429
  this.sentContent = true;
@@ -589,6 +593,8 @@ export class IMRenderer {
589
593
  return { kind: 'notice', text, severity: 'warn' };
590
594
  }
591
595
  case 'complete': {
596
+ if (event.queryFinal === false)
597
+ return null;
592
598
  // 上下文过长错误不输出(留给外层 auto-compact 处理)
593
599
  const hasContextError = event.terminalReason === 'prompt_too_long'
594
600
  || isContextTooLongText(event.errors?.join(' ') || '')
@@ -0,0 +1,124 @@
1
+ import { AccessPolicyError, readAccessPolicy, } from '../../config/access-policy.js';
2
+ import { isAcceptedContact, resolveContactView, resolvePrincipal, } from '../../config/contact-book.js';
3
+ export function evaluateInboundAdmissionPreflight(input) {
4
+ const selfAid = String(input.selfAid || '').trim();
5
+ const channelType = String(input.channelType || '').trim().toLowerCase();
6
+ const actorId = String(input.actorId || '').trim();
7
+ const context = {
8
+ selfAid,
9
+ channelKey: input.channelKey,
10
+ channelType,
11
+ chatType: input.chatType,
12
+ actorId,
13
+ trustedHandoffEcho: input.trustedHandoffEcho === true,
14
+ isOwner: false,
15
+ };
16
+ if (context.trustedHandoffEcho)
17
+ return { allow: true, context };
18
+ if (!selfAid)
19
+ return { allow: false, reason: 'invalid_identity', context };
20
+ if (input.chatType === 'private') {
21
+ const principal = resolvePrincipal(selfAid, channelType, actorId, input.channelKey);
22
+ context.principal = principal;
23
+ context.primaryId = principal.principalId;
24
+ if (principal.principalStatus === 'conflict') {
25
+ return { allow: false, reason: 'identity_conflict', context };
26
+ }
27
+ if (principal.principalStatus === 'error') {
28
+ return { allow: false, reason: 'identity_resolution_error', context };
29
+ }
30
+ if (channelType === 'aun' && principal.principalStatus !== 'native_aid') {
31
+ return { allow: false, reason: 'invalid_identity', context };
32
+ }
33
+ if (principal.principalId) {
34
+ try {
35
+ const contact = resolveContactView(selfAid, principal.principalId);
36
+ context.contactStatus = contact.status;
37
+ context.contactSource = contact.source;
38
+ context.isOwner = contact.isOwner;
39
+ if (contact.blocked)
40
+ return { allow: false, reason: 'blocked', context };
41
+ }
42
+ catch {
43
+ return { allow: false, reason: 'identity_resolution_error', context };
44
+ }
45
+ }
46
+ }
47
+ try {
48
+ context.policy = readAccessPolicy(selfAid);
49
+ }
50
+ catch (error) {
51
+ if (error instanceof AccessPolicyError && error.code === 'restricted_mode_without_owner') {
52
+ return { allow: false, reason: 'restricted_mode_without_owner', context };
53
+ }
54
+ return { allow: false, reason: 'invalid_access_policy', context };
55
+ }
56
+ return { allow: true, context };
57
+ }
58
+ export function evaluateOrdinaryInboundAdmission(context) {
59
+ if (context.trustedHandoffEcho)
60
+ return { allow: true, reason: 'trusted_handoff', context };
61
+ const policy = context.policy;
62
+ if (!policy)
63
+ return { allow: false, reason: 'invalid_access_policy', context };
64
+ if (context.chatType === 'group') {
65
+ if (policy.policyMode === 'owners-only') {
66
+ return { allow: false, reason: 'owners_only', context };
67
+ }
68
+ // `open` is genuinely open: group traffic is not gated by the optional
69
+ // channel allow-list. In `contacts`, AUN groups are currently open once
70
+ // the agent is receiving that group; non-AUN channels remain explicit.
71
+ if (policy.policyMode === 'open'
72
+ || (policy.policyMode === 'contacts' && context.channelType === 'aun')) {
73
+ return { allow: true, reason: 'group_channel_allowed', context };
74
+ }
75
+ return policy.allowedGroupChannels.includes(context.channelKey)
76
+ ? { allow: true, reason: 'group_channel_allowed', context }
77
+ : { allow: false, reason: 'group_channel_denied', context };
78
+ }
79
+ if (context.isOwner)
80
+ return { allow: true, reason: 'owner', context };
81
+ if (policy.policyMode === 'open')
82
+ return { allow: true, reason: 'open', context };
83
+ if (policy.policyMode === 'owners-only')
84
+ return { allow: false, reason: 'owners_only', context };
85
+ if (context.primaryId && isAcceptedContact(context.selfAid, context.primaryId)) {
86
+ return { allow: true, reason: 'contact', context };
87
+ }
88
+ return { allow: false, reason: 'contact_required', context };
89
+ }
90
+ const principalReplyBuckets = new Map();
91
+ const channelReplyBuckets = new Map();
92
+ const PRINCIPAL_REPLY_MAX = 3;
93
+ const PRINCIPAL_REPLY_WINDOW_MS = 60 * 60 * 1000;
94
+ /** Atomically consume both admission-control reply budgets. */
95
+ export function consumeAdmissionReplyBudget(context, now = Date.now()) {
96
+ const principalKey = `${context.selfAid}\0${context.primaryId || context.actorId || '<unknown>'}`;
97
+ const channelKey = `${context.selfAid}\0${context.channelKey}`;
98
+ const policy = context.policy;
99
+ const maxTimes = policy?.requestLimit.maxTimes ?? 600;
100
+ const coolDownMs = (policy?.requestLimit.coolDown ?? 60 * 60) * 1000;
101
+ if (!canConsume(principalReplyBuckets.get(principalKey), PRINCIPAL_REPLY_MAX, PRINCIPAL_REPLY_WINDOW_MS, now)) {
102
+ return false;
103
+ }
104
+ if (!canConsume(channelReplyBuckets.get(channelKey), maxTimes, coolDownMs, now))
105
+ return false;
106
+ consume(principalReplyBuckets, principalKey, PRINCIPAL_REPLY_WINDOW_MS, now);
107
+ consume(channelReplyBuckets, channelKey, coolDownMs, now);
108
+ return true;
109
+ }
110
+ export function clearAdmissionReplyBudgets() {
111
+ principalReplyBuckets.clear();
112
+ channelReplyBuckets.clear();
113
+ }
114
+ function canConsume(bucket, limit, windowMs, now) {
115
+ return !bucket || now - bucket.windowStart >= windowMs || bucket.count < limit;
116
+ }
117
+ function consume(buckets, key, windowMs, now) {
118
+ const bucket = buckets.get(key);
119
+ if (!bucket || now - bucket.windowStart >= windowMs) {
120
+ buckets.set(key, { count: 1, windowStart: now });
121
+ return;
122
+ }
123
+ bucket.count += 1;
124
+ }