evolcore 0.0.18 → 0.0.20

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 (51) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +2 -0
  3. package/bin/install-codex-managed-hooks.mjs +61 -0
  4. package/dist/agents/claude-runner.js +4 -3
  5. package/dist/agents/codex-runner.js +25 -20
  6. package/dist/agents/ecagent-runner.js +3 -2
  7. package/dist/aun/aid/agentmd.js +7 -0
  8. package/dist/aun/msg/group.js +14 -3
  9. package/dist/aun/msg/p2p.js +21 -11
  10. package/dist/aun/outbox.js +144 -19
  11. package/dist/channels/aun.js +621 -211
  12. package/dist/cli/daemon-commands.js +41 -8
  13. package/dist/cli/index.js +1 -0
  14. package/dist/cli/init.js +55 -15
  15. package/dist/cli/restart-monitor.js +3 -3
  16. package/dist/config/aun-gateway-config.js +2 -0
  17. package/dist/config/config-manager.js +92 -8
  18. package/dist/config/config-operation-service.js +1 -2
  19. package/dist/config/gateway-config.js +9 -7
  20. package/dist/config/lifecycle.js +16 -5
  21. package/dist/config-store.js +13 -6
  22. package/dist/core/auth/authorization-audit.js +5 -2
  23. package/dist/core/bootstrap-messages.js +2 -2
  24. package/dist/core/bootstrap-service.js +21 -36
  25. package/dist/core/channel-loader.js +0 -2
  26. package/dist/core/data-migration.js +10 -4
  27. package/dist/core/evolagent.js +5 -4
  28. package/dist/core/message/message-bridge.js +6 -11
  29. package/dist/core/message/response-engine.js +62 -6
  30. package/dist/core/permission/ec-command-parser.js +203 -24
  31. package/dist/core/permission/sandbox-runtime.js +46 -12
  32. package/dist/core/permission/tool-policy.js +116 -47
  33. package/dist/core/relation/peer-identity.js +18 -0
  34. package/dist/eck/kit-renderer.js +17 -8
  35. package/dist/index.js +30 -19
  36. package/dist/ipc.js +6 -1
  37. package/dist/paths.js +0 -3
  38. package/dist/utils/stats.js +52 -18
  39. package/dist/utils/welcome.js +2 -2
  40. package/kits/docs/path-registry.md +1 -1
  41. package/kits/rules/01-overview.md +1 -1
  42. package/kits/rules/02-navigation.md +2 -2
  43. package/kits/rules/03-identity.md +1 -1
  44. package/kits/rules/05-venue.md +1 -1
  45. package/kits/schemas/_meta.json +7 -4
  46. package/kits/schemas/agent-config.schema.10.json +2 -1
  47. package/kits/schemas/agent-config.schema.11.json +408 -0
  48. package/kits/schemas/daemon.schema.5.json +136 -0
  49. package/kits/schemas/defaults.schema.5.json +107 -0
  50. package/package.json +2 -1
  51. package/dist/core/message/pause-controller.js +0 -53
package/CHANGELOG.md CHANGED
@@ -3,6 +3,45 @@
3
3
  本文件记录 EvolCore 的重要变更。EvolClaw 版本线的历史记录已归档至
4
4
  [`docs/_archive/CHANGELOG-evolclaw.md`](docs/_archive/CHANGELOG-evolclaw.md)。
5
5
 
6
+ ## 0.0.20 (2026-08-28)
7
+
8
+ ### AUN 网关与投递可靠性
9
+
10
+ - 接入 SDK 网关发现结果,校验消息 ID、投递状态和显式路由,区分永久失败与可重试失败。
11
+ - Outbox 保留永久失败诊断,并以路由条件更新避免并发投递覆盖修正后的目标。
12
+
13
+ ### Bootstrap 与配置生命周期
14
+
15
+ - 收紧 Bootstrap 消息路由和 Agent 生命周期门禁,补充配置兼容校验及 `ec init` 的 ecagent 配置交互。
16
+ - 增加 Agent、Daemon 和默认配置 schema 版本,权限审计记录命中的策略路径。
17
+
18
+ ### 观察者模式
19
+
20
+ - 观察者模式默认开启,显式设置 `false` 才关闭并持久化覆盖。
21
+
22
+ ### 跨平台运行与安装
23
+
24
+ - 统一运行时根目录解析,延长 Windows Daemon IPC 优雅关闭等待,并完善 Codex 受管目录安装准备。
25
+
26
+ ## 0.0.19 (2026-08-27)
27
+
28
+ ### PowerShell EC 命令安全
29
+
30
+ - 支持 PowerShell `pwsh`/`powershell` 受管命令载体解析,拒绝拼接、展开和重定向。
31
+ - 统一 Codex EC 命令委派与预检解析,补充 PowerShell 引号、展开和错误指引。
32
+
33
+ ### Bootstrap 与运行时控制
34
+
35
+ - Bootstrap 阶段保留 Menu 与斜杠协议处理,普通模型任务继续按生命周期门禁。
36
+ - 命令意外泄漏至响应引擎时统一丢弃并记录失败审计,避免进入 Agent 执行。
37
+
38
+ ### 跨平台安装与诊断
39
+
40
+ - Windows 数据迁移固定调用系统 `bsdtar`,避免 Git Bash GNU tar 误解析 Windows 绝对路径。
41
+ - Linux 公开安装器与 npm 全局安装/升级均幂等创建真实 `/etc/codex` 目录;root 历史实例可在启动任务时自愈缺失目录,同名文件和符号链接仍被拒绝。
42
+ - 统一数据根解析,仅使用 `EVOLCORE_HOME` 或 `~/.evolcore`,避免因启动目录不同误用数据目录。
43
+ - `ec start` 已运行提示新增 Daemon 持续运行时长,并支持 IPC uptime 回退探测。
44
+
6
45
  ## 0.0.18 (2026-08-27)
7
46
 
8
47
  ### DaemonOwner 与受管 Agent 操作
package/README.md CHANGED
@@ -103,6 +103,8 @@ curl -fsSL https://download.evolai.cn/install.sh | bash
103
103
  npm install -g evolcore
104
104
  ```
105
105
 
106
+ Linux 全局安装会在 `postinstall` 阶段准备 Codex 受管运行所需的真实目录 `/etc/codex`。如果当前 npm 全局目录属于普通用户且该系统目录尚不存在,请先执行 `sudo install -d -m 0755 /etc/codex`,再重新安装。
107
+
106
108
  > **Windows 用户**:首次运行前可能需要执行 `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser`
107
109
 
108
110
  **从源码安装**:
@@ -18,6 +18,59 @@ function fail(message) {
18
18
  process.exit(1);
19
19
  }
20
20
 
21
+ function isGlobalInstall() {
22
+ return ['1', 'true'].includes(String(process.env.npm_config_global || '').toLowerCase());
23
+ }
24
+
25
+ function ensureRealDirectory(directory) {
26
+ let stat;
27
+ try {
28
+ stat = fs.lstatSync(directory);
29
+ } catch (error) {
30
+ if (error?.code !== 'ENOENT') {
31
+ fail(`could not inspect the Codex managed requirements mountpoint ${directory}: ${error?.message || String(error)}`);
32
+ }
33
+ }
34
+
35
+ if (stat) {
36
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
37
+ fail(`Codex managed requirements mountpoint is unsafe: ${directory} must be a real directory.`);
38
+ }
39
+ return;
40
+ }
41
+
42
+ try {
43
+ fs.mkdirSync(directory, { mode: 0o755 });
44
+ fs.chmodSync(directory, 0o755);
45
+ } catch (error) {
46
+ if (error?.code === 'EEXIST') {
47
+ const raced = fs.lstatSync(directory);
48
+ if (raced.isDirectory() && !raced.isSymbolicLink()) return;
49
+ }
50
+ fail(
51
+ `Linux global installation requires the real directory ${directory}, but it could not be created: `
52
+ + `${error?.message || String(error)}. `
53
+ + `Create it first with: sudo install -d -m 0755 ${directory}`,
54
+ );
55
+ }
56
+
57
+ const created = fs.lstatSync(directory);
58
+ if (!created.isDirectory() || created.isSymbolicLink()) {
59
+ fail(`Codex managed requirements mountpoint provisioning failed: ${directory} must be a real directory.`);
60
+ }
61
+ process.stdout.write(`[evolcore] Prepared Codex managed requirements mountpoint at ${directory}.\n`);
62
+ }
63
+
64
+ function runLinuxPostinstall() {
65
+ const explicitMountpoint = argument('--mountpoint');
66
+ if (process.platform !== 'linux') return;
67
+ // Local source installs do not launch the Linux Codex guard and must not
68
+ // mutate machine-wide configuration. An explicit path is accepted only for
69
+ // isolated lifecycle behavior tests.
70
+ if (!isGlobalInstall() && !explicitMountpoint) return;
71
+ ensureRealDirectory(explicitMountpoint || '/etc/codex');
72
+ }
73
+
21
74
  function tomlString(value) {
22
75
  return JSON.stringify(value);
23
76
  }
@@ -139,6 +192,14 @@ try {
139
192
  }
140
193
 
141
194
  function main() {
195
+ if (process.env.npm_lifecycle_event === 'postinstall') {
196
+ runLinuxPostinstall();
197
+ return;
198
+ }
199
+ if (process.platform === 'linux' && argument('--mountpoint')) {
200
+ runLinuxPostinstall();
201
+ return;
202
+ }
142
203
  if (process.platform !== 'win32' && !argument('--requirements')) {
143
204
  fail('Codex managed hook provisioning is only supported on Windows.');
144
205
  }
@@ -2041,7 +2041,7 @@ export class AgentRunner {
2041
2041
  ...(updatedInput ? { updatedInput } : {}),
2042
2042
  },
2043
2043
  });
2044
- const recordPreflightDenial = async (toolName, toolInput, preflight, requestId, policyCode) => {
2044
+ const recordPreflightDenial = async (toolName, toolInput, preflight, requestId, policyCode, matchedPath) => {
2045
2045
  const code = policyCode ?? (preflight?.behavior === 'deny' ? preflight.policyCode : undefined);
2046
2046
  if (!code)
2047
2047
  return;
@@ -2061,6 +2061,7 @@ export class AgentRunner {
2061
2061
  selfAid: ctx?.selfAid,
2062
2062
  requestId: typeof requestId === 'string' ? requestId : undefined,
2063
2063
  taskId: ctx?.taskId,
2064
+ matchedPath: matchedPath ?? (preflight?.behavior === 'deny' ? preflight.matchedPath : undefined),
2064
2065
  });
2065
2066
  try {
2066
2067
  await ctx?.recordExecutionAnomaly?.({
@@ -2186,7 +2187,7 @@ export class AgentRunner {
2186
2187
  };
2187
2188
  const roResult = checkReadonly(toolName, toolInput, projectPath, readonlyContext);
2188
2189
  if (roResult.behavior === 'deny') {
2189
- await recordPreflightDenial(toolName, toolInput, undefined, input.tool_use_id ?? input.toolUseID, roResult.policyCode ?? 'readonly_mode');
2190
+ await recordPreflightDenial(toolName, toolInput, undefined, input.tool_use_id ?? input.toolUseID, roResult.policyCode ?? 'readonly_mode', roResult.matchedPath);
2190
2191
  return hookDecision('deny', roResult.message, updatedInput);
2191
2192
  }
2192
2193
  return hookDecision('allow', undefined, updatedInput);
@@ -2346,7 +2347,7 @@ export class AgentRunner {
2346
2347
  };
2347
2348
  const roResult = checkReadonly(toolName, input, projectPath, readonlyContext);
2348
2349
  if (roResult.behavior === 'deny') {
2349
- await recordPreflightDenial(toolName, input, undefined, options.toolUseID, roResult.policyCode ?? 'readonly_mode');
2350
+ await recordPreflightDenial(toolName, input, undefined, options.toolUseID, roResult.policyCode ?? 'readonly_mode', roResult.matchedPath);
2350
2351
  return { behavior: 'deny', message: roResult.message, decisionClassification: 'user_reject' };
2351
2352
  }
2352
2353
  return { behavior: 'allow', updatedInput: input, decisionClassification: 'user_permanent' };
@@ -20,7 +20,7 @@ import { buildEnvelope, sendInteractionPayload } from '../core/message/message-u
20
20
  import { resolveCodexCapabilityThreadConfigForProject } from '../core/capability/capability-manager.js';
21
21
  import { AGENT_DELEGATION_TOKEN_ENV, hashDelegatedCommandArgv } from '../core/auth/agent-delegation.js';
22
22
  import { sanitizeShellExecutionEnvironment } from '../core/permission/shell-environment.js';
23
- import { classifyEvolcoreShellCommand, containsLiteralManagedTmpDirOutsideSendContent, parseLiteralShellArgv, unwrapCodexShellCommandArgv, } from '../core/permission/ec-command-parser.js';
23
+ import { classifyEvolcoreShellCommand, containsLiteralManagedTmpDirOutsideSendContent, parseLiteralShellArgv, resolveCodexShellCarrierArgv, } from '../core/permission/ec-command-parser.js';
24
24
  import { compareVersions } from '../utils/npm-ops.js';
25
25
  import { resolvePaths, resolveRoot } from '../paths.js';
26
26
  import { ensureProcessManagedTempDir } from '../cli/task-context.js';
@@ -316,18 +316,20 @@ export class CodexRunner {
316
316
  createDelegationCarrier() {
317
317
  return randomBytes(32).toString('base64url');
318
318
  }
319
- approvedLiteralEvolcoreCommandArgv(command, managedTempDir) {
320
- const classification = classifyEvolcoreShellCommand(command);
319
+ approvedLiteralEvolcoreCommandArgv(command, managedTempDir, dialect = 'posix') {
320
+ const parseOptions = {
321
+ allowManagedTmpDir: true,
322
+ dialect,
323
+ ...(managedTempDir ? { managedTempDir } : {}),
324
+ };
325
+ const classification = classifyEvolcoreShellCommand(command, parseOptions);
321
326
  if (classification.kind === 'bounded-output')
322
327
  return classification.command.argv;
323
328
  if (classification.kind !== 'literal')
324
329
  return undefined;
325
330
  // Keep the approval/delegation parser aligned with the preflight parser:
326
331
  // the session-managed `$TMPDIR` token is a permitted EC path reference.
327
- const argv = parseLiteralShellArgv(command, {
328
- allowManagedTmpDir: true,
329
- ...(managedTempDir ? { managedTempDir } : {}),
330
- });
332
+ const argv = parseLiteralShellArgv(command, parseOptions);
331
333
  if (argv && containsLiteralManagedTmpDirOutsideSendContent(argv))
332
334
  return undefined;
333
335
  return argv?.[0] === 'ec' ? argv : undefined;
@@ -343,11 +345,11 @@ export class CodexRunner {
343
345
  ? undefined
344
346
  : explicitArgv;
345
347
  }
346
- const explicitWrappedCommand = explicitArgv
347
- ? unwrapCodexShellCommandArgv(explicitArgv)
348
+ const explicitCarrier = explicitArgv
349
+ ? resolveCodexShellCarrierArgv(explicitArgv)
348
350
  : undefined;
349
- if (explicitWrappedCommand !== undefined) {
350
- return this.approvedLiteralEvolcoreCommandArgv(explicitWrappedCommand, managedTempDir);
351
+ if (explicitCarrier !== undefined) {
352
+ return this.approvedLiteralEvolcoreCommandArgv(explicitCarrier.command, managedTempDir, explicitCarrier.dialect);
351
353
  }
352
354
  const command = typeof toolInput.command === 'string' ? toolInput.command : '';
353
355
  const directArgv = this.approvedLiteralEvolcoreCommandArgv(command, managedTempDir);
@@ -357,12 +359,12 @@ export class CodexRunner {
357
359
  allowManagedTmpDir: true,
358
360
  ...(managedTempDir ? { managedTempDir } : {}),
359
361
  });
360
- const wrappedCommand = wrappedArgv
361
- ? unwrapCodexShellCommandArgv(wrappedArgv)
362
+ const shellCarrier = wrappedArgv
363
+ ? resolveCodexShellCarrierArgv(wrappedArgv)
362
364
  : undefined;
363
- return wrappedCommand === undefined
365
+ return shellCarrier === undefined
364
366
  ? undefined
365
- : this.approvedLiteralEvolcoreCommandArgv(wrappedCommand, managedTempDir);
367
+ : this.approvedLiteralEvolcoreCommandArgv(shellCarrier.command, managedTempDir, shellCarrier.dialect);
366
368
  }
367
369
  isManagedEvolcoreCommandIntent(toolInput) {
368
370
  if (Array.isArray(toolInput.commandArgv)) {
@@ -371,9 +373,11 @@ export class CodexRunner {
371
373
  return true;
372
374
  if (!rawArgv.every(value => typeof value === 'string'))
373
375
  return false;
374
- const wrappedCommand = unwrapCodexShellCommandArgv(rawArgv);
375
- return wrappedCommand !== undefined
376
- && classifyEvolcoreShellCommand(wrappedCommand).kind !== 'none';
376
+ const shellCarrier = resolveCodexShellCarrierArgv(rawArgv);
377
+ return shellCarrier !== undefined
378
+ && classifyEvolcoreShellCommand(shellCarrier.command, {
379
+ dialect: shellCarrier.dialect,
380
+ }).kind !== 'none';
377
381
  }
378
382
  const command = typeof toolInput.command === 'string' ? toolInput.command : '';
379
383
  return classifyEvolcoreShellCommand(command).kind !== 'none';
@@ -2352,7 +2356,7 @@ export class CodexRunner {
2352
2356
  // per-session 权限模式(runQuery 写入);缺省回落实例级 currentMode(兼容无 runQuery 上下文的调用)
2353
2357
  const rawMode = this.chatModes.get(sessionKey) ?? this.currentMode;
2354
2358
  const mode = normalizePermissionMode(rawMode).mode;
2355
- const recordBlockedOperation = async (policyCode, operationInput = toolInput, denialReason = 'policy denied') => {
2359
+ const recordBlockedOperation = async (policyCode, operationInput = toolInput, denialReason = 'policy denied', matchedPath) => {
2356
2360
  const summary = summarizeToolInputForAudit(toolName, operationInput).slice(0, 512);
2357
2361
  auditToolPreflightDenial({
2358
2362
  toolName,
@@ -2368,6 +2372,7 @@ export class CodexRunner {
2368
2372
  selfAid: permissionContext?.selfAid,
2369
2373
  requestId: typeof requestId === 'string' || typeof requestId === 'number' ? String(requestId) : undefined,
2370
2374
  taskId: permissionContext?.taskId,
2375
+ matchedPath,
2371
2376
  });
2372
2377
  try {
2373
2378
  await permissionContext?.recordExecutionAnomaly?.({
@@ -2409,7 +2414,7 @@ export class CodexRunner {
2409
2414
  logger.warn(`[CodexRunner] tool preflight denied: session=${sessionKey} tool=${toolName} ` +
2410
2415
  `policy=${preflight.policyCode ?? 'unknown'} reason=${preflight.message ?? 'policy denied'}`);
2411
2416
  if (preflight.policyCode) {
2412
- await recordBlockedOperation(preflight.policyCode, toolInput, preflight.message ?? 'tool preflight denied');
2417
+ await recordBlockedOperation(preflight.policyCode, toolInput, preflight.message ?? 'tool preflight denied', preflight.matchedPath);
2413
2418
  }
2414
2419
  return 'deny';
2415
2420
  }
@@ -987,7 +987,7 @@ export class EcagentRunner {
987
987
  }
988
988
  async authorizeTool(sessionId, projectPath, mode, toolName, input) {
989
989
  const permissionContext = this.permissionContexts.get(sessionId);
990
- const recordBlockedOperation = async (policyCode, operationInput = input) => {
990
+ const recordBlockedOperation = async (policyCode, operationInput = input, matchedPath) => {
991
991
  const summary = summarizeToolInputForAudit(toolName, operationInput).slice(0, 512);
992
992
  auditToolPreflightDenial({
993
993
  toolName,
@@ -1002,6 +1002,7 @@ export class EcagentRunner {
1002
1002
  role: permissionContext?.role,
1003
1003
  selfAid: permissionContext?.selfAid,
1004
1004
  taskId: permissionContext?.taskId,
1005
+ matchedPath,
1005
1006
  });
1006
1007
  try {
1007
1008
  await permissionContext?.recordExecutionAnomaly?.({
@@ -1039,7 +1040,7 @@ export class EcagentRunner {
1039
1040
  });
1040
1041
  if (preflight.behavior === 'deny') {
1041
1042
  if (preflight.policyCode) {
1042
- await recordBlockedOperation(preflight.policyCode, input);
1043
+ await recordBlockedOperation(preflight.policyCode, input, preflight.matchedPath);
1043
1044
  }
1044
1045
  return { block: true, reason: preflight.message };
1045
1046
  }
@@ -266,6 +266,13 @@ export async function agentmdSync(aid, opts) {
266
266
  const ownStore = !opts?.store;
267
267
  const localPath = agentMdPath(aid);
268
268
  try {
269
+ // AIDStore owns the agent.md consistency API in fastaun 0.5.x. Keep this
270
+ // runtime guard because callers and test doubles can still accidentally
271
+ // pass an AUNClient (which deliberately does not expose these methods).
272
+ const candidate = store;
273
+ if (typeof candidate.checkAgentMd !== 'function' || typeof candidate.downloadAgentMd !== 'function') {
274
+ throw new TypeError('invalid AIDStore: checkAgentMd/downloadAgentMd unavailable');
275
+ }
269
276
  const check = await store.checkAgentMd(aid, 30);
270
277
  // In sync (cache fresh) — return local file content with cached verification status.
271
278
  if (check.ok && !check.data.needs_update && check.data.local_found) {
@@ -211,12 +211,23 @@ export async function groupSend(args) {
211
211
  const encrypt = resolveAunMessageEncrypt(args.encrypt);
212
212
  const sendParams = { group_id: args.groupId, payload, encrypt };
213
213
  const result = await conn.call('group.send', sendParams);
214
- const messageId = typeof result?.message?.message_id === 'string' ? result.message.message_id : undefined;
215
- if (messageId)
216
- appendGroupSendOutboundLog(args, messageId, payload, runtimeContext, encrypt);
214
+ const messageId = typeof result?.message?.message_id === 'string' && result.message.message_id.trim()
215
+ ? result.message.message_id
216
+ : typeof result?.message_id === 'string' && result.message_id.trim()
217
+ ? result.message_id
218
+ : undefined;
219
+ if (!messageId) {
220
+ return {
221
+ ok: false,
222
+ error: 'group.send returned no message_id',
223
+ code: 'MISSING_MESSAGE_ID',
224
+ };
225
+ }
226
+ appendGroupSendOutboundLog(args, messageId, payload, runtimeContext, encrypt);
217
227
  return {
218
228
  ok: true,
219
229
  group_id: result?.group_id ?? args.groupId,
230
+ message_id: messageId,
220
231
  message: result?.message,
221
232
  event: result?.event,
222
233
  };
@@ -289,24 +289,34 @@ export async function msgSend(args) {
289
289
  const encrypt = resolveAunMessageEncrypt(args.encrypt);
290
290
  const sendParams = { to: args.to, payload, encrypt };
291
291
  const result = await conn.call('message.send', sendParams);
292
+ const messageId = typeof result?.message_id === 'string' && result.message_id.trim()
293
+ ? result.message_id
294
+ : typeof result?.message?.message_id === 'string' && result.message.message_id.trim()
295
+ ? result.message.message_id
296
+ : undefined;
297
+ if (!messageId) {
298
+ return {
299
+ ok: false,
300
+ error: 'message.send returned no message_id',
301
+ code: 'MISSING_MESSAGE_ID',
302
+ };
303
+ }
292
304
  // 5. 写出方向 jsonl(与 daemon 一致格式,标记 source)
293
305
  // source 标记:
294
306
  // - 'cli': 用户手动调用 ec msg send
295
307
  // - 'msg': agent 在会话中调用 ec msg send
296
- if (result?.message_id) {
297
- try {
298
- await appendMsgSendOutboundLog(args, { ok: true, message_id: result.message_id }, {
299
- payload,
300
- runtimeContext,
301
- chatmode,
302
- encrypt,
303
- });
304
- }
305
- catch { }
308
+ try {
309
+ await appendMsgSendOutboundLog(args, { ok: true, message_id: messageId }, {
310
+ payload,
311
+ runtimeContext,
312
+ chatmode,
313
+ encrypt,
314
+ });
306
315
  }
316
+ catch { }
307
317
  return {
308
318
  ok: true,
309
- message_id: result?.message_id,
319
+ message_id: messageId,
310
320
  seq: result?.seq,
311
321
  timestamp: result?.timestamp,
312
322
  status: result?.status,