evolcore 0.0.35 → 0.0.37
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 +42 -0
- package/README.md +6 -0
- package/bin/install-codex-managed-hooks.mjs +20 -3
- package/dist/agents/baseagent-availability.js +1 -1
- package/dist/agents/baseagent.js +88 -0
- package/dist/agents/claude-runner.js +59 -12
- package/dist/agents/codex/app-server-client.js +18 -1
- package/dist/agents/codex-runner.js +262 -21
- package/dist/agents/ecagent-runner.js +47 -11
- package/dist/agents/gemini-runner.js +36 -12
- package/dist/aun/aid/client.js +4 -3
- package/dist/aun/aid/control-aid.js +270 -8
- package/dist/aun/aid/identity.js +6 -3
- package/dist/aun/aid/ownership-operation.js +58 -0
- package/dist/aun/aid/store.js +1 -0
- package/dist/aun/group/fs-download.js +67 -2
- package/dist/aun/group/history.js +20 -5
- package/dist/aun/group/operations.js +8 -2
- package/dist/aun/menu/client.js +39 -2
- package/dist/aun/menu/transport.js +1 -1
- package/dist/aun/msg/history.js +43 -4
- package/dist/aun/msg/managed-operation.js +30 -53
- package/dist/aun/msg/p2p.js +51 -15
- package/dist/aun/outbox.js +4 -0
- package/dist/channels/aun.js +260 -73
- package/dist/channels/daemon.js +6 -4
- package/dist/channels/feishu.js +3 -0
- package/dist/cli/agent-command.js +161 -223
- package/dist/cli/agent-create.js +190 -223
- package/dist/cli/agent.js +3 -1
- package/dist/cli/aid-bind-command.js +53 -0
- package/dist/cli/aun-commands.js +384 -91
- package/dist/cli/bench.js +1 -1
- package/dist/cli/cli-argv.js +74 -0
- package/dist/cli/daemon-commands.js +105 -74
- package/dist/cli/diag.js +1 -1
- package/dist/cli/fs-command.js +18 -19
- package/dist/cli/getmeta-command.js +159 -6
- package/dist/cli/index.js +6 -12
- package/dist/cli/init-channel.js +8 -55
- package/dist/cli/init.js +125 -218
- package/dist/cli/queue-command.js +11 -8
- package/dist/cli/restart-monitor.js +177 -85
- package/dist/cli/session-command.js +1 -1
- package/dist/cli/stats.js +7 -5
- package/dist/cli/thread-command.js +103 -30
- package/dist/cli/trigger-command.js +1 -1
- package/dist/cli/watch-msg-diag.js +1 -0
- package/dist/config/access-policy.js +2 -2
- package/dist/config/boot-log.js +14 -11
- package/dist/config/config-field-policy.js +9 -1
- package/dist/config/config-manager.js +176 -90
- package/dist/config/config-operation-service.js +7 -14
- package/dist/config/contact-book-store.js +142 -26
- package/dist/config/contact-book.js +4 -2
- package/dist/config/lifecycle.js +1 -1
- package/dist/config/owner-config.js +96 -0
- package/dist/config/peer-role-resolver.js +12 -18
- package/dist/config/providers-config.js +382 -0
- package/dist/config/providers-import.js +74 -0
- package/dist/config/providers-management.js +328 -0
- package/dist/config/providers.js +22 -0
- package/dist/config/resolved-config-op.js +17 -14
- package/dist/config/snapshot.js +28 -16
- package/dist/config-store.js +18 -14
- package/dist/core/agent-ipc-registration.js +21 -63
- package/dist/core/agent-runtime.js +16 -5
- package/dist/core/auth/agent-delegation.js +199 -25
- package/dist/core/auth/auth-gateway.js +44 -2
- package/dist/core/auth/authorization-denial.js +1 -1
- package/dist/core/auth/debug-context.js +2 -1
- package/dist/core/auth/delegation-authorization.js +2 -2
- package/dist/core/auth/delegation-diagnostics.js +4 -1
- package/dist/core/auth/operation-authorizer.js +10 -1
- package/dist/core/auth/operation-catalog.js +19 -1
- package/dist/core/bootstrap-service.js +43 -20
- package/dist/core/channel-loader.js +0 -1
- package/dist/core/channel-runtime.js +30 -4
- package/dist/core/command/agent-control.js +196 -37
- package/dist/core/command/cli-intent-parser.js +60 -4
- package/dist/core/command/command-handler.js +212 -60
- package/dist/core/command/connect-menu.js +1 -0
- package/dist/core/command/diag-service.js +5 -4
- package/dist/core/command/file-search.js +368 -0
- package/dist/core/command/menu-catalog.js +2 -1
- package/dist/core/command/menu-handler.js +292 -107
- package/dist/core/command/menu-protocol.js +23 -0
- package/dist/core/command/role-menu.js +7 -19
- package/dist/core/command/skill-slash.js +130 -25
- package/dist/core/command/slash-handler.js +101 -53
- package/dist/core/command/topic-slash.js +16 -5
- package/dist/core/daemon-bootstrap.js +7 -1
- package/dist/core/daemon-control.js +19 -1
- package/dist/core/daemon-lifecycle.js +2 -1
- package/dist/core/event-catalog.js +2 -0
- package/dist/core/evolagent-registry.js +13 -2
- package/dist/core/evolagent.js +3 -6
- package/dist/core/handoff/ipc-registration.js +2 -2
- package/dist/core/handoff/runtime.js +40 -6
- package/dist/core/handoff/store.js +1 -0
- package/dist/core/inference/text-inference.js +95 -6
- package/dist/core/ipc-registration.js +43 -24
- package/dist/core/memory/consolidation-context.js +4 -1
- package/dist/core/memory/consolidation.js +25 -14
- package/dist/core/message/aun-ipc-sender.js +296 -88
- package/dist/core/message/aun-request-registry.js +226 -0
- package/dist/core/message/create-status.js +33 -4
- package/dist/core/message/message-bridge.js +62 -13
- package/dist/core/message/message-log.js +0 -1
- package/dist/core/message/message-queue.js +4 -1
- package/dist/core/message/message-utils.js +8 -1
- package/dist/core/message/peer-mode.js +17 -9
- package/dist/core/message/response-engine.js +266 -124
- package/dist/core/message/retry-scheduler.js +11 -8
- package/dist/core/model/catalog-service.js +60 -18
- package/dist/core/model/model-catalog.js +112 -9
- package/dist/core/model/model-fallback.js +94 -26
- package/dist/core/ownership/owner-resolver.js +687 -0
- package/dist/core/permission/approval-gateway.js +196 -62
- package/dist/core/permission/ec-command-parser.js +138 -25
- package/dist/core/permission/filesystem-approval-scope.js +141 -0
- package/dist/core/permission/protected-paths.js +14 -1
- package/dist/core/permission/sandbox-runtime.js +171 -18
- package/dist/core/permission/tool-policy.js +13 -2
- package/dist/core/role/runtime-policy.js +3 -4
- package/dist/core/session/session-idle-monitor.js +10 -8
- package/dist/core/session/session-manager.js +72 -45
- package/dist/core/session/session-mapper.js +18 -7
- package/dist/core/session/session-renew.js +5 -4
- package/dist/core/session/session-title.js +2 -1
- package/dist/core/session/session-turn-coordinator.js +4 -2
- package/dist/core/skill/index-generator.js +2 -16
- package/dist/core/task/task-recovery-service.js +15 -2
- package/dist/core/thread/command-parser.js +28 -13
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +11 -8
- package/dist/core/thread/thread-operation.js +79 -44
- package/dist/core/thread/thread-route.js +54 -6
- package/dist/core/thread/thread-service.js +236 -45
- package/dist/core/thread/topic-id.js +248 -0
- package/dist/eck/kit-renderer.js +1 -1
- package/dist/eck/message-renderer.js +12 -2
- package/dist/index.js +50 -27
- package/dist/ipc.js +59 -6
- package/dist/paths.js +1 -0
- package/dist/product.js +1 -0
- package/dist/response-system/engines/v1/proactive-flow.js +10 -3
- package/dist/stats/db.js +8 -0
- package/dist/stats/writer.js +26 -4
- package/dist/trigger/authorization.js +48 -3
- package/dist/trigger/feedback.js +28 -10
- package/dist/trigger/ipc-service.js +86 -10
- package/dist/trigger/local-files.js +55 -23
- package/dist/trigger/scheduler.js +57 -11
- package/dist/trigger/system-definitions.js +1 -0
- package/dist/trigger/validation.js +44 -15
- package/dist/utils/aid-bind.js +17 -297
- package/dist/utils/avatar-upload.js +16 -4
- package/dist/utils/cross-platform.js +115 -36
- package/dist/utils/ecweb-supervisor.js +1 -1
- package/dist/utils/ecweb-utils.js +8 -1
- package/dist/utils/error-utils.js +44 -6
- package/dist/utils/instance-registry.js +12 -2
- package/dist/utils/npm-ops.js +102 -27
- package/dist/utils/package-version-info.js +72 -27
- package/dist/utils/restart-safety.js +50 -0
- package/dist/utils/upgrade-jobs.js +304 -0
- package/dist/utils/windows-autostart.js +17 -10
- package/kits/docs/INDEX.md +5 -0
- package/kits/docs/aun/ABILITY_CALLING.md +239 -0
- package/kits/docs/evolcore/INDEX.md +14 -3
- package/kits/docs/evolcore/agent-create.md +55 -141
- package/kits/docs/evolcore/agent.md +38 -16
- package/kits/docs/evolcore/aid.md +34 -0
- package/kits/docs/evolcore/config.md +20 -1
- package/kits/docs/evolcore/event.md +2 -2
- package/kits/docs/evolcore/fs.md +18 -2
- package/kits/docs/evolcore/group-collaboration.md +13 -246
- package/kits/docs/evolcore/group.md +2 -1
- package/kits/docs/evolcore/memory-consolidation-batches.md +1 -1
- package/kits/docs/evolcore/menu-protocol.md +65 -1
- package/kits/docs/evolcore/msg.md +64 -2
- package/kits/docs/evolcore/skill.md +86 -0
- package/kits/docs/evolcore/stats.md +6 -0
- package/kits/docs/evolcore/task.md +2 -0
- package/kits/docs/evolcore/thread-chain.md +145 -51
- package/kits/docs/evolcore/trigger.md +48 -3
- package/kits/eck_manifest.json +21 -0
- package/kits/eck_message_manifest.json +4 -4
- package/kits/migrations/migrate-role-config-v5.mjs +20 -7
- package/kits/rules/01-overview.md +2 -1
- package/kits/rules/03-identity.md +3 -1
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/07-memory-and-thread.md +1 -1
- package/kits/schemas/_meta.json +16 -1
- package/kits/schemas/agent-config.schema.13.json +44 -2
- package/kits/schemas/contact-book.schema.3.json +5 -0
- package/kits/schemas/daemon.schema.6.json +3 -1
- package/kits/schemas/daemon.schema.8.json +329 -0
- package/kits/schemas/defaults.schema.5.json +39 -3
- package/kits/schemas/providers.schema.1.json +76 -0
- package/kits/schemas/relation-config.schema.9.json +5 -1
- package/kits/skills/.switches.json +28 -0
- package/kits/skills/aid-ability/SKILL.md +214 -0
- package/kits/skills/ec-agent-create/SKILL.md +162 -0
- package/kits/skills/ec-group/SKILL.md +2 -1
- package/kits/skills/ec-group-collaboration/SKILL.md +228 -0
- package/kits/skills/ec-identity/SKILL.md +143 -0
- package/kits/skills/ec-skill/scripts/cli.mjs +36 -3
- package/kits/skills/ec-skill/scripts/skill.mjs +202 -15
- package/kits/skills/ec-trigger/SKILL.md +167 -0
- package/kits/skills/ec-trigger/references/examples.md +153 -0
- package/kits/skills/thread-ops/SKILL.md +108 -420
- package/kits/templates/message-fragments/thread-context.md +1 -2
- package/kits/templates/message-fragments/trigger-thread-check.md +1 -1
- package/kits/templates/roles/member.json +1 -1
- package/kits/templates/roles/visitor.json +1 -0
- package/kits/templates/system-fragments/bootstrap.md +1 -0
- package/kits/templates/system-fragments/channel.md +2 -1
- package/kits/templates/system-fragments/commands.md +5 -4
- package/kits/templates/system-fragments/identity.md +2 -0
- package/kits/templates/system-fragments/session.md +1 -1
- package/kits/templates/system-fragments/venue.md +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 话题身份。
|
|
3
|
+
*
|
|
4
|
+
* 话题是双边的:同一个话题在本端和对端各有一个会话。话题在创建时获得一个
|
|
5
|
+
* 双方共享的全局唯一 id(`thread-…`),因此 id 自身就能定位话题。主话题没有
|
|
6
|
+
* 创建动作、没有生成 id,它的身份完全由"本端 + 对端"这条关系决定,所以用
|
|
7
|
+
* 两个 AID 拼成一个与话题并列的 id:
|
|
8
|
+
*
|
|
9
|
+
* main:<aidA>:<aidB>
|
|
10
|
+
*
|
|
11
|
+
* 两端各自算出的字符串必须一致,因此格式化时按字典序排序;解析时两种顺序
|
|
12
|
+
* 都接受并归一到规范顺序,即 `main:<对端>:<本端>` 与 `main:<本端>:<对端>`
|
|
13
|
+
* 等价。
|
|
14
|
+
*
|
|
15
|
+
* 主话题 id 是**身份**,不是线上字段:信封本身已钉死收发双方,发出去只会让
|
|
16
|
+
* 对端凭空建出一个叫 `main:…` 的话题。它只用于本端寻址、持久化与展示。
|
|
17
|
+
*/
|
|
18
|
+
export const MAIN_TOPIC_PREFIX = 'main:';
|
|
19
|
+
/**
|
|
20
|
+
* AID 段:不含 `:` 与 `/`,至少两级域名。
|
|
21
|
+
*
|
|
22
|
+
* 不能用 `isValidAid`:它要求三级以上,而群 AID(`g-xxx.agentid.cn`)只有两级。
|
|
23
|
+
* 话题的对端既可能是私聊 AID 也可能是群 AID,这里只做结构校验。
|
|
24
|
+
*/
|
|
25
|
+
function isTopicAidSegment(value) {
|
|
26
|
+
const labels = value.split('.');
|
|
27
|
+
if (labels.length < 2)
|
|
28
|
+
return false;
|
|
29
|
+
return labels.every(label => /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label));
|
|
30
|
+
}
|
|
31
|
+
/** 统一输入形态:去空白与 `@` 前缀。不做域名展开、不改大小写。 */
|
|
32
|
+
export function normalizeTopicAid(value) {
|
|
33
|
+
return String(value ?? '').trim().replace(/^@/, '');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 由关系两端生成规范主话题 id。
|
|
37
|
+
*
|
|
38
|
+
* 排序保证两端独立计算得到同一个字符串;这也是"换个位置就一致"的实现方式,
|
|
39
|
+
* 而不是依赖调用方传对顺序。
|
|
40
|
+
*/
|
|
41
|
+
export function formatMainTopicId(aidA, aidB) {
|
|
42
|
+
const a = normalizeTopicAid(aidA);
|
|
43
|
+
const b = normalizeTopicAid(aidB);
|
|
44
|
+
if (!isTopicAidSegment(a) || !isTopicAidSegment(b)) {
|
|
45
|
+
throw new Error(`Invalid AID for main topic: ${JSON.stringify(aidA)}, ${JSON.stringify(aidB)}`);
|
|
46
|
+
}
|
|
47
|
+
const [lo, hi] = a <= b ? [a, b] : [b, a];
|
|
48
|
+
return `${MAIN_TOPIC_PREFIX}${lo}:${hi}`;
|
|
49
|
+
}
|
|
50
|
+
export function isMainTopicId(value) {
|
|
51
|
+
if (typeof value !== 'string' || !value.startsWith(MAIN_TOPIC_PREFIX))
|
|
52
|
+
return false;
|
|
53
|
+
const parts = value.slice(MAIN_TOPIC_PREFIX.length).split(':');
|
|
54
|
+
return parts.length === 2 && parts.every(isTopicAidSegment);
|
|
55
|
+
}
|
|
56
|
+
/** 解析主话题 id;两种书写顺序都接受,返回去重后的两端(不保证顺序)。 */
|
|
57
|
+
export function parseMainTopicId(value) {
|
|
58
|
+
if (!isMainTopicId(value))
|
|
59
|
+
return undefined;
|
|
60
|
+
const [aidA, aidB] = value.slice(MAIN_TOPIC_PREFIX.length).split(':');
|
|
61
|
+
return { aidA, aidB };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 主话题 id 是否属于 `self`,是则返回对端。
|
|
65
|
+
*
|
|
66
|
+
* 这是主话题唯一的合法性判据:会话两端之外的人拿到这个 id 必须失败关闭,
|
|
67
|
+
* 不能"猜一个对端"。
|
|
68
|
+
*/
|
|
69
|
+
export function mainTopicPeer(topicId, selfAid) {
|
|
70
|
+
const parsed = parseMainTopicId(topicId);
|
|
71
|
+
if (!parsed)
|
|
72
|
+
return undefined;
|
|
73
|
+
const self = normalizeTopicAid(selfAid);
|
|
74
|
+
if (parsed.aidA === self)
|
|
75
|
+
return parsed.aidB;
|
|
76
|
+
if (parsed.aidB === self)
|
|
77
|
+
return parsed.aidA;
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
/** 校验并归一到规范顺序;不是主话题 id 或含非法段时返回 undefined。 */
|
|
81
|
+
export function canonicalizeMainTopicId(value) {
|
|
82
|
+
const parsed = parseMainTopicId(value);
|
|
83
|
+
if (!parsed)
|
|
84
|
+
return undefined;
|
|
85
|
+
return formatMainTopicId(parsed.aidA, parsed.aidB);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 宽松版:任一侧不是合法 AID 段时返回 undefined 而不是抛错。
|
|
89
|
+
*
|
|
90
|
+
* 会话文件读取路径会碰到内部对端(`bg:` / `trigger:` / `daemon:` 等)与
|
|
91
|
+
* 非 AUN 渠道,那里不能因为拼不出主话题 id 就中断读取。
|
|
92
|
+
*/
|
|
93
|
+
export function safeFormatMainTopicId(aidA, aidB) {
|
|
94
|
+
if (!aidA || !aidB)
|
|
95
|
+
return undefined;
|
|
96
|
+
try {
|
|
97
|
+
return formatMainTopicId(aidA, aidB);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 该 threadId 是否表示"主话题"(本端会话视角)。
|
|
105
|
+
*
|
|
106
|
+
* `''` 是历史落盘形态,`'main'` 是更早的哨兵值,`main:<a>:<b>` 是现行规范形态。
|
|
107
|
+
* 三者都表示主话题;任何需要区分"主话题 / 话题"的地方都必须用它,不能再用
|
|
108
|
+
* 真假判断——规范形态非空,真假判断会把主话题当成话题。
|
|
109
|
+
*/
|
|
110
|
+
export function isMainSessionThreadId(value) {
|
|
111
|
+
if (value === undefined || value === null || value === '')
|
|
112
|
+
return true;
|
|
113
|
+
if (typeof value !== 'string')
|
|
114
|
+
return false;
|
|
115
|
+
return value === 'main' || isMainTopicId(value);
|
|
116
|
+
}
|
|
117
|
+
/** 该 threadId 是否表示话题(真正独立的话题会话)。同时作为类型谓词使用。 */
|
|
118
|
+
export function isTopicThreadId(value) {
|
|
119
|
+
return typeof value === 'string' && value !== '' && !isMainSessionThreadId(value);
|
|
120
|
+
}
|
|
121
|
+
/** 别名:旧代码中广泛使用的 isSubTopicThreadId,语义与 isTopicThreadId 完全一致。 */
|
|
122
|
+
export const isSubTopicThreadId = isTopicThreadId;
|
|
123
|
+
/**
|
|
124
|
+
* 把任意 threadId 形态(`''` / null / `'main'` / `main:<a>:<b>` / 话题 id)归一。
|
|
125
|
+
*
|
|
126
|
+
* `selfAid` / `peerId` 用于给历史形态(空串、`'main'`)补出规范主话题 id;
|
|
127
|
+
* 原值已是规范主话题 id 时以原值为准(归一到规范顺序)。
|
|
128
|
+
*/
|
|
129
|
+
export function classifyThreadId(value, selfAid, peerId) {
|
|
130
|
+
if (isTopicThreadId(value))
|
|
131
|
+
return { kind: 'topic', threadId: value };
|
|
132
|
+
if (typeof value === 'string' && isMainTopicId(value)) {
|
|
133
|
+
return { kind: 'main', topicId: canonicalizeMainTopicId(value) };
|
|
134
|
+
}
|
|
135
|
+
return { kind: 'main', topicId: safeFormatMainTopicId(selfAid, peerId) };
|
|
136
|
+
}
|
|
137
|
+
/** switch 穷尽兜底:新增 kind 而调用方未处理时编译失败。 */
|
|
138
|
+
export function assertNeverThreadKind(value) {
|
|
139
|
+
throw new Error(`Unhandled thread kind: ${JSON.stringify(value)}`);
|
|
140
|
+
}
|
|
141
|
+
export function sessionThreadKind(session) {
|
|
142
|
+
return classifyThreadId(session.rawThreadId, session.selfAID, session.channelId);
|
|
143
|
+
}
|
|
144
|
+
/** 话题会话返回话题 id,主会话返回 undefined。用于线上 thread_id、话题屏障、getThreadSession 等话题专属路径。 */
|
|
145
|
+
export function sessionTopicThreadId(session) {
|
|
146
|
+
if (!session)
|
|
147
|
+
return undefined;
|
|
148
|
+
const k = sessionThreadKind(session);
|
|
149
|
+
return k.kind === 'topic' ? k.threadId : undefined;
|
|
150
|
+
}
|
|
151
|
+
/** 本端身份:话题返回话题 id,主会话返回规范主话题 id(拼不出时 undefined)。用于日志、展示、localTopicId。 */
|
|
152
|
+
export function sessionLocalTopicId(session) {
|
|
153
|
+
if (!session)
|
|
154
|
+
return undefined;
|
|
155
|
+
const k = sessionThreadKind(session);
|
|
156
|
+
return k.kind === 'topic' ? k.threadId : k.topicId;
|
|
157
|
+
}
|
|
158
|
+
// 两者都返回 boolean 而非类型谓词:谓词会把 false 分支收窄成 never,
|
|
159
|
+
// 而"不是话题"的会话仍是会话。需要非空收窄时调用方自己写 `s && isMainSession(s)`。
|
|
160
|
+
export function isTopicSession(session) {
|
|
161
|
+
return sessionTopicThreadId(session) !== undefined;
|
|
162
|
+
}
|
|
163
|
+
/** 非空且为主会话。session 为空时返回 false(不是"话题"也不是"主会话")。 */
|
|
164
|
+
export function isMainSession(session) {
|
|
165
|
+
return !!session && !isTopicSession(session);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 解析话题引用。
|
|
169
|
+
*
|
|
170
|
+
* 规范形态只有两种:`main:<aid>:<aid>` 与裸 `thread-…`。
|
|
171
|
+
* 裸 `main` 一律拒绝——没有对端就无法确定发给谁,系统不做"默认当前对端"的补全。
|
|
172
|
+
* 历史写法 `<peer>/<id>` 仍可解析(它已在多处命令中存在),但主话题的
|
|
173
|
+
* `<peer>/main` 从未实现过,直接拒绝并指向新形态。
|
|
174
|
+
*
|
|
175
|
+
* 裸值是按形态区分的:形如 AID(至少两级、只含域名安全字符)的值视为**主话题的对端**,
|
|
176
|
+
* 解析成 `main:<该AID>:<self>`;其他裸值是话题 id。这个歧义无法彻底消除,但两种
|
|
177
|
+
* 形态的字符集不重叠(话题 id 是 `thread-…`,不含点),按 AID 结构判断是安全的。
|
|
178
|
+
*/
|
|
179
|
+
export function resolveThreadRef(ref, selfAid) {
|
|
180
|
+
const raw = String(ref ?? '').trim();
|
|
181
|
+
if (!raw)
|
|
182
|
+
return { kind: 'current' };
|
|
183
|
+
if (raw === 'current')
|
|
184
|
+
return { kind: 'current' };
|
|
185
|
+
if (isMainTopicId(raw)) {
|
|
186
|
+
const peer = mainTopicPeer(raw, selfAid);
|
|
187
|
+
if (!peer) {
|
|
188
|
+
return {
|
|
189
|
+
kind: 'invalid',
|
|
190
|
+
error: `主话题 ${raw} 不属于当前本端 ${normalizeTopicAid(selfAid)}——主话题 id 由本端与对端共同构成`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const topicId = canonicalizeMainTopicId(raw) ?? raw;
|
|
194
|
+
return { kind: 'main', topicId, peer };
|
|
195
|
+
}
|
|
196
|
+
if (raw === 'main') {
|
|
197
|
+
return {
|
|
198
|
+
kind: 'invalid',
|
|
199
|
+
error: '裸 main 不是可用的话题 id:主话题必须写明双方,形如 main:<对端AID>:<本端AID>',
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const slash = raw.lastIndexOf('/');
|
|
203
|
+
if (slash >= 0) {
|
|
204
|
+
const peer = raw.slice(0, slash);
|
|
205
|
+
const rest = raw.slice(slash + 1);
|
|
206
|
+
if (rest === 'main') {
|
|
207
|
+
return {
|
|
208
|
+
kind: 'invalid',
|
|
209
|
+
error: `<对端>/main 不是话题 id:主话题请用 main:<对端AID>:<本端AID>(如 ec thread list 输出所示)`,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (!peer || !rest) {
|
|
213
|
+
return { kind: 'invalid', error: `无效的话题引用: ${raw}` };
|
|
214
|
+
}
|
|
215
|
+
return { kind: 'thread', threadId: rest, peer };
|
|
216
|
+
}
|
|
217
|
+
// 裸对端 AID → 该关系的主话题(`ec thread rename <peer>` 等历史写法的语义)。
|
|
218
|
+
// self 缺失时无法拼出主话题 id,仍按话题 id 处理,由调用方报"不存在"。
|
|
219
|
+
const self = normalizeTopicAid(selfAid);
|
|
220
|
+
if (self && isTopicAidSegment(raw)) {
|
|
221
|
+
const topicId = formatMainTopicId(self, raw);
|
|
222
|
+
return { kind: 'main', topicId, peer: raw };
|
|
223
|
+
}
|
|
224
|
+
return { kind: 'thread', threadId: raw };
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* history 类命令 `--thread` 值的归一:接受 `ec thread list` 打印的展示形态 `<peer>/<id>`,
|
|
228
|
+
* 剥掉对端前缀后返回裸 id;其余值原样返回(裸话题 id、`main:<a>:<b>`、`all` 等由调用方
|
|
229
|
+
* 各自校验)。写了前缀时 `samePeer` 必须认可它与本次查询的对端一致,否则拒绝——
|
|
230
|
+
* 不能拿别的对端的话题引用去读当前对端的历史。
|
|
231
|
+
*/
|
|
232
|
+
export function normalizeThreadOptionValue(value, samePeer) {
|
|
233
|
+
const raw = value.trim();
|
|
234
|
+
const slash = raw.lastIndexOf('/');
|
|
235
|
+
if (slash < 0)
|
|
236
|
+
return { ok: true, threadId: raw };
|
|
237
|
+
const peer = raw.slice(0, slash).replace(/^@/, '');
|
|
238
|
+
const threadId = raw.slice(slash + 1);
|
|
239
|
+
if (!peer || !threadId)
|
|
240
|
+
return { ok: false, error: `无效的话题引用: ${raw}` };
|
|
241
|
+
if (threadId === 'main') {
|
|
242
|
+
return { ok: false, error: `<对端>/main 不是话题 id:主话题请用 main:<对端AID>:<本端AID>` };
|
|
243
|
+
}
|
|
244
|
+
if (samePeer && !samePeer(peer)) {
|
|
245
|
+
return { ok: false, error: `话题引用 ${raw} 的对端与查询对象不一致` };
|
|
246
|
+
}
|
|
247
|
+
return { ok: true, threadId, peer };
|
|
248
|
+
}
|
package/dist/eck/kit-renderer.js
CHANGED
|
@@ -233,7 +233,7 @@ const PARAM_DESCRIPTIONS = {
|
|
|
233
233
|
VENUES_DIR: '当前 agent 环境数据目录',
|
|
234
234
|
selfAid: '当前 agent 的 AID',
|
|
235
235
|
selfName: '当前 agent 的显示名',
|
|
236
|
-
lifecycle: '当前 agent 生命周期(created/bootstrapping/active)',
|
|
236
|
+
lifecycle: '当前 agent 生命周期(created/ownerpending/bootstrapping/active)',
|
|
237
237
|
isBootstrapping: '当前 agent 是否处于 bootstrap 首次设定阶段',
|
|
238
238
|
hasPersona: '是否有 persona 内容',
|
|
239
239
|
hasWorkingMemory: '是否有 working memory',
|
|
@@ -133,7 +133,7 @@ function renderOneItem(item, sessionVars, sessionCache, contentSentinel) {
|
|
|
133
133
|
injectTime: isOwnerHint
|
|
134
134
|
? formatLocalTime(item.injectTime ?? item.timestamp ?? Date.now(), sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
135
135
|
: undefined,
|
|
136
|
-
// T4:
|
|
136
|
+
// T4: 跨话题上下文(thread-inbox 注入)
|
|
137
137
|
isThreadContext,
|
|
138
138
|
threadContextOriginThreadId: item.threadContext?.originThreadId,
|
|
139
139
|
threadContextOriginPeer: item.threadContext?.originPeer,
|
|
@@ -153,7 +153,9 @@ function renderOneItem(item, sessionVars, sessionCache, contentSentinel) {
|
|
|
153
153
|
const tz = sessionVars.timezone ? String(sessionVars.timezone) : undefined;
|
|
154
154
|
return `${formatLocalTime(g.firstTimestamp, tz)} - ${formatLocalTime(g.lastTimestamp, tz)}`;
|
|
155
155
|
})(),
|
|
156
|
-
|
|
156
|
+
// 信封头的"复查"字段恒出现:复查 Trigger 没建成时显示"无",不能整行省略——
|
|
157
|
+
// 省略时 agent 无从察觉复查缺失(2026-10-20 复查全部静默创建失败即如此)。
|
|
158
|
+
threadContextTriggerId: item.threadContext?.triggerId ?? '无',
|
|
157
159
|
// T9: trigger 消息专属信封变量
|
|
158
160
|
isTriggerMsg,
|
|
159
161
|
triggerMsgId: isTriggerMsg ? item.triggerInfo?.triggerId : undefined,
|
|
@@ -161,6 +163,14 @@ function renderOneItem(item, sessionVars, sessionCache, contentSentinel) {
|
|
|
161
163
|
triggerMsgFireTime: isTriggerMsg && item.triggerInfo?.fireTime !== undefined
|
|
162
164
|
? formatLocalTime(item.triggerInfo.fireTime, sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
163
165
|
: undefined,
|
|
166
|
+
// 跨话题复查信封的"发送于":原消息首次发送时间(labels.firstSentAt,ms 字符串),
|
|
167
|
+
// 与跨话题上下文信封的"发送于"同义、同格式。
|
|
168
|
+
triggerMsgFirstSentTime: (() => {
|
|
169
|
+
const ms = isTriggerMsg ? Number(item.triggerInfo?.labels?.firstSentAt) : NaN;
|
|
170
|
+
return Number.isFinite(ms) && ms > 0
|
|
171
|
+
? formatLocalTime(ms, sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
172
|
+
: undefined;
|
|
173
|
+
})(),
|
|
164
174
|
// T10: labels 路由 key(默认 'default')+ 动态展开 triggerMsgLabel_<key>
|
|
165
175
|
triggerMsgKind: isTriggerMsg ? (item.triggerInfo?.labels?.kind ?? 'default') : undefined,
|
|
166
176
|
...(isTriggerMsg && item.triggerInfo?.labels
|
package/dist/index.js
CHANGED
|
@@ -14,10 +14,12 @@ import { CodexSessionFileAdapter } from './core/session/adapters/codex-session-f
|
|
|
14
14
|
import { GeminiSessionFileAdapter } from './core/session/adapters/gemini-session-file-adapter.js';
|
|
15
15
|
import { EcagentSessionFileAdapter } from './core/session/adapters/ecagent-session-file-adapter.js';
|
|
16
16
|
import { loadDefaults, loadAllAgents, migrateIdentitiesIfNeeded, loadDaemonConfig, initializeEckSnapshotsConfig } from './config-store.js';
|
|
17
|
+
import { inspectClaudeSandboxDependencies, formatClaudeSandboxDependencies } from './core/permission/sandbox-runtime.js';
|
|
17
18
|
import { migrateRelationSharedDirectories } from './core/relation/shared-data.js';
|
|
18
19
|
import { DEFAULT_ECWEB_PORT, ecwebService } from './config/daemon-services.js';
|
|
19
|
-
import { ConfigTarget, onConfigWrite
|
|
20
|
+
import { ConfigTarget, onConfigWrite } from './config/config-manager.js';
|
|
20
21
|
import { expirePendingContactRequests } from './config/contact-request-service.js';
|
|
22
|
+
import { synchronizeOwnershipContactsSync } from './config/contact-book-store.js';
|
|
21
23
|
import { createSessionIdentityResolver } from './config/peer-role-resolver.js';
|
|
22
24
|
import { initializeStartupConfig, prepareStartupConfig, recordStartupConfig } from './config/boot-log.js';
|
|
23
25
|
import { CONFIG_SCHEMA_VERSION } from './types.js';
|
|
@@ -43,6 +45,7 @@ import { readFastaunVersion, readInstalledEvolcoreVersion, reportEvolcoreStartup
|
|
|
43
45
|
import { recoverAllRoleMutationsSync } from './core/command/role-menu.js';
|
|
44
46
|
import { HandoffRuntime } from './core/handoff/runtime.js';
|
|
45
47
|
import { startDaemonControlAid } from './core/daemon-control.js';
|
|
48
|
+
import { ownerResolver, getDaemonOwners } from './core/ownership/owner-resolver.js';
|
|
46
49
|
import { cleanupStartupHandoffs, recoverStartupHandoffs, resumePendingSessions, createDaemonShutdown, daemonConversationTotalExecutionMs, daemonConversationWatchdogMs, daemonIdleTimeoutMs, } from './core/daemon-lifecycle.js';
|
|
47
50
|
import { BootstrapService, createBootstrapCompletionHandler, createBootstrapOwnerBoundHandler } from './core/bootstrap-service.js';
|
|
48
51
|
import { MessageCache } from './core/message/message-cache.js';
|
|
@@ -188,17 +191,19 @@ async function main() {
|
|
|
188
191
|
loadKitManifest();
|
|
189
192
|
// 加载配置(新结构:defaults.json + per-agent config.json)
|
|
190
193
|
const defaults = loadDefaults() ?? { $schema_version: CONFIG_SCHEMA_VERSION };
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
throw new Error('daemon.json.owners is required when EVOLCORE_REQUIRE_OWNERS=1');
|
|
194
|
+
const sandboxDependencies = inspectClaudeSandboxDependencies();
|
|
195
|
+
if (sandboxDependencies.status === 'missing') {
|
|
196
|
+
logger.warn(`[ClaudeSandbox] ${formatClaudeSandboxDependencies(sandboxDependencies)}`);
|
|
195
197
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
if (daemonCfg.aid) {
|
|
199
|
+
ownerResolver.setDaemonAid(daemonCfg.aid);
|
|
200
|
+
ownerResolver.setConfiguredOwners(daemonCfg.aid, [
|
|
201
|
+
daemonCfg.owner,
|
|
202
|
+
...(daemonCfg.owners ?? []),
|
|
203
|
+
].filter((owner) => typeof owner === 'string'));
|
|
201
204
|
}
|
|
205
|
+
const processLevelOwners = getDaemonOwners;
|
|
206
|
+
const bindBootstrapMode = process.env.EVOLCORE_BIND_BOOTSTRAP === '1';
|
|
202
207
|
const paths = resolvePaths();
|
|
203
208
|
// ECWeb has one lifecycle owner: the daemon. The CLI may have started an
|
|
204
209
|
// instance just before spawning us; the supervisor adopts it when healthy,
|
|
@@ -333,16 +338,29 @@ async function main() {
|
|
|
333
338
|
receiverAid: daemonCfg.aid,
|
|
334
339
|
getAvailableBaseagents: detectAvailableBaseagents,
|
|
335
340
|
getUptimeSeconds: () => Math.floor(process.uptime()),
|
|
336
|
-
onDaemonOwnersUpdated: (owners) => { processLevelOwners = owners; },
|
|
337
|
-
onAgentOwnerUpdated: createBootstrapOwnerBoundHandler({
|
|
338
|
-
getService: () => bootstrapService,
|
|
339
|
-
agentRegistry,
|
|
340
|
-
channelInstances,
|
|
341
|
-
eventBus,
|
|
342
|
-
}),
|
|
343
341
|
})
|
|
344
342
|
: null;
|
|
345
343
|
bindService?.startCleanup();
|
|
344
|
+
const onProtocolOwnerBound = createBootstrapOwnerBoundHandler({
|
|
345
|
+
getService: () => bootstrapService, agentRegistry, channelInstances, eventBus,
|
|
346
|
+
});
|
|
347
|
+
let initializationServiceForOwnerRecovery;
|
|
348
|
+
const stopOwnerNotifications = ownerResolver.onChange((subjectAid, ownerAid) => {
|
|
349
|
+
permissionGateway.revalidatePendingApprovals(subjectAid);
|
|
350
|
+
if (agentRegistry.get(subjectAid)) {
|
|
351
|
+
try {
|
|
352
|
+
synchronizeOwnershipContactsSync(subjectAid);
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
logger.warn(`[ownership] Contact role synchronization failed: self=${subjectAid} error=${error instanceof Error ? error.message : String(error)}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (!ownerAid)
|
|
359
|
+
return;
|
|
360
|
+
initializationServiceForOwnerRecovery?.resumeForOwner(subjectAid, ownerAid);
|
|
361
|
+
onProtocolOwnerBound(subjectAid, ownerAid);
|
|
362
|
+
});
|
|
363
|
+
onShutdown(() => { stopOwnerNotifications(); ownerResolver.stop(); });
|
|
346
364
|
const agentDelegationRegistry = new AgentDelegationRegistry();
|
|
347
365
|
// Replace any inherited marker from a parent/previous daemon before child
|
|
348
366
|
// runners or in-process IPC clients are created.
|
|
@@ -424,7 +442,7 @@ async function main() {
|
|
|
424
442
|
processor.setMessageQueue(messageQueue);
|
|
425
443
|
const handoffQueueTtlMs = daemonIdleTimeoutMs(globalSettings);
|
|
426
444
|
const taskExecutionTtlMs = daemonConversationTotalExecutionMs(globalSettings);
|
|
427
|
-
const handoffRuntime = new HandoffRuntime(sessionManager, messageQueue, createAunHandoffSender(sessionManager, channelInstances), undefined, { queueTtlMs: handoffQueueTtlMs });
|
|
445
|
+
const handoffRuntime = new HandoffRuntime(sessionManager, messageQueue, createAunHandoffSender(sessionManager, channelInstances, sessionId => responseEngine.getOutboundDebug(sessionId)), undefined, { queueTtlMs: handoffQueueTtlMs });
|
|
428
446
|
responseEngine.setHandoffRuntime(handoffRuntime);
|
|
429
447
|
cmdHandler.setHandoffRuntime(handoffRuntime);
|
|
430
448
|
// Trigger runtime: daemon-level script + feedback scheduler.
|
|
@@ -471,12 +489,13 @@ async function main() {
|
|
|
471
489
|
projectPath: primaryAgent?.projectPath || process.cwd(),
|
|
472
490
|
};
|
|
473
491
|
cmdHandler.setDaemonTriggerOwner(daemonTriggerOwner.aid, daemonChannel.channelName);
|
|
492
|
+
responseEngine.setDaemonTriggerOwner(daemonTriggerOwner.aid);
|
|
474
493
|
const getTriggerChannel = createTriggerChannelResolver({ agentRegistry, channelInstances, daemonChannel, daemonTriggerOwner });
|
|
475
494
|
const triggerAuthorizationDependencies = {
|
|
476
495
|
agentDelegationRegistry,
|
|
477
496
|
daemonTriggerOwner,
|
|
478
497
|
getAgent: (agentAid) => agentRegistry.get(agentAid),
|
|
479
|
-
getDaemonOwners
|
|
498
|
+
getDaemonOwners,
|
|
480
499
|
getTriggerChannel,
|
|
481
500
|
sessionManager,
|
|
482
501
|
triggerControlToken,
|
|
@@ -490,7 +509,7 @@ async function main() {
|
|
|
490
509
|
});
|
|
491
510
|
};
|
|
492
511
|
const authorizeTriggerExecution = (definition) => (authorizeTriggerRun(definition, {
|
|
493
|
-
getDaemonOwners
|
|
512
|
+
getDaemonOwners,
|
|
494
513
|
}));
|
|
495
514
|
const authenticatedTriggerActor = (agentAid, actorSessionId, delegationToken, delegationCommandHash, controlToken, contextOnly = false) => authenticateTriggerActor(triggerAuthorizationDependencies, agentAid, actorSessionId, delegationToken, delegationCommandHash, controlToken, contextOnly);
|
|
496
515
|
const sendConsolidationFeedback = createConsolidationFeedbackSender((agentAid, channelKey) => {
|
|
@@ -549,7 +568,7 @@ async function main() {
|
|
|
549
568
|
return !!inst && inst.channel.getStatus?.().connected === true;
|
|
550
569
|
};
|
|
551
570
|
cmdHandler.setAgentStorageClientResolver(createAgentStorageClientResolver(channelInstances));
|
|
552
|
-
const msgBridge = new MessageBridge(defaultProjectPath, sessionManager, processor, messageQueue, cmdHandler, eventBus, primaryAgent?.config.debounce,
|
|
571
|
+
const msgBridge = new MessageBridge(defaultProjectPath, sessionManager, processor, messageQueue, cmdHandler, eventBus, primaryAgent?.config.debounce, processLevelOwners);
|
|
553
572
|
msgBridge.setAgentRegistry(agentRegistry);
|
|
554
573
|
msgBridge.setInteractionRouter(interactionRouter);
|
|
555
574
|
msgBridge.setGroupInviteReviewService(groupInviteReviewService);
|
|
@@ -629,7 +648,7 @@ async function main() {
|
|
|
629
648
|
// A failed bind (for example, a stale Windows named pipe) must abort startup
|
|
630
649
|
// without creating a second AUN session that can kick the old daemon.
|
|
631
650
|
let controlChannel;
|
|
632
|
-
const diagService = new DiagService(() => ({ controlAid: loadDaemonConfig().aid, owners:
|
|
651
|
+
const diagService = new DiagService(() => ({ controlAid: loadDaemonConfig().aid, owners: getDaemonOwners() }), async (to, text) => {
|
|
633
652
|
if (!controlChannel)
|
|
634
653
|
throw new Error('Control AID channel is unavailable');
|
|
635
654
|
const result = await controlChannel.sendDaemonMsg({ to, payload: { type: 'text', text }, encrypt: true });
|
|
@@ -647,7 +666,7 @@ async function main() {
|
|
|
647
666
|
runtimeIsDist,
|
|
648
667
|
runtimeBuildIdentity,
|
|
649
668
|
diskDistDir,
|
|
650
|
-
getProcessOwners:
|
|
669
|
+
getProcessOwners: processLevelOwners,
|
|
651
670
|
getAgentRuntimeState: () => agentRuntimeState,
|
|
652
671
|
getAgentRuntimeError: () => agentRuntimeError,
|
|
653
672
|
daemonAid: daemonCfg.aid,
|
|
@@ -722,7 +741,10 @@ async function main() {
|
|
|
722
741
|
resync: coreResyncAgents,
|
|
723
742
|
create: async (options) => {
|
|
724
743
|
const { agentCreateNonInteractive } = await import('./cli/agent-create.js');
|
|
725
|
-
return await agentCreateNonInteractive(options, {
|
|
744
|
+
return await agentCreateNonInteractive(options, {
|
|
745
|
+
hotLoadAgent: coreHotLoadAgent,
|
|
746
|
+
bindOwnerAgent: (aid, ownerAid) => ownerResolver.bind(aid, ownerAid),
|
|
747
|
+
});
|
|
726
748
|
},
|
|
727
749
|
aunAids: () => channelInstances.flatMap(instance => {
|
|
728
750
|
if (instance.channelType !== 'aun')
|
|
@@ -739,9 +761,10 @@ async function main() {
|
|
|
739
761
|
hotLoad: coreHotLoadAgent,
|
|
740
762
|
activate: completeAgentBootstrap,
|
|
741
763
|
});
|
|
764
|
+
initializationServiceForOwnerRecovery = agentInitializationService;
|
|
742
765
|
agentApplicationService.setInitializationService(agentInitializationService);
|
|
743
766
|
cmdHandler.setAgentApplicationService(agentApplicationService);
|
|
744
|
-
ipcServer.setRemoteAccessOwnerProvider(() => processLevelOwners[0]);
|
|
767
|
+
ipcServer.setRemoteAccessOwnerProvider(() => processLevelOwners()[0]);
|
|
745
768
|
cmdHandler.setDaemonMonitorProvider(() => ipcServer.getMonitorSnapshot().snapshot);
|
|
746
769
|
ipcServer.setShutdownExecutor(async (reason) => {
|
|
747
770
|
if (!shutdown) {
|
|
@@ -781,7 +804,7 @@ async function main() {
|
|
|
781
804
|
},
|
|
782
805
|
bindService,
|
|
783
806
|
diagService,
|
|
784
|
-
getProcessOwners:
|
|
807
|
+
getProcessOwners: getDaemonOwners,
|
|
785
808
|
getControlAidState: () => controlChannel?.getAidState?.(),
|
|
786
809
|
daemonAid: daemonCfg.aid,
|
|
787
810
|
triggerControlToken,
|
|
@@ -836,7 +859,7 @@ async function main() {
|
|
|
836
859
|
cmdHandler,
|
|
837
860
|
bindService,
|
|
838
861
|
diagService,
|
|
839
|
-
getProcessOwners:
|
|
862
|
+
getProcessOwners: getDaemonOwners,
|
|
840
863
|
});
|
|
841
864
|
// 统一 channel:health 跨通道通知(仅 auth_error)
|
|
842
865
|
registerChannelHealthNotifications({ eventBus, channelInstances, agentRegistry });
|
package/dist/ipc.js
CHANGED
|
@@ -23,6 +23,8 @@ import { remoteAccessService } from './core/auth/remote-access-store.js';
|
|
|
23
23
|
import { setModelCatalogDaemonOwner } from './core/model/model-catalog.js';
|
|
24
24
|
import { RUNTIME_ENVIRONMENT_NAMES, setRuntimeEnvironmentOverride } from './config/runtime-env.js';
|
|
25
25
|
import { MAIN_CLI_BIN } from './product.js';
|
|
26
|
+
import { ownerResolver } from './core/ownership/owner-resolver.js';
|
|
27
|
+
import { parseOwnershipCommand, executeOwnershipCommand, ownershipFailure } from './aun/aid/ownership-operation.js';
|
|
26
28
|
import { delegationDiagnosticMessage, withDelegationDiagnosticContext, } from './core/auth/delegation-diagnostics.js';
|
|
27
29
|
const isWindows = process.platform === 'win32';
|
|
28
30
|
const isNamedPipe = (p) => isWindows && p.toLowerCase().startsWith('\\\\.\\pipe\\');
|
|
@@ -83,7 +85,7 @@ const MEMORY_COMMAND_ENDPOINTS = new Set([
|
|
|
83
85
|
'memory.create', 'memory.update', 'memory.archive', 'memory.demote', 'memory.consolidate',
|
|
84
86
|
]);
|
|
85
87
|
const DELEGATED_ARGV_ENDPOINTS = new Set([
|
|
86
|
-
'agent.op', 'config.op', 'contact.op', 'aid.op', 'group.op', 'msg.op', 'fs.op',
|
|
88
|
+
'agent.op', 'config.op', 'contact.op', 'aid.op', 'aid.ownership', 'group.op', 'msg.op', 'fs.op',
|
|
87
89
|
'ctl', 'diag', 'menu-client.request', 'task.resume', 'queue.op', 'storage.auth', 'storage.upload',
|
|
88
90
|
'trigger.op', 'skill.refresh', 'thread.op', 'local-command-context', 'evolagent.bootstrapComplete', ...MEMORY_COMMAND_ENDPOINTS,
|
|
89
91
|
'handoff-return', 'handoff-recover-return', 'handoff-status', 'handoff-list', 'handoff-trace',
|
|
@@ -114,6 +116,8 @@ function requiresLocalControlToken(cmd) {
|
|
|
114
116
|
return true;
|
|
115
117
|
if (type === 'debug-issue-token')
|
|
116
118
|
return true;
|
|
119
|
+
if (type === 'aid.ownership')
|
|
120
|
+
return !sessionId || !delegated;
|
|
117
121
|
if (type === 'skill.refresh' || type === 'thread.op')
|
|
118
122
|
return !sessionId || !delegated;
|
|
119
123
|
return ['evolagent.bootstrapComplete', 'diag', 'handoff-status', 'handoff-list', 'handoff-trace', 'task.resume'].includes(type)
|
|
@@ -198,6 +202,7 @@ export class IpcServer {
|
|
|
198
202
|
systemSessionCommandGate;
|
|
199
203
|
codexPreToolUseExecutor;
|
|
200
204
|
aunMsgSender;
|
|
205
|
+
aunRequestGetExecutor;
|
|
201
206
|
diagExecutor;
|
|
202
207
|
menuClientExecutor;
|
|
203
208
|
handoffReturnExecutor;
|
|
@@ -206,6 +211,7 @@ export class IpcServer {
|
|
|
206
211
|
handoffListExecutor;
|
|
207
212
|
handoffTraceExecutor;
|
|
208
213
|
bindExecutor;
|
|
214
|
+
aidOwnershipExecutor;
|
|
209
215
|
configOperationExecutor;
|
|
210
216
|
contactOperationExecutor;
|
|
211
217
|
aidOperationExecutor;
|
|
@@ -508,6 +514,9 @@ export class IpcServer {
|
|
|
508
514
|
setAunMsgSender(sender) {
|
|
509
515
|
this.aunMsgSender = sender;
|
|
510
516
|
}
|
|
517
|
+
setAunRequestGetExecutor(executor) {
|
|
518
|
+
this.aunRequestGetExecutor = executor;
|
|
519
|
+
}
|
|
511
520
|
hasAunMsgSender() {
|
|
512
521
|
return this.aunMsgSender !== undefined;
|
|
513
522
|
}
|
|
@@ -538,6 +547,9 @@ export class IpcServer {
|
|
|
538
547
|
setBindExecutor(executor) {
|
|
539
548
|
this.bindExecutor = executor;
|
|
540
549
|
}
|
|
550
|
+
setAidOwnershipExecutor(executor) {
|
|
551
|
+
this.aidOwnershipExecutor = executor;
|
|
552
|
+
}
|
|
541
553
|
/** Inject DingTalk contact binding-code executor. */
|
|
542
554
|
setDingtalkContactBindExecutor(executor) {
|
|
543
555
|
this.dingtalkContactBindExecutor = executor;
|
|
@@ -1088,7 +1100,13 @@ export class IpcServer {
|
|
|
1088
1100
|
return { ok: false, error: 'Invalid model catalog scope' };
|
|
1089
1101
|
}
|
|
1090
1102
|
try {
|
|
1091
|
-
const { getLocalCatalog } = await import('./core/model/model-catalog.js');
|
|
1103
|
+
const { getLocalCatalog, getLocalProviderCatalog } = await import('./core/model/model-catalog.js');
|
|
1104
|
+
if (cmd.providerId !== undefined || cmd.serviceType !== undefined) {
|
|
1105
|
+
if (typeof cmd.providerId !== 'string' || typeof cmd.serviceType !== 'string' || cmd.self !== undefined) {
|
|
1106
|
+
return { ok: false, error: 'Invalid provider catalog scope' };
|
|
1107
|
+
}
|
|
1108
|
+
return { ok: true, snapshot: await getLocalProviderCatalog(cmd.providerId, cmd.serviceType, cmd.refresh === true) };
|
|
1109
|
+
}
|
|
1092
1110
|
return { ok: true, snapshot: await getLocalCatalog(cmd.self, cmd.baseagent, cmd.refresh === true) };
|
|
1093
1111
|
}
|
|
1094
1112
|
catch {
|
|
@@ -1191,6 +1209,23 @@ export class IpcServer {
|
|
|
1191
1209
|
return { ok: false, error: 'bind executor not configured' };
|
|
1192
1210
|
return this.bindExecutor.cancel(cmd.taskId);
|
|
1193
1211
|
}
|
|
1212
|
+
case 'aid.ownership': {
|
|
1213
|
+
if (!Array.isArray(cmd.argv) || cmd.argv.some((value) => typeof value !== 'string')) {
|
|
1214
|
+
return { ok: false, code: 'INVALID_ARGUMENT', error: 'Ownership argv is required' };
|
|
1215
|
+
}
|
|
1216
|
+
if (cmd.sessionId || cmd.delegationToken) {
|
|
1217
|
+
if (!this.aidOwnershipExecutor)
|
|
1218
|
+
return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Managed ownership is unavailable' };
|
|
1219
|
+
return this.aidOwnershipExecutor(cmd.argv, cmd.sessionId, cmd.delegationToken, cmd.delegationCommandHash);
|
|
1220
|
+
}
|
|
1221
|
+
try {
|
|
1222
|
+
const command = parseOwnershipCommand(cmd.argv);
|
|
1223
|
+
return { ok: true, state: await executeOwnershipCommand(command, ownerResolver.getDaemonAid()) };
|
|
1224
|
+
}
|
|
1225
|
+
catch (error) {
|
|
1226
|
+
return ownershipFailure(error);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1194
1229
|
case 'dingtalk.contact-bind.register': {
|
|
1195
1230
|
if (!this.dingtalkContactBindExecutor) {
|
|
1196
1231
|
return { ok: false, error: 'dingtalk contact bind executor not configured' };
|
|
@@ -1476,6 +1511,21 @@ export class IpcServer {
|
|
|
1476
1511
|
}
|
|
1477
1512
|
return this.debugIssueTokenExecutor({ sessionId: cmd.sessionId });
|
|
1478
1513
|
}
|
|
1514
|
+
case 'aun-msg-request-get': {
|
|
1515
|
+
if (!this.aunRequestGetExecutor)
|
|
1516
|
+
return { ok: false, code: 'NOT_CONFIGURED', error: 'AUN request registry is not configured' };
|
|
1517
|
+
if (typeof cmd.aid !== 'string' || !cmd.aid)
|
|
1518
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'missing aid' };
|
|
1519
|
+
if (typeof cmd.requestId !== 'string' || !cmd.requestId)
|
|
1520
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'missing requestId' };
|
|
1521
|
+
return this.aunRequestGetExecutor({
|
|
1522
|
+
aid: cmd.aid,
|
|
1523
|
+
requestId: cmd.requestId,
|
|
1524
|
+
sessionId: typeof cmd.sessionId === 'string' ? cmd.sessionId : undefined,
|
|
1525
|
+
delegationToken: typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined,
|
|
1526
|
+
delegationCommandHash: typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined,
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1479
1529
|
case 'aun-msg-send': {
|
|
1480
1530
|
if (cmd.argv !== undefined) {
|
|
1481
1531
|
if (!this.aunMsgSender)
|
|
@@ -1529,7 +1579,7 @@ export class IpcServer {
|
|
|
1529
1579
|
}
|
|
1530
1580
|
: undefined;
|
|
1531
1581
|
try {
|
|
1532
|
-
const normalizedPayload = payload && Object.prototype.hasOwnProperty.call(payload, 'mentions')
|
|
1582
|
+
const normalizedPayload = cmd.rawPayload !== true && payload && Object.prototype.hasOwnProperty.call(payload, 'mentions')
|
|
1533
1583
|
? { ...payload, mentions: normalizeAunMentionEntries(payload.mentions) }
|
|
1534
1584
|
: payload;
|
|
1535
1585
|
return await this.aunMsgSender({
|
|
@@ -1537,6 +1587,7 @@ export class IpcServer {
|
|
|
1537
1587
|
to: cmd.to,
|
|
1538
1588
|
scope: cmd.scope === 'group' ? 'group' : 'msg',
|
|
1539
1589
|
payload: normalizedPayload,
|
|
1590
|
+
rawPayload: cmd.rawPayload === true,
|
|
1540
1591
|
file,
|
|
1541
1592
|
mentions: Object.prototype.hasOwnProperty.call(cmd, 'mentions')
|
|
1542
1593
|
? normalizeAunMentionEntries(cmd.mentions)
|
|
@@ -1546,6 +1597,8 @@ export class IpcServer {
|
|
|
1546
1597
|
handoffContext: cmd.handoffContext,
|
|
1547
1598
|
originSessionId: typeof cmd.originSessionId === 'string' ? cmd.originSessionId : undefined,
|
|
1548
1599
|
originMessageId: typeof cmd.originMessageId === 'string' ? cmd.originMessageId : undefined,
|
|
1600
|
+
returnPolicy: cmd.returnPolicy === 'required' ? 'required' : cmd.returnPolicy === 'none' ? 'none' : undefined,
|
|
1601
|
+
timeoutMs: typeof cmd.timeoutMs === 'number' && Number.isFinite(cmd.timeoutMs) ? cmd.timeoutMs : undefined,
|
|
1549
1602
|
delegationToken: typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined,
|
|
1550
1603
|
delegationCommandHash: typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined,
|
|
1551
1604
|
log,
|
|
@@ -1765,7 +1818,7 @@ export class IpcServer {
|
|
|
1765
1818
|
if (disabled)
|
|
1766
1819
|
return disabled;
|
|
1767
1820
|
const ownerAid = taskCtx.selfAid
|
|
1768
|
-
?
|
|
1821
|
+
? ownerResolver.primaryOwner(taskCtx.selfAid)
|
|
1769
1822
|
: undefined;
|
|
1770
1823
|
const { launchConsolidation } = await import('./core/memory/consolidation.js');
|
|
1771
1824
|
if (!this.consolidationLaunchExecutor) {
|
|
@@ -2412,7 +2465,7 @@ export class IpcServer {
|
|
|
2412
2465
|
if (disabled)
|
|
2413
2466
|
return { error: disabled };
|
|
2414
2467
|
const ownerAid = taskCtx.selfAid
|
|
2415
|
-
?
|
|
2468
|
+
? ownerResolver.primaryOwner(taskCtx.selfAid)
|
|
2416
2469
|
: undefined;
|
|
2417
2470
|
if (allowed === 'owner' && !ownerAid) {
|
|
2418
2471
|
return { error: { ok: false, code: 'INVALID_REQUEST', error: '当前 agent 未配置 owner' } };
|
|
@@ -2481,7 +2534,7 @@ export class IpcServer {
|
|
|
2481
2534
|
try {
|
|
2482
2535
|
if (!this.consolidationLaunchExecutor)
|
|
2483
2536
|
return;
|
|
2484
|
-
const ownerAid =
|
|
2537
|
+
const ownerAid = ownerResolver.primaryOwner(selfAid);
|
|
2485
2538
|
await this.consolidationLaunchExecutor({
|
|
2486
2539
|
taskCtx,
|
|
2487
2540
|
mode: 'forget',
|
package/dist/paths.js
CHANGED
|
@@ -34,6 +34,7 @@ export function resolvePaths() {
|
|
|
34
34
|
outboxDir: path.join(root, 'data', 'outbox'),
|
|
35
35
|
dataDir: path.join(root, 'data'),
|
|
36
36
|
claudeModelCache: path.join(root, 'data', 'claude-model-cache.json'),
|
|
37
|
+
providersConfig: path.join(root, 'providers.json'),
|
|
37
38
|
logs: path.join(root, 'logs'),
|
|
38
39
|
agentsDir,
|
|
39
40
|
lineStats: path.join(root, 'logs', 'line-stats.log'),
|