evolcore 0.0.26 → 0.0.27

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 (169) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/bin/codex-managed-acl.ps1 +43 -0
  3. package/dist/agents/baseagent-availability.js +68 -0
  4. package/dist/agents/claude-runner.js +123 -22
  5. package/dist/agents/codex/app-server-client.js +63 -26
  6. package/dist/agents/codex-runner.js +316 -411
  7. package/dist/agents/ecagent-runner.js +170 -25
  8. package/dist/agents/gemini-runner.js +6 -0
  9. package/dist/agents/runner-types.js +50 -2
  10. package/dist/aun/aid/agentmd.js +73 -31
  11. package/dist/aun/aid/client.js +1 -1
  12. package/dist/aun/aid/control-aid.js +180 -1
  13. package/dist/aun/aid/identity.js +3 -3
  14. package/dist/aun/group/history.js +303 -0
  15. package/dist/aun/group/identity.js +43 -0
  16. package/dist/aun/group/index.js +5 -0
  17. package/dist/aun/{msg/group.js → group/operations.js} +161 -38
  18. package/dist/aun/{menu-client.js → menu/client.js} +12 -7
  19. package/dist/aun/menu/index.js +2 -0
  20. package/dist/aun/menu/transport.js +49 -0
  21. package/dist/aun/msg/index.js +2 -1
  22. package/dist/aun/msg/managed-operation.js +84 -18
  23. package/dist/aun/msg/mention-schema.js +51 -0
  24. package/dist/aun/msg/p2p.js +13 -8
  25. package/dist/aun/msg/upload.js +43 -88
  26. package/dist/aun/outbox.js +29 -7
  27. package/dist/aun/rpc/client.js +1 -0
  28. package/dist/aun/storage/client.js +39 -50
  29. package/dist/channels/aun.js +522 -233
  30. package/dist/channels/daemon.js +10 -6
  31. package/dist/cli/agent-command.js +108 -6
  32. package/dist/cli/agent-create.js +515 -2
  33. package/dist/cli/agent.js +109 -8
  34. package/dist/cli/aun-commands.js +191 -42
  35. package/dist/cli/config.js +8 -5
  36. package/dist/cli/contact.js +2 -2
  37. package/dist/cli/ctl-command.js +2 -2
  38. package/dist/cli/daemon-commands.js +35 -23
  39. package/dist/cli/diag.js +2 -2
  40. package/dist/cli/fs-command.js +3 -3
  41. package/dist/cli/handoff-command.js +6 -6
  42. package/dist/cli/index.js +8 -2
  43. package/dist/cli/init.js +34 -1
  44. package/dist/cli/managed-command-guard.js +2 -1
  45. package/dist/cli/menu-client.js +9 -5
  46. package/dist/cli/model.js +3 -3
  47. package/dist/cli/queue-command.js +2 -2
  48. package/dist/cli/response.js +2 -2
  49. package/dist/cli/restart-monitor.js +16 -2
  50. package/dist/cli/task-command.js +59 -0
  51. package/dist/cli/task-context.js +97 -49
  52. package/dist/cli/trigger-command.js +20 -10
  53. package/dist/config/builtin-roles.js +10 -0
  54. package/dist/config/config-field-policy.js +11 -0
  55. package/dist/config/config-manager.js +32 -4
  56. package/dist/config/config-operation-service.js +20 -5
  57. package/dist/config/contact-book-store.js +1 -1
  58. package/dist/config/contact-book.js +1 -1
  59. package/dist/config/contact-operation-service.js +1 -1
  60. package/dist/config/peer-role-resolver.js +1 -1
  61. package/dist/config/resolved-config-op.js +3 -0
  62. package/dist/config-store.js +1 -1
  63. package/dist/core/agent-application-service.js +5 -0
  64. package/dist/core/audit/event-key.js +17 -2
  65. package/dist/core/audit/log-integrity.js +34 -8
  66. package/dist/core/auth/agent-delegation.js +48 -14
  67. package/dist/core/auth/auth-gateway.js +2 -0
  68. package/dist/core/auth/authorization-audit.js +34 -38
  69. package/dist/core/auth/operation-authorizer.js +67 -5
  70. package/dist/core/auth/operation-catalog.js +110 -0
  71. package/dist/core/auth/remote-access-store.js +115 -9
  72. package/dist/core/bootstrap-messages.js +66 -7
  73. package/dist/core/bootstrap-service.js +110 -19
  74. package/dist/core/command/agent-control.js +88 -7
  75. package/dist/core/command/agent-storage-menu.js +443 -0
  76. package/dist/core/command/cli-intent-parser.js +19 -0
  77. package/dist/core/command/command-handler.js +76 -39
  78. package/dist/core/command/data-root-resolver.js +273 -0
  79. package/dist/core/command/group-menu.js +7 -2
  80. package/dist/core/command/menu-catalog.js +34 -4
  81. package/dist/core/command/menu-handler.js +348 -77
  82. package/dist/core/command/menu-protocol.js +40 -6
  83. package/dist/core/command/role-menu.js +2 -2
  84. package/dist/core/command/slash-handler.js +37 -22
  85. package/dist/core/event-catalog.js +4 -0
  86. package/dist/core/evolagent-registry.js +28 -2
  87. package/dist/core/group/invite-service.js +924 -0
  88. package/dist/core/interaction-router.js +22 -8
  89. package/dist/core/message/im-renderer.js +76 -15
  90. package/dist/core/message/message-bridge.js +94 -11
  91. package/dist/core/message/message-log.js +5 -3
  92. package/dist/core/message/message-queue.js +73 -41
  93. package/dist/core/message/response-engine.js +709 -117
  94. package/dist/core/permission/approval-gateway.js +36 -3
  95. package/dist/core/permission/ec-command-parser.js +61 -29
  96. package/dist/core/permission/protected-paths.js +134 -16
  97. package/dist/core/permission/sandbox-runtime.js +72 -3
  98. package/dist/core/permission/tool-error-code.js +15 -0
  99. package/dist/core/permission/tool-policy.js +7 -7
  100. package/dist/core/relation/peer-identity.js +57 -6
  101. package/dist/core/relation/shared-data.js +106 -0
  102. package/dist/core/role/runtime-policy.js +64 -0
  103. package/dist/core/runtime-lock.js +10 -26
  104. package/dist/core/session/runner-task-history.js +170 -0
  105. package/dist/core/session/session-manager.js +34 -6
  106. package/dist/core/session/session-mapper.js +41 -0
  107. package/dist/core/session/session-turn-coordinator.js +37 -7
  108. package/dist/core/session/session-turns.js +48 -7
  109. package/dist/core/task/task-recovery-service.js +176 -0
  110. package/dist/core/task/task-resume-operation.js +32 -0
  111. package/dist/eck/group-rules-sync.js +5 -3
  112. package/dist/eck/kit-renderer.js +1 -0
  113. package/dist/index.js +308 -54
  114. package/dist/ipc.js +141 -15
  115. package/dist/paths.js +17 -4
  116. package/dist/product.js +2 -0
  117. package/dist/trigger/event-source.js +19 -0
  118. package/dist/trigger/feedback.js +233 -40
  119. package/dist/trigger/parser.js +55 -5
  120. package/dist/trigger/patch.js +9 -0
  121. package/dist/trigger/scheduler.js +30 -4
  122. package/dist/trigger/validation.js +20 -3
  123. package/dist/utils/ecweb-utils.js +1 -0
  124. package/dist/utils/error-utils.js +40 -2
  125. package/dist/utils/logger.js +23 -13
  126. package/dist/utils/tool-summary.js +59 -3
  127. package/dist/utils/welcome.js +174 -1
  128. package/ecagent/dist/harness/agent-harness.js +3 -0
  129. package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
  130. package/kits/docs/INDEX.md +0 -6
  131. package/kits/docs/channels/aun.md +15 -2
  132. package/kits/docs/channels/feishu.md +1 -1
  133. package/kits/docs/context-assembly.md +29 -17
  134. package/kits/docs/evolcore/INDEX.md +8 -3
  135. package/kits/docs/evolcore/agent-create.md +39 -7
  136. package/kits/docs/evolcore/agent.md +33 -1
  137. package/kits/docs/evolcore/aid.md +9 -1
  138. package/kits/docs/evolcore/config.md +40 -1
  139. package/kits/docs/evolcore/group-collaboration.md +1 -1
  140. package/kits/docs/evolcore/group.md +117 -2
  141. package/kits/docs/evolcore/menu-client.md +16 -0
  142. package/kits/docs/evolcore/msg.md +3 -0
  143. package/kits/docs/evolcore/storage.md +3 -0
  144. package/kits/docs/evolcore/task.md +14 -0
  145. package/kits/docs/evolcore/trigger.md +51 -3
  146. package/kits/docs/venues/group.md +5 -0
  147. package/kits/eck_manifest.json +27 -0
  148. package/kits/rules/01-overview.md +11 -7
  149. package/kits/rules/04-relation.md +2 -1
  150. package/kits/rules/05-venue.md +1 -1
  151. package/kits/rules/06-channel.md +6 -4
  152. package/kits/schemas/agent-config.schema.12.json +25 -1
  153. package/kits/schemas/daemon.schema.6.json +2 -2
  154. package/kits/schemas/defaults.schema.5.json +1 -1
  155. package/kits/schemas/relation-config.schema.1.json +1 -1
  156. package/kits/schemas/relation-config.schema.5.json +1 -1
  157. package/kits/schemas/role-config.schema.1.json +14 -0
  158. package/kits/templates/roles/member.json +5 -0
  159. package/kits/templates/roles/visitor.json +5 -0
  160. package/kits/templates/system-fragments/baseagent.md +1 -1
  161. package/kits/templates/system-fragments/bootstrap.md +26 -9
  162. package/kits/templates/system-fragments/channel.md +8 -44
  163. package/kits/templates/system-fragments/commands.md +10 -2
  164. package/kits/templates/system-fragments/group-unread-history.md +7 -0
  165. package/kits/templates/system-fragments/reply.md +56 -0
  166. package/package.json +7 -3
  167. package/dist/aun/group-identity.js +0 -9
  168. /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
  169. /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
@@ -115,14 +115,14 @@ function writeEntries(aid, entries, queue = 'default') {
115
115
  atomicWrite(file, content);
116
116
  }
117
117
  function trimFinalEntries(entries) {
118
- const finalEntries = entries.filter(entry => !!entry.terminal || !!entry.deliveryResult);
118
+ const finalEntries = entries.filter(entry => !entry.critical && (!!entry.terminal || !!entry.deliveryResult));
119
119
  if (finalEntries.length <= MAX_TERMINAL_ENTRIES_PER_AID)
120
120
  return entries;
121
121
  const retainedFinalIds = new Set(finalEntries
122
122
  .sort((left, right) => (left.terminal?.at ?? left.deliveryResult?.at ?? left.ts) - (right.terminal?.at ?? right.deliveryResult?.at ?? right.ts))
123
123
  .slice(-MAX_TERMINAL_ENTRIES_PER_AID)
124
124
  .map(entry => entry.id));
125
- return entries.filter(entry => (!entry.terminal && !entry.deliveryResult) || retainedFinalIds.has(entry.id));
125
+ return entries.filter(entry => entry.critical || (!entry.terminal && !entry.deliveryResult) || retainedFinalIds.has(entry.id));
126
126
  }
127
127
  export function enqueue(aid, opts) {
128
128
  const queue = opts.queue ?? 'default';
@@ -138,12 +138,11 @@ export function enqueue(aid, opts) {
138
138
  markExpired(existing);
139
139
  }
140
140
  if (opts.dedupeKey) {
141
- // Terminal results are decisions for this logical operation. Reusing the
142
- // same route must not silently turn a permanent rejection into a retry;
143
- // an explicit route correction is the only case that replaces it.
141
+ // A terminal result or a delivery receipt is also a decision for this
142
+ // logical operation. Reusing the same route must return that decision
143
+ // instead of silently creating a second send attempt. Route correction
144
+ // remains the one intentional replacement path.
144
145
  const existing = existingEntries.find(entry => entry.dedupeKey === opts.dedupeKey
145
- && !entry.terminal
146
- && !entry.deliveryResult
147
146
  && !isExpired(entry));
148
147
  if (existing
149
148
  && existing.channelId === opts.channelId
@@ -323,6 +322,17 @@ export function markTerminal(aid, id, failure, submitted, queue = submitted ? en
323
322
  writeEntries(aid, entries, queue);
324
323
  return true;
325
324
  }
325
+ /** Keep the latest transient failure visible without changing the operation or its route. */
326
+ export function recordRetry(aid, submitted, failure) {
327
+ const queue = entryQueue(submitted);
328
+ const entries = readEntries(aid, queue);
329
+ const entry = entries.find(candidate => candidate.id === submitted.id);
330
+ if (!entry || !hasSamePersistedRoute(entry, submitted) || entry.terminal || entry.deliveryResult)
331
+ return;
332
+ entry.lastError = failure.error ?? 'delivery is pending';
333
+ entry.lastErrorCode = failure.code;
334
+ writeEntries(aid, entries, queue);
335
+ }
326
336
  /** Retain a bounded success receipt for queued Trigger history reconciliation. */
327
337
  export function markDelivered(aid, id, messageId, submitted, queue = submitted ? entryQueue(submitted) : 'default') {
328
338
  const entries = readEntries(aid, queue);
@@ -364,6 +374,18 @@ async function drainOnce(aid, sender, queue) {
364
374
  let permanent = 0;
365
375
  const remaining = [];
366
376
  for (const entry of entries) {
377
+ // Cancellation or another sender may have changed an
378
+ // entry while this drain was awaiting a previous network call.
379
+ if (entry.critical) {
380
+ const currentEntry = readEntries(aid, queue).find(candidate => candidate.id === entry.id);
381
+ if (!currentEntry || !hasSamePersistedRoute(currentEntry, entry))
382
+ continue;
383
+ if (currentEntry.terminal || currentEntry.deliveryResult) {
384
+ remaining.push(currentEntry);
385
+ continue;
386
+ }
387
+ Object.assign(entry, currentEntry);
388
+ }
367
389
  if (isExpired(entry)) {
368
390
  expired++;
369
391
  markExpired(entry);
@@ -5,6 +5,7 @@ export async function createShortConnection(aid, opts) {
5
5
  const client = await loadClient(store, aid);
6
6
  await client.connect({ connection_kind: 'short', short_ttl_ms: opts?.shortTtlMs ?? 30000, auto_reconnect: false });
7
7
  return {
8
+ get storage() { return client.storage; },
8
9
  async call(method, params) {
9
10
  return client.call(method, params);
10
11
  },
@@ -1,9 +1,10 @@
1
1
  import fs from 'fs';
2
- import crypto from 'crypto';
3
- import { rpcCall } from '../rpc/index.js';
2
+ import { createShortConnection, rpcCall } from '../rpc/index.js';
4
3
  function rpcErrorToString(error) {
5
4
  if (!error)
6
5
  return 'unknown error';
6
+ if (error instanceof Error)
7
+ return error.message;
7
8
  if (typeof error === 'string')
8
9
  return error;
9
10
  try {
@@ -13,67 +14,55 @@ function rpcErrorToString(error) {
13
14
  return String(error);
14
15
  }
15
16
  }
16
- function pickUrl(value) {
17
- return typeof value === 'string' && value.trim() ? value : undefined;
18
- }
19
17
  export async function storageUpload(aid, localFile, remotePath, opts) {
20
18
  const fileBuffer = Buffer.isBuffer(localFile) ? localFile : fs.readFileSync(localFile);
21
19
  return storageUploadBuffer(aid, fileBuffer, remotePath, opts);
22
20
  }
23
21
  export async function storageUploadBuffer(aid, fileBuffer, remotePath, opts) {
24
- const contentType = opts?.contentType ?? 'application/octet-stream';
25
- const sha256 = crypto.createHash('sha256').update(fileBuffer).digest('hex');
26
- const createResult = await rpcCall(aid, 'storage.create_upload_session', {
27
- object_key: remotePath,
28
- content_type: contentType,
29
- size_bytes: fileBuffer.length,
30
- }, { aunPath: opts?.aunPath });
31
- if (!createResult.ok) {
32
- return { ok: false, objectKey: remotePath, error: rpcErrorToString(createResult.error) };
33
- }
34
- const uploadUrl = createResult.result.upload_url;
35
- if (!uploadUrl) {
36
- return { ok: false, objectKey: remotePath, error: 'storage.create_upload_session did not return upload_url' };
37
- }
38
- const putResp = await fetch(uploadUrl, {
39
- method: 'PUT',
40
- headers: { 'Content-Type': contentType },
41
- body: new Blob([new Uint8Array(fileBuffer)], { type: contentType }),
42
- redirect: 'follow',
43
- });
44
- if (!putResp.ok) {
45
- return { ok: false, objectKey: remotePath, error: `HTTP PUT failed: ${putResp.status}` };
22
+ let conn;
23
+ try {
24
+ conn = await createShortConnection(aid, { aunPath: opts?.aunPath });
25
+ const uploaded = await conn.storage.writeBytes(remotePath, fileBuffer, {
26
+ contentType: opts?.contentType,
27
+ public: opts?.isPublic ?? false,
28
+ overwrite: true,
29
+ });
30
+ const objectKey = uploaded.path.replace(/^\/+/, '');
31
+ if (!objectKey)
32
+ throw new Error('Storage 上传结果缺少文件路径');
33
+ // agent.md avatars require a stable public URL, never an expiring ticket.
34
+ const publicUrl = opts?.isPublic
35
+ ? `https://${aid}/${objectKey.split('/').map(encodeURIComponent).join('/')}`
36
+ : undefined;
37
+ return { ok: true, objectKey, publicUrl };
46
38
  }
47
- const completeResult = await rpcCall(aid, 'storage.complete_upload', {
48
- object_key: remotePath,
49
- sha256,
50
- content_type: contentType,
51
- size_bytes: fileBuffer.length,
52
- is_private: !opts?.isPublic,
53
- }, { aunPath: opts?.aunPath });
54
- if (!completeResult.ok) {
55
- return { ok: false, objectKey: remotePath, error: rpcErrorToString(completeResult.error) };
39
+ catch (error) {
40
+ return { ok: false, objectKey: remotePath, error: rpcErrorToString(error) };
56
41
  }
57
- let publicUrl = pickUrl(completeResult.result?.url);
58
- if (opts?.isPublic) {
59
- if (!publicUrl) {
60
- const ticketResult = await rpcCall(aid, 'storage.create_download_ticket', {
61
- object_key: remotePath,
62
- expire_in_seconds: 86400 * 30,
63
- }, { aunPath: opts?.aunPath });
64
- if (ticketResult.ok) {
65
- publicUrl = pickUrl(ticketResult.result?.url) ?? pickUrl(ticketResult.result?.download_url);
66
- }
67
- }
68
- publicUrl ??= `https://${aid}/${remotePath}`;
42
+ finally {
43
+ if (conn)
44
+ await conn.close();
69
45
  }
70
- return { ok: true, objectKey: remotePath, publicUrl };
71
46
  }
72
47
  export async function storageLs(aid, prefix, opts) {
73
48
  return rpcCall(aid, 'storage.list_objects', { prefix: prefix || '' }, { aunPath: opts?.aunPath });
74
49
  }
75
50
  export async function storageRm(aid, remotePath, opts) {
76
- return rpcCall(aid, 'storage.delete_object', { object_key: remotePath }, { aunPath: opts?.aunPath });
51
+ let conn;
52
+ try {
53
+ conn = await createShortConnection(aid, { aunPath: opts?.aunPath });
54
+ const result = await conn.storage.remove(remotePath);
55
+ return { ok: true, result };
56
+ }
57
+ catch (error) {
58
+ const code = error && typeof error === 'object' && 'code' in error && typeof error.code === 'number'
59
+ ? error.code : -1;
60
+ return { ok: false, error: { code, message: rpcErrorToString(error) } };
61
+ }
62
+ finally {
63
+ if (conn)
64
+ await conn.close();
65
+ }
77
66
  }
78
67
  export async function storageQuota(aid, opts) {
79
68
  return rpcCall(aid, 'storage.get_quota', {}, { aunPath: opts?.aunPath });