evolcore 0.0.7 → 0.0.9
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.
- package/CHANGELOG.md +43 -0
- package/README.md +38 -4
- package/dist/agents/baseagent.js +117 -24
- package/dist/agents/claude-runner.js +31 -2
- package/dist/agents/codex-app-server-client.js +37 -2
- package/dist/agents/codex-runner.js +11 -3
- package/dist/aun/aid/control-aid.js +40 -27
- package/dist/aun/aid/domain.js +23 -0
- package/dist/aun/msg/group.js +9 -9
- package/dist/aun/msg/p2p.js +11 -6
- package/dist/aun/msg/upload.js +43 -29
- package/dist/aun/outbox.js +48 -5
- package/dist/channels/aun.js +225 -71
- package/dist/cli/aun-commands.js +10 -7
- package/dist/cli/bench.js +4 -3
- package/dist/cli/daemon-commands.js +208 -68
- package/dist/cli/data-command.js +62 -35
- package/dist/cli/index.js +11 -1
- package/dist/cli/init-channel.js +1 -1
- package/dist/cli/init.js +112 -17
- package/dist/cli/model.js +5 -5
- package/dist/cli/restart-monitor.js +102 -22
- package/dist/config/builtin-role-templates.js +4 -3
- package/dist/config/config-field-policy.js +6 -2
- package/dist/config/config-manager.js +79 -11
- package/dist/config/gateway-config.js +80 -35
- package/dist/config/role-schema.js +18 -3
- package/dist/config/role-service.js +3 -3
- package/dist/config/role-store.js +4 -3
- package/dist/config-store.js +19 -3
- package/dist/core/auth/operation-authorizer.js +3 -1
- package/dist/core/baseagent-loader.js +5 -3
- package/dist/core/bootstrap-service.js +0 -12
- package/dist/core/capability/providers/codex-capability-provider.js +2 -2
- package/dist/core/channel-loader.js +15 -2
- package/dist/core/command/command-handler.js +1 -1
- package/dist/core/command/evol-menu-version-gate.js +3 -2
- package/dist/core/command/menu-handler.js +50 -28
- package/dist/core/command/menu-protocol.js +7 -4
- package/dist/core/command/slash-handler.js +4 -4
- package/dist/core/data-migration.js +517 -24
- package/dist/core/inference/text-inference.js +18 -5
- package/dist/core/message/message-bridge.js +17 -6
- package/dist/core/message/response-engine.js +22 -3
- package/dist/core/model/config-scope.js +3 -3
- package/dist/core/permission/tool-policy.js +18 -0
- package/dist/core/protected-paths.js +12 -1
- package/dist/index.js +794 -725
- package/dist/ipc.js +3 -1
- package/dist/product.js +1 -0
- package/dist/utils/autostart.js +27 -0
- package/dist/utils/codex-cli.js +39 -0
- package/dist/utils/cross-platform.js +147 -18
- package/dist/utils/ecweb-utils.js +15 -2
- package/dist/utils/instance-registry.js +43 -6
- package/dist/utils/macos-autostart.js +179 -0
- package/dist/utils/process-introspect.js +7 -3
- package/dist/utils/windows-autostart.js +130 -0
- package/ecagent/dist/agent-loop.d.ts +1 -1
- package/ecagent/dist/agent-loop.js +1 -1
- package/ecagent/dist/agent.d.ts +1 -1
- package/ecagent/dist/agent.js +1 -1
- package/ecagent/dist/harness/agent-harness.d.ts +1 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts +1 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts +1 -1
- package/ecagent/dist/harness/compaction/utils.d.ts +1 -1
- package/ecagent/dist/harness/messages.d.ts +1 -1
- package/ecagent/dist/harness/session/session.d.ts +1 -1
- package/ecagent/dist/harness/types.d.ts +1 -1
- package/ecagent/dist/proxy.d.ts +1 -1
- package/ecagent/dist/proxy.js +1 -1
- package/ecagent/dist/types.d.ts +1 -1
- package/kits/migrations/migrate-role-config-v5.mjs +27 -2
- package/kits/rules/01-overview.md +3 -2
- package/kits/schemas/_meta.json +2 -1
- package/kits/schemas/agent-config.schema.10.json +19 -1
- package/kits/schemas/daemon.schema.4.json +136 -0
- package/kits/schemas/defaults.schema.4.json +15 -1
- package/kits/schemas/relation-config.schema.8.json +22 -1
- package/kits/schemas/role-config.schema.1.json +2 -2
- package/package.json +2 -4
- package/ecagent/dist/agent-loop.d.ts.map +0 -1
- package/ecagent/dist/agent-loop.js.map +0 -1
- package/ecagent/dist/agent.d.ts.map +0 -1
- package/ecagent/dist/agent.js.map +0 -1
- package/ecagent/dist/harness/agent-harness.d.ts.map +0 -1
- package/ecagent/dist/harness/agent-harness.js.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.js.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.js.map +0 -1
- package/ecagent/dist/harness/compaction/utils.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/utils.js.map +0 -1
- package/ecagent/dist/harness/env/nodejs.d.ts.map +0 -1
- package/ecagent/dist/harness/env/nodejs.js.map +0 -1
- package/ecagent/dist/harness/messages.d.ts.map +0 -1
- package/ecagent/dist/harness/messages.js.map +0 -1
- package/ecagent/dist/harness/prompt-templates.d.ts.map +0 -1
- package/ecagent/dist/harness/prompt-templates.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.js.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.js.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.js.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.d.ts.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.js.map +0 -1
- package/ecagent/dist/harness/session/session.d.ts.map +0 -1
- package/ecagent/dist/harness/session/session.js.map +0 -1
- package/ecagent/dist/harness/session/uuid.d.ts.map +0 -1
- package/ecagent/dist/harness/session/uuid.js.map +0 -1
- package/ecagent/dist/harness/skills.d.ts.map +0 -1
- package/ecagent/dist/harness/skills.js.map +0 -1
- package/ecagent/dist/harness/system-prompt.d.ts.map +0 -1
- package/ecagent/dist/harness/system-prompt.js.map +0 -1
- package/ecagent/dist/harness/types.d.ts.map +0 -1
- package/ecagent/dist/harness/types.js.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.js.map +0 -1
- package/ecagent/dist/harness/utils/truncate.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/truncate.js.map +0 -1
- package/ecagent/dist/index.d.ts.map +0 -1
- package/ecagent/dist/index.js.map +0 -1
- package/ecagent/dist/node.d.ts.map +0 -1
- package/ecagent/dist/node.js.map +0 -1
- package/ecagent/dist/proxy.d.ts.map +0 -1
- package/ecagent/dist/proxy.js.map +0 -1
- package/ecagent/dist/runtime/api/lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/lazy.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +0 -1
- package/ecagent/dist/runtime/auth/context.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/context.js.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.js.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.js.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.js.map +0 -1
- package/ecagent/dist/runtime/auth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/types.js.map +0 -1
- package/ecagent/dist/runtime/compat.d.ts.map +0 -1
- package/ecagent/dist/runtime/compat.js.map +0 -1
- package/ecagent/dist/runtime/index.d.ts.map +0 -1
- package/ecagent/dist/runtime/index.js.map +0 -1
- package/ecagent/dist/runtime/models.d.ts.map +0 -1
- package/ecagent/dist/runtime/models.js.map +0 -1
- package/ecagent/dist/runtime/oauth.d.ts.map +0 -1
- package/ecagent/dist/runtime/oauth.js.map +0 -1
- package/ecagent/dist/runtime/providers/faux.d.ts.map +0 -1
- package/ecagent/dist/runtime/providers/faux.js.map +0 -1
- package/ecagent/dist/runtime/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.js.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.js.map +0 -1
- package/ecagent/dist/runtime/utils/headers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/headers.js.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.js.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.js.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.js.map +0 -1
- package/ecagent/dist/runtime/utils/retry.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/retry.js.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.js.map +0 -1
- package/ecagent/dist/runtime/utils/validation.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/validation.js.map +0 -1
- package/ecagent/dist/types.d.ts.map +0 -1
- package/ecagent/dist/types.js.map +0 -1
- package/ecagent/package.json +0 -93
- package/ecagent/src/agent-loop.ts +0 -792
- package/ecagent/src/agent.ts +0 -575
- package/ecagent/src/harness/agent-harness.ts +0 -1029
- package/ecagent/src/harness/compaction/branch-summarization.ts +0 -261
- package/ecagent/src/harness/compaction/compaction.ts +0 -753
- package/ecagent/src/harness/compaction/utils.ts +0 -144
- package/ecagent/src/harness/env/nodejs.ts +0 -569
- package/ecagent/src/harness/messages.ts +0 -164
- package/ecagent/src/harness/prompt-templates.ts +0 -267
- package/ecagent/src/harness/session/jsonl-repo.ts +0 -179
- package/ecagent/src/harness/session/jsonl-storage.ts +0 -314
- package/ecagent/src/harness/session/memory-repo.ts +0 -50
- package/ecagent/src/harness/session/memory-storage.ts +0 -133
- package/ecagent/src/harness/session/repo-utils.ts +0 -51
- package/ecagent/src/harness/session/session.ts +0 -338
- package/ecagent/src/harness/session/uuid.ts +0 -54
- package/ecagent/src/harness/skills.ts +0 -375
- package/ecagent/src/harness/system-prompt.ts +0 -34
- package/ecagent/src/harness/types.ts +0 -838
- package/ecagent/src/harness/utils/shell-output.ts +0 -135
- package/ecagent/src/harness/utils/truncate.ts +0 -344
- package/ecagent/src/index.ts +0 -46
- package/ecagent/src/node.ts +0 -2
- package/ecagent/src/proxy.ts +0 -367
- package/ecagent/src/runtime/api/lazy.ts +0 -70
- package/ecagent/src/runtime/api/pi-messages.lazy.ts +0 -4
- package/ecagent/src/runtime/api/pi-messages.ts +0 -436
- package/ecagent/src/runtime/auth/context.ts +0 -45
- package/ecagent/src/runtime/auth/credential-store.ts +0 -47
- package/ecagent/src/runtime/auth/helpers.ts +0 -46
- package/ecagent/src/runtime/auth/resolve.ts +0 -141
- package/ecagent/src/runtime/auth/types.ts +0 -182
- package/ecagent/src/runtime/compat.ts +0 -158
- package/ecagent/src/runtime/index.ts +0 -31
- package/ecagent/src/runtime/models.ts +0 -452
- package/ecagent/src/runtime/oauth.ts +0 -1
- package/ecagent/src/runtime/providers/faux.ts +0 -538
- package/ecagent/src/runtime/types.ts +0 -718
- package/ecagent/src/runtime/utils/diagnostics.ts +0 -45
- package/ecagent/src/runtime/utils/event-stream.ts +0 -88
- package/ecagent/src/runtime/utils/headers.ts +0 -18
- package/ecagent/src/runtime/utils/json-parse.ts +0 -124
- package/ecagent/src/runtime/utils/oauth/types.ts +0 -79
- package/ecagent/src/runtime/utils/overflow.ts +0 -165
- package/ecagent/src/runtime/utils/provider-env.ts +0 -52
- package/ecagent/src/runtime/utils/retry.ts +0 -101
- package/ecagent/src/runtime/utils/typebox-helpers.ts +0 -24
- package/ecagent/src/runtime/utils/validation.ts +0 -310
- package/ecagent/src/types.ts +0 -430
- package/ecagent/tsconfig.build.json +0 -32
package/dist/channels/aun.js
CHANGED
|
@@ -16,9 +16,8 @@ import { chatDirPath } from '../core/session/session-fs-store.js';
|
|
|
16
16
|
import { appendHintAdd, appendHintRemove, parseInjectRequest } from '../core/message/pending-hints.js';
|
|
17
17
|
import { appendAidLifecycle } from '../aun/aid/identity.js';
|
|
18
18
|
import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
|
|
19
|
-
import { uploadFileAndBuildPayload } from '../aun/msg/upload.js';
|
|
19
|
+
import { MAX_AUN_ATTACHMENT_SIZE, uploadBufferAndBuildPayload, uploadFileAndBuildPayload } from '../aun/msg/upload.js';
|
|
20
20
|
import { loadAgent, saveAgent } from '../config-store.js';
|
|
21
|
-
import { activeBaseagent } from '../core/model/config-scope.js';
|
|
22
21
|
import { resolveEffective } from '../config/config-manager.js';
|
|
23
22
|
import { isManagementRole } from '../config/builtin-roles.js';
|
|
24
23
|
import { mentionModeToDispatch } from '../config/mention-mode.js';
|
|
@@ -35,6 +34,19 @@ import { isExplicitGroupId } from '../aun/group-identity.js';
|
|
|
35
34
|
import { refreshAgentDisplayName, resolveAgentDisplayName } from '../aun/aid/agentmd.js';
|
|
36
35
|
import { readInstalledEvolcoreVersion } from '../utils/evolcore-version.js';
|
|
37
36
|
export const AUN_HANDOFF_MARKER_FIELD = '_evolcore_handoff_id';
|
|
37
|
+
const AUN_INTERACTION_CARD_TTL_MS = 24 * 60 * 60 * 1000;
|
|
38
|
+
const IMAGE_MIME_TYPE = /^image\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/i;
|
|
39
|
+
function normalizeImageMimeType(mimeType) {
|
|
40
|
+
const normalized = mimeType?.split(';', 1)[0].trim().toLowerCase();
|
|
41
|
+
if (!normalized)
|
|
42
|
+
return undefined;
|
|
43
|
+
if (!normalized.startsWith('image/'))
|
|
44
|
+
return undefined;
|
|
45
|
+
if (!IMAGE_MIME_TYPE.test(normalized)) {
|
|
46
|
+
throw new Error('result.image MIME type must be a valid image media type');
|
|
47
|
+
}
|
|
48
|
+
return normalized;
|
|
49
|
+
}
|
|
38
50
|
/**
|
|
39
51
|
* 构造 connect extra_info:自描述本进程身份。
|
|
40
52
|
*
|
|
@@ -275,8 +287,8 @@ export class AUNChannel {
|
|
|
275
287
|
}
|
|
276
288
|
}
|
|
277
289
|
/** 判断 channelId 是否为群组 ID
|
|
278
|
-
* - 新格式:group.{
|
|
279
|
-
* - 数字群号:{group_no}.{
|
|
290
|
+
* - 新格式:group.{aidDomain}/{group_no|group_name}
|
|
291
|
+
* - 数字群号:{group_no}.{aidDomain}(如 11117.example.com)
|
|
280
292
|
* - 兼容旧格式:grp_xxx、g-xxx.agentid.pub
|
|
281
293
|
*/
|
|
282
294
|
/** 判断 channelId 是否群组 ID(public:plugin adapter 闭包需调用) */
|
|
@@ -359,10 +371,11 @@ export class AUNChannel {
|
|
|
359
371
|
|| (channelId && !this.isGroupId(channelId) ? channelId : '')
|
|
360
372
|
|| '';
|
|
361
373
|
if (cardInfo.isCommandCard) {
|
|
362
|
-
// CommandCard:action_value 是完整 slash
|
|
363
|
-
|
|
374
|
+
// CommandCard:action_value 是完整 slash 命令,构造伪入站消息。
|
|
375
|
+
// 先完成点击者鉴权,再消费 mapping;否则群成员的一次误点会让发起者
|
|
376
|
+
// 无法继续操作同一张卡片。
|
|
377
|
+
const chatType = channelId ? (this.isGroupId(channelId) ? 'group' : 'private') : 'private';
|
|
364
378
|
if (this.messageHandler && actionValue.startsWith('/')) {
|
|
365
|
-
const chatType = channelId ? (this.isGroupId(channelId) ? 'group' : 'private') : 'private';
|
|
366
379
|
// Initiator 校验:仅群聊需要(私聊信道一对一,点击者恒为对端 = initiator)。
|
|
367
380
|
// 身份只信认证信封提取的 cardClickerAid,非 payload 自报。
|
|
368
381
|
if (chatType === 'group' && !cardClickerAid) {
|
|
@@ -376,6 +389,9 @@ export class AUNChannel {
|
|
|
376
389
|
this.notifyCardActionFailure(channelId, '⚠️ 仅卡片发起者可操作', cardClickerAid, threadId);
|
|
377
390
|
return '';
|
|
378
391
|
}
|
|
392
|
+
// 已通过鉴权并即将进入处理流程;此时才消费 mapping,避免非发起者
|
|
393
|
+
// 或非法命令点击导致卡片提前失效。
|
|
394
|
+
this.cardMessageIdMap.delete(cardMsgId);
|
|
379
395
|
Promise.resolve(this.messageHandler({
|
|
380
396
|
channelId: channelId || '',
|
|
381
397
|
channelType: 'aun',
|
|
@@ -495,7 +511,7 @@ export class AUNChannel {
|
|
|
495
511
|
}
|
|
496
512
|
}
|
|
497
513
|
else if (this.ownedCardMsgIds.has(cardMsgId)) {
|
|
498
|
-
// 本 agent 发出的卡片,但 entry 已过期(
|
|
514
|
+
// 本 agent 发出的卡片,但 entry 已过期(24h TTL)
|
|
499
515
|
logger.debug(`${this.logPrefix()} action_card_reply expired: cardMsgId=${cardMsgId}`);
|
|
500
516
|
this.notifyCardActionFailure(channelId, '⚠️ 卡片已失效,请重新发起');
|
|
501
517
|
}
|
|
@@ -579,6 +595,38 @@ export class AUNChannel {
|
|
|
579
595
|
parts.push('---');
|
|
580
596
|
return parts.join('\n');
|
|
581
597
|
}
|
|
598
|
+
// 结构化 link/location 必须优先保留业务字段。部分客户端同时提供
|
|
599
|
+
// 顶层 text(仅供展示),若先返回该字段会丢失 URL、坐标和地址。
|
|
600
|
+
if (obj.type === 'link') {
|
|
601
|
+
const parts = [];
|
|
602
|
+
if (typeof obj.title === 'string' && obj.title)
|
|
603
|
+
parts.push(`标题: ${obj.title}`);
|
|
604
|
+
if (typeof obj.description === 'string' && obj.description)
|
|
605
|
+
parts.push(`描述: ${obj.description}`);
|
|
606
|
+
if (typeof obj.url === 'string' && obj.url)
|
|
607
|
+
parts.push(`URL: ${obj.url}`);
|
|
608
|
+
if (text && !parts.includes(text))
|
|
609
|
+
parts.push(text);
|
|
610
|
+
return parts.length > 0 ? parts.join('\n') : text || JSON.stringify(payload);
|
|
611
|
+
}
|
|
612
|
+
if (obj.type === 'location') {
|
|
613
|
+
const parts = [];
|
|
614
|
+
if (typeof obj.name === 'string' && obj.name)
|
|
615
|
+
parts.push(`地点: ${obj.name}`);
|
|
616
|
+
if (typeof obj.address === 'string' && obj.address)
|
|
617
|
+
parts.push(`地址: ${obj.address}`);
|
|
618
|
+
if (typeof obj.latitude === 'number' && Number.isFinite(obj.latitude))
|
|
619
|
+
parts.push(`纬度: ${obj.latitude}`);
|
|
620
|
+
if (typeof obj.longitude === 'number' && Number.isFinite(obj.longitude))
|
|
621
|
+
parts.push(`经度: ${obj.longitude}`);
|
|
622
|
+
if (typeof obj.precision_m === 'number' && Number.isFinite(obj.precision_m))
|
|
623
|
+
parts.push(`精度: ${obj.precision_m}m`);
|
|
624
|
+
if (typeof obj.map_url === 'string' && obj.map_url)
|
|
625
|
+
parts.push(`地图: ${obj.map_url}`);
|
|
626
|
+
if (text && !parts.includes(text))
|
|
627
|
+
parts.push(text);
|
|
628
|
+
return parts.length > 0 ? parts.join('\n') : text || JSON.stringify(payload);
|
|
629
|
+
}
|
|
582
630
|
if (typeof obj.text === 'string')
|
|
583
631
|
return text;
|
|
584
632
|
return JSON.stringify(payload);
|
|
@@ -713,8 +761,11 @@ export class AUNChannel {
|
|
|
713
761
|
this.messageSeqMap.delete(messageId);
|
|
714
762
|
}
|
|
715
763
|
shouldEncrypt(_peerId) {
|
|
716
|
-
|
|
717
|
-
|
|
764
|
+
return this.config.defaultEncrypt ?? true;
|
|
765
|
+
}
|
|
766
|
+
/** Effective channel default for callers that must persist a concrete transport choice. */
|
|
767
|
+
getDefaultEncrypt() {
|
|
768
|
+
return this.shouldEncrypt(this.config.aid);
|
|
718
769
|
}
|
|
719
770
|
_aid;
|
|
720
771
|
_selfName; // 本地 agent.md 中的 name,首次 connect 时读取
|
|
@@ -884,8 +935,12 @@ export class AUNChannel {
|
|
|
884
935
|
this.store = store;
|
|
885
936
|
const client = await loadClient(store, aidName);
|
|
886
937
|
this.client = client;
|
|
887
|
-
//
|
|
888
|
-
//
|
|
938
|
+
// fastaun gives a preset in-memory gateway precedence over its metadata
|
|
939
|
+
// cache and AID discovery. authenticate({ gateway }) is deliberately
|
|
940
|
+
// rejected by its public API, so set the documented client preset before
|
|
941
|
+
// authentication instead.
|
|
942
|
+
if (configuredGateway)
|
|
943
|
+
client._gatewayUrl = configuredGateway;
|
|
889
944
|
this.gatewayUrl = configuredGateway;
|
|
890
945
|
// Register event handlers before connecting
|
|
891
946
|
client.on('message.received', (data) => {
|
|
@@ -1138,13 +1193,10 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1138
1193
|
await this.callAndTrace('message.send', {
|
|
1139
1194
|
to: owner,
|
|
1140
1195
|
payload: { type: 'text', text: welcomeText },
|
|
1141
|
-
encrypt:
|
|
1196
|
+
encrypt: this.shouldEncrypt(owner),
|
|
1142
1197
|
persist_required: true,
|
|
1143
1198
|
});
|
|
1144
1199
|
logger.info(`${this.logPrefix()} Welcome message sent to owner: ${owner}`);
|
|
1145
|
-
// Send binding credential for Evol App to persist locally
|
|
1146
|
-
// active_baseagent 经 config-scope 解析。
|
|
1147
|
-
await this.sendBindingCredential(owner, agentDisplayName, activeBaseagent(aidName)).catch(e => logger.warn(`${this.logPrefix()} Binding credential failed: ${e}`));
|
|
1148
1200
|
// Mark agent as initialized in config.json (replaces old agent.md frontmatter flag)
|
|
1149
1201
|
try {
|
|
1150
1202
|
const fresh = loadAgent(aidName);
|
|
@@ -1162,17 +1214,6 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1162
1214
|
logger.warn(`${this.logPrefix()} Failed to send welcome message: ${e}`);
|
|
1163
1215
|
}
|
|
1164
1216
|
}
|
|
1165
|
-
async sendBindingCredential(owner, name, baseagent) {
|
|
1166
|
-
if (!this.client)
|
|
1167
|
-
return;
|
|
1168
|
-
await this.callAndTrace('message.send', {
|
|
1169
|
-
to: owner,
|
|
1170
|
-
payload: { type: 'binding', aid: this.config.aid, name, owner, baseagent },
|
|
1171
|
-
encrypt: true,
|
|
1172
|
-
persist_required: true,
|
|
1173
|
-
});
|
|
1174
|
-
logger.info(`${this.logPrefix()} Binding credential sent to owner: ${owner}`);
|
|
1175
|
-
}
|
|
1176
1217
|
// ── Event handlers ──────────────────────────────────────────
|
|
1177
1218
|
/**
|
|
1178
1219
|
* 统一处理入站附件:下载 → 图片识别+base64 注入 → 拼接文本。
|
|
@@ -1364,24 +1405,24 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1364
1405
|
return null;
|
|
1365
1406
|
}
|
|
1366
1407
|
isTrustedStorageHost(host, normalizedOwner) {
|
|
1367
|
-
const
|
|
1368
|
-
// 对端
|
|
1369
|
-
const
|
|
1370
|
-
if (
|
|
1371
|
-
|
|
1372
|
-
// 本端
|
|
1373
|
-
const
|
|
1374
|
-
if (
|
|
1375
|
-
|
|
1376
|
-
// 校验 host 是否为任一可信
|
|
1377
|
-
for (const
|
|
1378
|
-
if (host === `storage.${
|
|
1408
|
+
const trustedAidDomains = new Set();
|
|
1409
|
+
// 对端 AID domain(文件所有者 owner_aid)
|
|
1410
|
+
const peerAidDomain = this.extractAidDomain(normalizedOwner);
|
|
1411
|
+
if (peerAidDomain)
|
|
1412
|
+
trustedAidDomains.add(peerAidDomain);
|
|
1413
|
+
// 本端 AID domain(自己的 AID)
|
|
1414
|
+
const selfAidDomain = this.extractAidDomain((this.getAid() || '').toLowerCase());
|
|
1415
|
+
if (selfAidDomain)
|
|
1416
|
+
trustedAidDomains.add(selfAidDomain);
|
|
1417
|
+
// 校验 host 是否为任一可信 AID domain 的存储域名
|
|
1418
|
+
for (const aidDomain of trustedAidDomains) {
|
|
1419
|
+
if (host === `storage.${aidDomain}`)
|
|
1379
1420
|
return true;
|
|
1380
1421
|
}
|
|
1381
1422
|
return false;
|
|
1382
1423
|
}
|
|
1383
|
-
/** 从 AID
|
|
1384
|
-
|
|
1424
|
+
/** 从 AID 提取后缀 domain(去掉首段 label)。`mybot.example.com` → `example.com` */
|
|
1425
|
+
extractAidDomain(aid) {
|
|
1385
1426
|
if (!aid || !aid.includes('.'))
|
|
1386
1427
|
return '';
|
|
1387
1428
|
return aid.split('.').slice(1).join('.');
|
|
@@ -1921,7 +1962,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1921
1962
|
//
|
|
1922
1963
|
// observable=true 时,Agent 收发的每条 AUN 消息(原始信封 + 解密后明文
|
|
1923
1964
|
// payload)镜像一份给 owners[]。入站在所有过滤之前转发;出站在真实发送
|
|
1924
|
-
//
|
|
1965
|
+
// 成功后转发。Observer 使用 daemon 的全局 AUN 默认加密设置,业务合同保持不变。
|
|
1925
1966
|
// observable / owners 不在此处缓存——由 daemon 注入 resolver,从 EvolAgent 的
|
|
1926
1967
|
// in-memory merged config(启动/重启/热重载时统一更新的唯一缓存)读取,避免重复缓存。
|
|
1927
1968
|
observerConfigResolver;
|
|
@@ -1984,7 +2025,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1984
2025
|
this.emitForward('outbound', result, recipientOwners);
|
|
1985
2026
|
}
|
|
1986
2027
|
/**
|
|
1987
|
-
* 实际投递 observer.forward 给每个 owner
|
|
2028
|
+
* 实际投递 observer.forward 给每个 owner,使用 daemon 的全局 AUN 默认加密设置。
|
|
1988
2029
|
* original 为 SDK 给到的原始对象(入站回调 data / 出站 SendResult),整体透传,
|
|
1989
2030
|
* 不挑字段、不改字段——SDK 加任何字段都会自动一并转发给 owner。
|
|
1990
2031
|
*/
|
|
@@ -1995,9 +2036,10 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1995
2036
|
agent_aid: this.config.aid,
|
|
1996
2037
|
original,
|
|
1997
2038
|
};
|
|
2039
|
+
const encrypt = this.shouldEncrypt('observer.forward');
|
|
1998
2040
|
for (const ownerAid of owners) {
|
|
1999
|
-
this.callAndTrace('message.send', { to: ownerAid, payload: forwardPayload, encrypt
|
|
2000
|
-
.catch(e => logger.
|
|
2041
|
+
this.callAndTrace('message.send', { to: ownerAid, payload: forwardPayload, encrypt })
|
|
2042
|
+
.catch(e => logger.warn(`${this.logPrefix()} observer.forward send to ${ownerAid} failed: ${e}`));
|
|
2001
2043
|
}
|
|
2002
2044
|
}
|
|
2003
2045
|
// ── 观察者插话(Observer Insert,v0.3 待用上下文提示) ──────────────
|
|
@@ -2007,7 +2049,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2007
2049
|
// (不 dispatch、不跑 LLM、不回 owner);下一条对端消息到达时由 message-processor
|
|
2008
2050
|
// 回放消费、注入渲染层。action=add 加提示 / remove 撤销。
|
|
2009
2051
|
// 详见 docs/observer-insert-design.md 第一部分。
|
|
2010
|
-
/** 回 observer.inject.ack 给 owner
|
|
2052
|
+
/** 回 observer.inject.ack 给 owner;加密使用 daemon 的全局 AUN 默认设置。 */
|
|
2011
2053
|
emitInjectAck(ownerAid, injectId, data, error) {
|
|
2012
2054
|
if (!this.connected || !this.client)
|
|
2013
2055
|
return;
|
|
@@ -2018,8 +2060,8 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2018
2060
|
ackPayload.data = data;
|
|
2019
2061
|
if (error)
|
|
2020
2062
|
ackPayload.error = error;
|
|
2021
|
-
this.callAndTrace('message.send', { to: ownerAid, payload: ackPayload, encrypt:
|
|
2022
|
-
.catch(e => logger.
|
|
2063
|
+
this.callAndTrace('message.send', { to: ownerAid, payload: ackPayload, encrypt: this.shouldEncrypt(ownerAid) })
|
|
2064
|
+
.catch(e => logger.warn(`${this.logPrefix()} observer.inject.ack send to ${ownerAid} failed: ${e}`));
|
|
2023
2065
|
}
|
|
2024
2066
|
/** 处理 observer.inject:鉴权 + 校验 + 只落盘到 pending-hints(不触发处理、不回 owner)。 */
|
|
2025
2067
|
handleObserverInject(fromAid, payload, displayName, peerType) {
|
|
@@ -2519,9 +2561,6 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2519
2561
|
}
|
|
2520
2562
|
}
|
|
2521
2563
|
payloadByteLength(payload, logText) {
|
|
2522
|
-
if (payload.type === 'image' && typeof payload.data_base64 === 'string') {
|
|
2523
|
-
return Buffer.byteLength(payload.data_base64, 'utf-8');
|
|
2524
|
-
}
|
|
2525
2564
|
return Buffer.byteLength(logText, 'utf-8');
|
|
2526
2565
|
}
|
|
2527
2566
|
applyReplyContextToPayload(payload, context) {
|
|
@@ -2541,11 +2580,16 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2541
2580
|
const timer = setTimeout(() => this.invalidatedInteractions.delete(interactionId), 24 * 60 * 60 * 1000);
|
|
2542
2581
|
timer.unref?.();
|
|
2543
2582
|
}
|
|
2544
|
-
async recallInteractionCard(messageId) {
|
|
2583
|
+
async recallInteractionCard(messageId, channelId) {
|
|
2545
2584
|
if (!this.client || !this.connected)
|
|
2546
2585
|
return false;
|
|
2547
2586
|
try {
|
|
2548
|
-
|
|
2587
|
+
const isGroup = channelId ? this.isGroupId(channelId) : false;
|
|
2588
|
+
const method = isGroup ? 'group.recall' : 'message.recall';
|
|
2589
|
+
const params = isGroup
|
|
2590
|
+
? { group_id: channelId, message_ids: [messageId] }
|
|
2591
|
+
: { message_ids: [messageId] };
|
|
2592
|
+
await this.callAndTrace(method, params, { silentError: true });
|
|
2549
2593
|
return true;
|
|
2550
2594
|
}
|
|
2551
2595
|
catch (error) {
|
|
@@ -2566,8 +2610,9 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2566
2610
|
}
|
|
2567
2611
|
const messageIds = [...(this.interactionCardMessageIds.get(interactionId) ?? [])];
|
|
2568
2612
|
for (const messageId of messageIds) {
|
|
2613
|
+
const channelId = this.cardMessageIdMap.get(messageId)?.channelId;
|
|
2569
2614
|
this.forgetInteractionCard(messageId, interactionId);
|
|
2570
|
-
await this.recallInteractionCard(messageId);
|
|
2615
|
+
await this.recallInteractionCard(messageId, channelId);
|
|
2571
2616
|
}
|
|
2572
2617
|
}
|
|
2573
2618
|
forgetInteractionCard(messageId, interactionId) {
|
|
@@ -2577,13 +2622,14 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2577
2622
|
if (ids && ids.size === 0)
|
|
2578
2623
|
this.interactionCardMessageIds.delete(interactionId);
|
|
2579
2624
|
}
|
|
2580
|
-
registerCardPostSend(messageId, action) {
|
|
2625
|
+
registerCardPostSend(messageId, action, channelId) {
|
|
2581
2626
|
if (action.type !== 'register_interaction_card')
|
|
2582
2627
|
return;
|
|
2583
2628
|
this.cardMessageIdMap.set(messageId, {
|
|
2584
2629
|
requestId: action.requestId,
|
|
2585
2630
|
isCommandCard: action.isCommandCard,
|
|
2586
2631
|
initiatorAid: action.initiatorAid,
|
|
2632
|
+
channelId,
|
|
2587
2633
|
});
|
|
2588
2634
|
this.ownedCardMsgIds.add(messageId);
|
|
2589
2635
|
let messageIds = this.interactionCardMessageIds.get(action.requestId);
|
|
@@ -2595,7 +2641,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2595
2641
|
const now = Date.now();
|
|
2596
2642
|
const mapTtl = action.expiresAt && action.expiresAt > now
|
|
2597
2643
|
? action.expiresAt - now
|
|
2598
|
-
:
|
|
2644
|
+
: AUN_INTERACTION_CARD_TTL_MS;
|
|
2599
2645
|
const mapTimer = setTimeout(() => {
|
|
2600
2646
|
this.cardMessageIdMap.delete(messageId);
|
|
2601
2647
|
const ids = this.interactionCardMessageIds.get(action.requestId);
|
|
@@ -2609,14 +2655,14 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2609
2655
|
const invalidationReason = this.invalidatedInteractions.get(action.requestId);
|
|
2610
2656
|
if (invalidationReason) {
|
|
2611
2657
|
this.cardMessageIdMap.delete(messageId);
|
|
2612
|
-
void this.recallInteractionCard(messageId);
|
|
2658
|
+
void this.recallInteractionCard(messageId, channelId);
|
|
2613
2659
|
}
|
|
2614
2660
|
}
|
|
2615
2661
|
runPostSend(entry, messageId) {
|
|
2616
2662
|
if (!entry.postSend)
|
|
2617
2663
|
return;
|
|
2618
2664
|
if (entry.postSend.type === 'register_interaction_card') {
|
|
2619
|
-
this.registerCardPostSend(messageId, entry.postSend);
|
|
2665
|
+
this.registerCardPostSend(messageId, entry.postSend, entry.channelId);
|
|
2620
2666
|
}
|
|
2621
2667
|
}
|
|
2622
2668
|
async sendAunPayload(channelId, payload, context, label) {
|
|
@@ -2931,7 +2977,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2931
2977
|
finalPayload._evolcore_causation_ref = causationRef;
|
|
2932
2978
|
registerAunCausation(causationRef, this.config.aid, args.to, outboundCausation);
|
|
2933
2979
|
}
|
|
2934
|
-
const encrypt = args.encrypt
|
|
2980
|
+
const encrypt = args.encrypt ?? this.shouldEncrypt(args.to);
|
|
2935
2981
|
const sendParams = {
|
|
2936
2982
|
to: args.to,
|
|
2937
2983
|
payload: this.truncatePayloadIfNeeded(finalPayload, 'msg-send-ipc'),
|
|
@@ -3036,7 +3082,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
3036
3082
|
const finalPayload = this.stripUndefinedDeep({ ...args.payload });
|
|
3037
3083
|
if (args.mentions?.length)
|
|
3038
3084
|
finalPayload.mentions = args.mentions;
|
|
3039
|
-
const encrypt = args.encrypt
|
|
3085
|
+
const encrypt = args.encrypt ?? this.shouldEncrypt(args.groupId);
|
|
3040
3086
|
try {
|
|
3041
3087
|
const result = await this.callAndTrace('group.send', {
|
|
3042
3088
|
group_id: args.groupId,
|
|
@@ -3529,6 +3575,117 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
3529
3575
|
outbox.remove(this.config.aid, entry.id);
|
|
3530
3576
|
}
|
|
3531
3577
|
}
|
|
3578
|
+
async sendImage(channelId, data, mimeType, alt, context) {
|
|
3579
|
+
if (!Buffer.isBuffer(data)) {
|
|
3580
|
+
throw new Error('result.image data must be a Buffer');
|
|
3581
|
+
}
|
|
3582
|
+
if (data.length === 0) {
|
|
3583
|
+
throw new Error('result.image data cannot be empty');
|
|
3584
|
+
}
|
|
3585
|
+
if (data.length > MAX_AUN_ATTACHMENT_SIZE) {
|
|
3586
|
+
throw new Error(`result.image is too large (${formatSize(data.length)}, max ${formatSize(MAX_AUN_ATTACHMENT_SIZE)})`);
|
|
3587
|
+
}
|
|
3588
|
+
let normalizedMimeType = normalizeImageMimeType(mimeType);
|
|
3589
|
+
if (!normalizedMimeType) {
|
|
3590
|
+
const { default: imageType } = await import('image-type');
|
|
3591
|
+
const detected = await imageType(data).catch(() => undefined);
|
|
3592
|
+
normalizedMimeType = detected?.mime;
|
|
3593
|
+
if (!normalizedMimeType) {
|
|
3594
|
+
throw new Error('result.image requires a valid image MIME type or recognizable image data');
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
const logText = alt ? `[image] ${alt}` : '[image]';
|
|
3598
|
+
const entry = outbox.enqueue(this.config.aid, {
|
|
3599
|
+
channelId,
|
|
3600
|
+
type: 'image',
|
|
3601
|
+
contentKind: 'image',
|
|
3602
|
+
image: { dataBase64: data.toString('base64'), mimeType: normalizedMimeType, alt },
|
|
3603
|
+
context,
|
|
3604
|
+
logText,
|
|
3605
|
+
});
|
|
3606
|
+
logger.debug(`${this.logPrefix()} Outbox enqueued image: id=${entry.id} channel=${channelId} bytes=${data.length}`);
|
|
3607
|
+
if (!this.connected || !this.client) {
|
|
3608
|
+
logger.warn(`${this.logPrefix()} Not connected, image send queued in outbox (id=${entry.id}). Triggering reconnect.`);
|
|
3609
|
+
if (!this.reconnectTimer && !this.client) {
|
|
3610
|
+
this.initClient().catch(e => logger.error(`${this.logPrefix()} Reconnect from sendImage failed: ${e}`));
|
|
3611
|
+
}
|
|
3612
|
+
return;
|
|
3613
|
+
}
|
|
3614
|
+
const ok = await this.withOutboxInFlight(entry, () => this.deliverImageEntry(entry), false);
|
|
3615
|
+
if (ok)
|
|
3616
|
+
outbox.remove(this.config.aid, entry.id);
|
|
3617
|
+
}
|
|
3618
|
+
async buildUploadedImagePayload(data, mimeType, alt) {
|
|
3619
|
+
if (!this.connected || !this.client) {
|
|
3620
|
+
throw new Error('AUN channel is not connected; image cannot be uploaded');
|
|
3621
|
+
}
|
|
3622
|
+
let contentType = normalizeImageMimeType(mimeType);
|
|
3623
|
+
let extension;
|
|
3624
|
+
if (!contentType) {
|
|
3625
|
+
const { default: imageType } = await import('image-type');
|
|
3626
|
+
const detected = await imageType(data).catch(() => undefined);
|
|
3627
|
+
contentType = detected?.mime;
|
|
3628
|
+
extension = detected?.ext;
|
|
3629
|
+
}
|
|
3630
|
+
if (!contentType) {
|
|
3631
|
+
throw new Error('result.image requires a valid image MIME type or recognizable image data');
|
|
3632
|
+
}
|
|
3633
|
+
if (!extension) {
|
|
3634
|
+
const subtype = contentType.slice('image/'.length);
|
|
3635
|
+
extension = subtype === 'jpeg'
|
|
3636
|
+
? 'jpg'
|
|
3637
|
+
: subtype === 'svg+xml'
|
|
3638
|
+
? 'svg'
|
|
3639
|
+
: subtype.replace(/[^a-z0-9]/g, '') || 'img';
|
|
3640
|
+
}
|
|
3641
|
+
const digest = crypto.createHash('sha256').update(data).digest('hex').slice(0, 12);
|
|
3642
|
+
const filename = `image-${digest}.${extension}`;
|
|
3643
|
+
const connection = {
|
|
3644
|
+
call: (method, params) => this.callAndTrace(method, params),
|
|
3645
|
+
close: async () => { },
|
|
3646
|
+
};
|
|
3647
|
+
const built = await uploadBufferAndBuildPayload(connection, this.config.aid, data, filename, { as: 'image', contentType });
|
|
3648
|
+
const imagePayload = { ...built.payload };
|
|
3649
|
+
setIfDefined(imagePayload, 'alt', alt);
|
|
3650
|
+
return imagePayload;
|
|
3651
|
+
}
|
|
3652
|
+
async deliverImageEntry(entry) {
|
|
3653
|
+
const image = entry.image;
|
|
3654
|
+
if (!image || typeof image.dataBase64 !== 'string') {
|
|
3655
|
+
logger.warn(`${this.logPrefix()} deliverImageEntry: missing image data (outbox id=${entry.id})`);
|
|
3656
|
+
return true;
|
|
3657
|
+
}
|
|
3658
|
+
const data = Buffer.from(image.dataBase64, 'base64');
|
|
3659
|
+
if (data.length === 0) {
|
|
3660
|
+
logger.warn(`${this.logPrefix()} deliverImageEntry: invalid image data (outbox id=${entry.id})`);
|
|
3661
|
+
return true;
|
|
3662
|
+
}
|
|
3663
|
+
const imagePayload = await this.buildUploadedImagePayload(data, image.mimeType, image.alt);
|
|
3664
|
+
entry.type = 'payload';
|
|
3665
|
+
entry.contentKind = 'image';
|
|
3666
|
+
entry.payload = this.applyReplyContextToPayload(imagePayload, entry.context);
|
|
3667
|
+
entry.logText ??= image.alt ? `[image] ${image.alt}` : '[image]';
|
|
3668
|
+
delete entry.image;
|
|
3669
|
+
// Persist the attachment reference before message.send. A failed send then
|
|
3670
|
+
// retries the compact wire payload without re-uploading the same image.
|
|
3671
|
+
let payloadEntry = entry;
|
|
3672
|
+
if (!outbox.replace(this.config.aid, entry)) {
|
|
3673
|
+
payloadEntry = outbox.enqueue(this.config.aid, {
|
|
3674
|
+
channelId: entry.channelId,
|
|
3675
|
+
type: 'payload',
|
|
3676
|
+
contentKind: 'image',
|
|
3677
|
+
payload: entry.payload,
|
|
3678
|
+
context: entry.context,
|
|
3679
|
+
logText: entry.logText,
|
|
3680
|
+
ttl: entry.ttl,
|
|
3681
|
+
});
|
|
3682
|
+
}
|
|
3683
|
+
const sent = await this.deliverPayloadEntry(payloadEntry);
|
|
3684
|
+
if (sent.ok && payloadEntry.id !== entry.id) {
|
|
3685
|
+
outbox.remove(this.config.aid, payloadEntry.id);
|
|
3686
|
+
}
|
|
3687
|
+
return sent.ok;
|
|
3688
|
+
}
|
|
3532
3689
|
async deliverFileEntry(entry) {
|
|
3533
3690
|
const channelId = entry.channelId;
|
|
3534
3691
|
const absPath = entry.filePath;
|
|
@@ -3715,6 +3872,9 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
3715
3872
|
else if (entry.type === 'file') {
|
|
3716
3873
|
return this.withOutboxInFlight(entry, () => this.deliverFileEntry(entry), false);
|
|
3717
3874
|
}
|
|
3875
|
+
else if (entry.type === 'image') {
|
|
3876
|
+
return this.withOutboxInFlight(entry, () => this.deliverImageEntry(entry), false);
|
|
3877
|
+
}
|
|
3718
3878
|
else if (entry.type === 'payload') {
|
|
3719
3879
|
const sent = await this.withOutboxInFlight(entry, () => this.deliverPayloadEntry(entry), { ok: false });
|
|
3720
3880
|
return sent.ok;
|
|
@@ -4021,6 +4181,7 @@ export class AUNChannelPlugin {
|
|
|
4021
4181
|
aid,
|
|
4022
4182
|
keystorePath: inst.keystorePath,
|
|
4023
4183
|
gatewayUrl: inst.gatewayUrl,
|
|
4184
|
+
defaultEncrypt: ctx.aunDefaultEncrypt,
|
|
4024
4185
|
accessToken: inst.accessToken,
|
|
4025
4186
|
flushDelay: inst.flushDelay,
|
|
4026
4187
|
agentName: ctx.agentName,
|
|
@@ -4087,16 +4248,7 @@ export class AUNChannelPlugin {
|
|
|
4087
4248
|
return;
|
|
4088
4249
|
}
|
|
4089
4250
|
case 'result.image': {
|
|
4090
|
-
|
|
4091
|
-
const b64 = buf.toString('base64');
|
|
4092
|
-
const imagePayload = { type: 'image', data_base64: b64 };
|
|
4093
|
-
setIfDefined(imagePayload, 'alt', payload.alt);
|
|
4094
|
-
setIfDefined(imagePayload, 'mime_type', payload.mimeType);
|
|
4095
|
-
await channel.sendContentPayload(channelId, imagePayload, {
|
|
4096
|
-
contentKind: 'image',
|
|
4097
|
-
context: replyCtx,
|
|
4098
|
-
logText: payload.alt ? `[image] ${payload.alt}` : '[image]',
|
|
4099
|
-
});
|
|
4251
|
+
await channel.sendImage(channelId, payload.data, payload.mimeType, payload.alt, replyCtx);
|
|
4100
4252
|
return;
|
|
4101
4253
|
}
|
|
4102
4254
|
case 'activity.batch': {
|
|
@@ -4147,7 +4299,7 @@ export class AUNChannelPlugin {
|
|
|
4147
4299
|
return;
|
|
4148
4300
|
case 'interaction': {
|
|
4149
4301
|
const req = payload.interaction;
|
|
4150
|
-
const cardTtlMs =
|
|
4302
|
+
const cardTtlMs = AUN_INTERACTION_CARD_TTL_MS;
|
|
4151
4303
|
if (req.kind.kind === 'action') {
|
|
4152
4304
|
const action = req.kind;
|
|
4153
4305
|
const aunCard = {
|
|
@@ -4204,6 +4356,8 @@ export class AUNChannelPlugin {
|
|
|
4204
4356
|
aunCard.text = card.body;
|
|
4205
4357
|
setIfDefined(aunCard, 'format', card.bodyFormat);
|
|
4206
4358
|
}
|
|
4359
|
+
if (req.initiatorId && channel.isGroupId(channelId))
|
|
4360
|
+
aunCard.initiator = req.initiatorId;
|
|
4207
4361
|
if (replyCtx?.threadId)
|
|
4208
4362
|
aunCard.thread_id = replyCtx.threadId;
|
|
4209
4363
|
await channel.sendContentPayload(channelId, aunCard, {
|
package/dist/cli/aun-commands.js
CHANGED
|
@@ -808,7 +808,7 @@ Options:
|
|
|
808
808
|
--app <name> 指定应用 slot(独立消费通道,不影响 daemon)
|
|
809
809
|
--aun-path <path> 指定 AUN keystore 根
|
|
810
810
|
--format json 输出 JSON 格式
|
|
811
|
-
--encrypt
|
|
811
|
+
--encrypt 强制端到端加密(未指定时使用 daemon 默认值)
|
|
812
812
|
--no-encrypt 强制明文发送(优先于 --encrypt)
|
|
813
813
|
--thread <id> 指定话题 ID(用于多话题路由)
|
|
814
814
|
--session <latest|all|id> 按 EvolCore 逻辑会话过滤历史(默认 latest)
|
|
@@ -1048,9 +1048,10 @@ Options:
|
|
|
1048
1048
|
}
|
|
1049
1049
|
body = { mode: 'text', text };
|
|
1050
1050
|
}
|
|
1051
|
-
//
|
|
1052
|
-
|
|
1053
|
-
|
|
1051
|
+
// 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
|
|
1052
|
+
const encrypt = args.includes('--no-encrypt')
|
|
1053
|
+
? false
|
|
1054
|
+
: args.includes('--encrypt') ? true : undefined;
|
|
1054
1055
|
const thread = getArgValue(args, '--thread');
|
|
1055
1056
|
const returnPolicyRaw = getArgValue(args, '--return');
|
|
1056
1057
|
if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
|
|
@@ -1292,7 +1293,7 @@ Options:
|
|
|
1292
1293
|
--app <name> 指定应用 slot(独立消费通道,不影响 daemon)
|
|
1293
1294
|
--aun-path <path> 指定 AUN keystore 根
|
|
1294
1295
|
--format json 输出 JSON 格式
|
|
1295
|
-
--encrypt
|
|
1296
|
+
--encrypt 强制端到端加密(未指定时使用 daemon 默认值;仅 send)
|
|
1296
1297
|
--no-encrypt 强制明文发送(优先于 --encrypt;仅 send)
|
|
1297
1298
|
--thread <id> 指定话题 ID(仅 send)
|
|
1298
1299
|
--return <none|required> 跨会话发送必填(仅 send;Trigger 只能使用 none)
|
|
@@ -1469,8 +1470,10 @@ Options:
|
|
|
1469
1470
|
body = { mode: 'text', text };
|
|
1470
1471
|
}
|
|
1471
1472
|
const mentions = collectMentions();
|
|
1472
|
-
//
|
|
1473
|
-
const encryptGroup = args.includes('--
|
|
1473
|
+
// 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
|
|
1474
|
+
const encryptGroup = args.includes('--no-encrypt')
|
|
1475
|
+
? false
|
|
1476
|
+
: args.includes('--encrypt') ? true : undefined;
|
|
1474
1477
|
const thread = getArgValue(args, '--thread');
|
|
1475
1478
|
const returnPolicyRaw = getArgValue(args, '--return');
|
|
1476
1479
|
if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
|
package/dist/cli/bench.js
CHANGED
|
@@ -5,9 +5,10 @@ import os from 'os';
|
|
|
5
5
|
import { execFile } from 'child_process';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { aidList, aidCreate } from '../aun/aid/identity.js';
|
|
8
|
-
import {
|
|
8
|
+
import { resolveControlAidDomain } from '../aun/aid/control-aid.js';
|
|
9
9
|
import { msgSend, msgPull } from '../aun/msg/index.js';
|
|
10
10
|
import { getPackageRoot, aunPath as defaultAunPath } from '../paths.js';
|
|
11
|
+
import { loadDaemonConfig } from '../config-store.js';
|
|
11
12
|
import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
|
|
12
13
|
import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
|
|
13
14
|
const execFileAsync = promisify(execFile);
|
|
@@ -476,10 +477,10 @@ Options:
|
|
|
476
477
|
const need = numAids - usableAids.length;
|
|
477
478
|
if (!formatJson)
|
|
478
479
|
console.log(warn(`仅 ${usableAids.length} 个可用,需创建 ${need} 个新 AID`));
|
|
479
|
-
const
|
|
480
|
+
const aidDomain = resolveControlAidDomain(loadDaemonConfig().aun?.defaultAidDomain);
|
|
480
481
|
for (let i = 0; i < need; i++) {
|
|
481
482
|
const hex = crypto.randomBytes(4).toString('hex');
|
|
482
|
-
const newAid = `bench-${hex}.${
|
|
483
|
+
const newAid = `bench-${hex}.${aidDomain}`;
|
|
483
484
|
try {
|
|
484
485
|
await aidCreate(newAid, { aunPath });
|
|
485
486
|
aids.push(newAid);
|