evolcore 0.0.11 → 0.0.12
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 +22 -0
- package/bin/codex-managed-hook.mjs +80 -0
- package/dist/agents/claude-runner.js +35 -2
- package/dist/agents/codex-app-server-client.js +120 -14
- package/dist/agents/codex-runner.js +273 -35
- package/dist/agents/ecagent-runner.js +36 -4
- package/dist/agents/gemini-runner.js +1 -0
- package/dist/aun/aid/client.js +11 -21
- package/dist/aun/aid/managed-operation.js +107 -0
- package/dist/aun/msg/group.js +81 -12
- package/dist/aun/msg/managed-operation.js +804 -0
- package/dist/aun/msg/mention-schema.js +20 -0
- package/dist/aun/msg/p2p.js +7 -0
- package/dist/channels/aun.js +288 -108
- package/dist/channels/daemon.js +13 -0
- package/dist/cli/agent-command.js +56 -8
- package/dist/cli/agent.js +170 -6
- package/dist/cli/aun-commands.js +270 -69
- package/dist/cli/bench.js +12 -3
- package/dist/cli/daemon-commands.js +31 -31
- package/dist/cli/fs-command.js +60 -0
- package/dist/cli/handoff-command.js +3 -0
- package/dist/cli/index.js +30 -2
- package/dist/cli/managed-command-guard.js +41 -0
- package/dist/cli/model.js +11 -4
- package/dist/cli/queue-command.js +11 -1
- package/dist/cli/response.js +71 -0
- package/dist/cli/restart-monitor.js +4 -18
- package/dist/cli/trigger-command.js +4 -0
- package/dist/config/builtin-roles.js +4 -0
- package/dist/config/contact-book-store.js +11 -3
- package/dist/config/contact-request-service.js +161 -15
- package/dist/config/mention-mode.js +8 -24
- package/dist/core/auth/agent-delegation.js +0 -1
- package/dist/core/auth/operation-authorizer.js +30 -7
- package/dist/core/auth/operation-catalog.js +187 -25
- package/dist/core/bootstrap-messages.js +18 -0
- package/dist/core/bootstrap-service.js +63 -4
- package/dist/core/capability/providers/claude-capability-provider.js +9 -31
- package/dist/core/capability/providers/codex-capability-provider.js +4 -15
- package/dist/core/capability/skill-discovery.js +55 -0
- package/dist/core/channel-loader.js +1 -1
- package/dist/core/command/cli-intent-parser.js +9 -0
- package/dist/core/command/command-handler.js +467 -6
- package/dist/core/command/connect-menu.js +15 -0
- package/dist/core/command/group-menu.js +4 -4
- package/dist/core/command/menu-catalog.js +366 -0
- package/dist/core/command/menu-handler.js +147 -35
- package/dist/core/command/menu-protocol.js +71 -0
- package/dist/core/command/slash-gate.js +5 -2
- package/dist/core/command/slash-handler.js +41 -21
- package/dist/core/daemon-file-cache.js +2 -1
- package/dist/core/data-migration.js +9 -2
- package/dist/core/evolagent.js +4 -2
- package/dist/core/handoff/dispatcher.js +5 -2
- package/dist/core/handoff/runtime.js +145 -21
- package/dist/core/handoff/store.js +24 -0
- package/dist/core/handoff/types.js +1 -0
- package/dist/core/message/logical-queue-bridge.js +1 -0
- package/dist/core/message/mention-schema.js +126 -0
- package/dist/core/message/message-bridge.js +236 -78
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +1 -0
- package/dist/core/message/response-engine.js +54 -36
- package/dist/core/permission/ec-command-parser.js +156 -10
- package/dist/core/permission/sandbox-runtime.js +22 -1
- package/dist/core/permission/tool-policy.js +73 -30
- package/dist/core/protected-paths.js +7 -2
- package/dist/core/session/session-manager.js +21 -2
- package/dist/eck/manifest-engine.js +39 -13
- package/dist/index.js +384 -98
- package/dist/ipc.js +218 -9
- package/dist/response-system/coordinator.js +6 -4
- package/dist/response-system/engines/v1/proactive-flow.js +26 -8
- package/dist/response-system/modes/single-session/index.js +14 -1
- package/dist/response-system/selector.js +6 -5
- package/dist/trigger/anomaly-store.js +4 -0
- package/dist/trigger/script-executor.js +1 -0
- package/dist/utils/codex-app-server-registry.js +90 -0
- package/dist/utils/codex-cli.js +5 -1
- package/dist/utils/cross-platform.js +15 -0
- package/dist/utils/npm-ops.js +5 -12
- package/dist/utils/tool-summary.js +11 -0
- package/kits/docs/channels/aun.md +1 -1
- package/kits/docs/context-assembly.md +2 -2
- package/kits/docs/evolcore/agent.md +11 -6
- package/kits/docs/evolcore/aid.md +14 -0
- package/kits/docs/prompt-loading-architecture.md +1 -2
- package/kits/docs/venues/group.md +1 -1
- package/kits/eck_manifest.json +0 -12
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/05-venue.md +2 -2
- package/kits/schemas/single-session.schema.1.json +3 -3
- package/kits/schemas/single-session.schema.2.json +3 -3
- package/kits/templates/roles/admin.json +22 -0
- package/kits/templates/roles/member.json +27 -0
- package/kits/templates/roles/visitor.json +33 -3
- package/kits/templates/system-fragments/bootstrap.md +1 -1
- package/kits/templates/system-fragments/channel.md +1 -1
- package/kits/templates/system-fragments/session.md +1 -1
- package/package.json +2 -2
- package/dist/core/command/evol-menu-version-gate.js +0 -39
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { resolveRoot } from '../../paths.js';
|
|
4
|
+
import { agentmdGet, agentmdPut } from './agentmd.js';
|
|
5
|
+
import { aidLookup, aidShow } from './identity.js';
|
|
6
|
+
import { isValidAid } from './validation.js';
|
|
7
|
+
export class ManagedAidOperationError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
constructor(code, message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = 'ManagedAidOperationError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function normalizeAid(value) {
|
|
16
|
+
const aid = String(value || '').trim();
|
|
17
|
+
return aid.startsWith('@') ? aid.slice(1) : aid;
|
|
18
|
+
}
|
|
19
|
+
function hasOnlyOptionalJsonFormat(args, aidIndex) {
|
|
20
|
+
const suffix = args.slice(aidIndex + 1);
|
|
21
|
+
return suffix.length === 0 || (suffix.length === 2 && suffix[0] === '--format' && suffix[1] === 'json');
|
|
22
|
+
}
|
|
23
|
+
function parseAid(value) {
|
|
24
|
+
const aid = normalizeAid(value);
|
|
25
|
+
if (!aid)
|
|
26
|
+
return { ok: false, code: 'INVALID_ARGUMENT', reason: 'missing AID' };
|
|
27
|
+
if (!isValidAid(aid))
|
|
28
|
+
return { ok: false, code: 'INVALID_AID', reason: `invalid AID: ${aid}` };
|
|
29
|
+
return { ok: true, aid };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The daemon accepts only the self-scoped AID commands exposed to managed
|
|
33
|
+
* tasks. Parsing here is deliberately narrower than the standalone CLI.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveManagedAidOperation(argv) {
|
|
36
|
+
const args = argv[0] === 'aid' ? argv.slice(1) : argv;
|
|
37
|
+
const subcommand = args[0];
|
|
38
|
+
if ((subcommand === 'show' || subcommand === 'lookup') && hasOnlyOptionalJsonFormat(args, 1)) {
|
|
39
|
+
const parsedAid = parseAid(args[1]);
|
|
40
|
+
if (!parsedAid.ok)
|
|
41
|
+
return parsedAid;
|
|
42
|
+
return {
|
|
43
|
+
ok: true,
|
|
44
|
+
command: {
|
|
45
|
+
kind: subcommand,
|
|
46
|
+
aid: parsedAid.aid,
|
|
47
|
+
operationId: `ec.aid.${subcommand}`,
|
|
48
|
+
canonicalArgv: ['aid', subcommand, parsedAid.aid],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (subcommand === 'agentmd' && (args[1] === 'get' || args[1] === 'put') && hasOnlyOptionalJsonFormat(args, 2)) {
|
|
53
|
+
const parsedAid = parseAid(args[2]);
|
|
54
|
+
if (!parsedAid.ok)
|
|
55
|
+
return parsedAid;
|
|
56
|
+
const kind = `agentmd.${args[1]}`;
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
command: {
|
|
60
|
+
kind,
|
|
61
|
+
aid: parsedAid.aid,
|
|
62
|
+
operationId: `ec.aid.${kind}`,
|
|
63
|
+
canonicalArgv: ['aid', 'agentmd', args[1], parsedAid.aid],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
code: 'NOT_ALLOWED',
|
|
70
|
+
reason: 'Managed AID operations only allow exact self-scoped show, lookup, agentmd get, or agentmd put commands with an optional --format json suffix',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const defaultDependencies = () => ({
|
|
74
|
+
root: resolveRoot(),
|
|
75
|
+
aidShow,
|
|
76
|
+
aidLookup,
|
|
77
|
+
agentmdGet,
|
|
78
|
+
agentmdPut,
|
|
79
|
+
existsSync: fs.existsSync,
|
|
80
|
+
readFileSync: fs.readFileSync,
|
|
81
|
+
});
|
|
82
|
+
/** Execute a validated AID operation from the daemon-owned host filesystem. */
|
|
83
|
+
export async function executeManagedAidOperation(command, overrides = {}) {
|
|
84
|
+
const deps = { ...defaultDependencies(), ...overrides };
|
|
85
|
+
const aunPath = deps.root;
|
|
86
|
+
switch (command.kind) {
|
|
87
|
+
case 'show':
|
|
88
|
+
return { kind: command.kind, aid: command.aid, value: await deps.aidShow(command.aid, { aunPath }) };
|
|
89
|
+
case 'lookup':
|
|
90
|
+
return { kind: command.kind, aid: command.aid, value: await deps.aidLookup(command.aid) };
|
|
91
|
+
case 'agentmd.get':
|
|
92
|
+
return {
|
|
93
|
+
kind: command.kind,
|
|
94
|
+
aid: command.aid,
|
|
95
|
+
value: await deps.agentmdGet(command.aid, { aunPath, withVerification: true }),
|
|
96
|
+
};
|
|
97
|
+
case 'agentmd.put': {
|
|
98
|
+
const localPath = path.join(aunPath, 'AIDs', command.aid, 'agent.md');
|
|
99
|
+
if (!deps.existsSync(localPath)) {
|
|
100
|
+
throw new ManagedAidOperationError('LOCAL_AGENTMD_MISSING', `local agent.md not found: ${command.aid}`);
|
|
101
|
+
}
|
|
102
|
+
const content = deps.readFileSync(localPath, 'utf-8');
|
|
103
|
+
await deps.agentmdPut(content, { aid: command.aid, aunPath });
|
|
104
|
+
return { kind: command.kind, aid: command.aid, path: localPath };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
package/dist/aun/msg/group.js
CHANGED
|
@@ -13,6 +13,7 @@ import { readBestTaskRuntimeContext } from '../../cli/task-context.js';
|
|
|
13
13
|
import { ipcQuery } from '../../ipc.js';
|
|
14
14
|
import { resolvePaths } from '../../paths.js';
|
|
15
15
|
import { AGENT_DELEGATION_TOKEN_ENV } from '../../core/auth/agent-delegation.js';
|
|
16
|
+
import { normalizeAunMentionEntries } from './mention-schema.js';
|
|
16
17
|
function buildGroupPayload(body) {
|
|
17
18
|
return body.mode === 'text' ? { type: 'text', text: body.text } : { ...body.payload };
|
|
18
19
|
}
|
|
@@ -189,8 +190,18 @@ export async function groupSend(args) {
|
|
|
189
190
|
break;
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
|
-
|
|
193
|
-
payload.mentions
|
|
193
|
+
const payloadMentions = Object.prototype.hasOwnProperty.call(payload, 'mentions')
|
|
194
|
+
? normalizeAunMentionEntries(payload.mentions)
|
|
195
|
+
: undefined;
|
|
196
|
+
if (args.mentions !== undefined) {
|
|
197
|
+
const normalizedMentions = normalizeAunMentionEntries(args.mentions);
|
|
198
|
+
if (normalizedMentions.length > 0)
|
|
199
|
+
payload.mentions = normalizedMentions;
|
|
200
|
+
else if (payloadMentions !== undefined)
|
|
201
|
+
payload.mentions = payloadMentions;
|
|
202
|
+
}
|
|
203
|
+
else if (payloadMentions !== undefined) {
|
|
204
|
+
payload.mentions = payloadMentions;
|
|
194
205
|
}
|
|
195
206
|
applyGroupRoutingPayloadFields(payload, args, runtimeContext);
|
|
196
207
|
const encrypt = resolveAunMessageEncrypt(args.encrypt);
|
|
@@ -305,8 +316,9 @@ export async function groupInfo(args) {
|
|
|
305
316
|
}
|
|
306
317
|
}
|
|
307
318
|
export async function groupList(args) {
|
|
308
|
-
|
|
319
|
+
let conn;
|
|
309
320
|
try {
|
|
321
|
+
conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
|
|
310
322
|
const params = {};
|
|
311
323
|
if (args.size !== undefined)
|
|
312
324
|
params.size = args.size;
|
|
@@ -329,7 +341,8 @@ export async function groupList(args) {
|
|
|
329
341
|
return formatRpcError(e);
|
|
330
342
|
}
|
|
331
343
|
finally {
|
|
332
|
-
|
|
344
|
+
if (conn)
|
|
345
|
+
await conn.close();
|
|
333
346
|
}
|
|
334
347
|
}
|
|
335
348
|
export async function groupUpdate(args) {
|
|
@@ -675,7 +688,7 @@ export async function groupUpdateRules(args) {
|
|
|
675
688
|
}
|
|
676
689
|
}
|
|
677
690
|
const GROUP_RULES_FILE_PATH = '/rules.md';
|
|
678
|
-
const MAX_GROUP_RULES_BYTES = 4 * 1024;
|
|
691
|
+
export const MAX_GROUP_RULES_BYTES = 4 * 1024;
|
|
679
692
|
const MTIME_TOLERANCE_MS = 1;
|
|
680
693
|
export async function groupRulesFileGet(args) {
|
|
681
694
|
return withAunClient(args.from, args, async (client) => {
|
|
@@ -742,13 +755,26 @@ export async function groupRulesFileGet(args) {
|
|
|
742
755
|
}
|
|
743
756
|
export async function groupRulesFileSet(args) {
|
|
744
757
|
return withAunClient(args.from, args, async (client) => {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
758
|
+
if ((args.filePath === undefined) === (args.content === undefined)) {
|
|
759
|
+
throw new Error('规则文件必须且只能提供 filePath 或 content');
|
|
760
|
+
}
|
|
761
|
+
let upload;
|
|
762
|
+
if (args.content !== undefined) {
|
|
763
|
+
const bytes = Buffer.from(args.content, 'utf8');
|
|
764
|
+
if (!args.content || bytes.byteLength > MAX_GROUP_RULES_BYTES || bytes.toString('utf8') !== args.content) {
|
|
765
|
+
throw new Error(`规则内容必须是非空 UTF-8,且不超过 ${MAX_GROUP_RULES_BYTES} bytes`);
|
|
766
|
+
}
|
|
767
|
+
upload = await uploadGroupRulesBytes(client, args.groupId, bytes);
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
assertLocalRulesFile(args.filePath);
|
|
771
|
+
upload = await client.group.fs.cp(args.filePath, `${args.groupId}:${GROUP_RULES_FILE_PATH}`, {
|
|
772
|
+
force: true,
|
|
773
|
+
overwrite: true,
|
|
774
|
+
parents: true,
|
|
775
|
+
contentType: 'text/markdown; charset=utf-8',
|
|
776
|
+
});
|
|
777
|
+
}
|
|
752
778
|
const published = await publishCurrentRulesFile(client, args.groupId, args.from);
|
|
753
779
|
return { ...published, upload };
|
|
754
780
|
});
|
|
@@ -984,6 +1010,49 @@ function assertLocalRulesFile(filePath) {
|
|
|
984
1010
|
throw new Error(`规则文件不是有效 UTF-8: ${errorMessage(e)}`);
|
|
985
1011
|
}
|
|
986
1012
|
}
|
|
1013
|
+
async function uploadGroupRulesBytes(client, groupId, bytes) {
|
|
1014
|
+
const remotePath = `${groupId}:${GROUP_RULES_FILE_PATH}`;
|
|
1015
|
+
const base = {
|
|
1016
|
+
path: remotePath,
|
|
1017
|
+
size_bytes: bytes.byteLength,
|
|
1018
|
+
sha256: sha256Hex(bytes),
|
|
1019
|
+
content_type: 'text/markdown; charset=utf-8',
|
|
1020
|
+
force: true,
|
|
1021
|
+
parents: true,
|
|
1022
|
+
};
|
|
1023
|
+
const check = await client.call('group.fs.check_upload', base);
|
|
1024
|
+
if (isRecord(check) && check.within_limit === false) {
|
|
1025
|
+
throw new Error('规则文件超过 group.fs 上传限制');
|
|
1026
|
+
}
|
|
1027
|
+
if (isRecord(check) && (check.instant === true || check.dedup_hit === true || check.skip_upload === true)) {
|
|
1028
|
+
return client.call('group.fs.complete_upload', {
|
|
1029
|
+
...base,
|
|
1030
|
+
skip_blob: true,
|
|
1031
|
+
...(check.session_id !== undefined ? { session_id: check.session_id } : {}),
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
const session = await client.call('group.fs.create_upload_session', base);
|
|
1035
|
+
if (!isRecord(session))
|
|
1036
|
+
throw new Error('group.fs.create_upload_session returned invalid response');
|
|
1037
|
+
const uploadUrl = stringField(session, ['upload_url', 'url']);
|
|
1038
|
+
if (!uploadUrl)
|
|
1039
|
+
throw new Error('group.fs.create_upload_session did not return upload_url');
|
|
1040
|
+
const headers = {};
|
|
1041
|
+
if (isRecord(session.headers)) {
|
|
1042
|
+
for (const [key, value] of Object.entries(session.headers)) {
|
|
1043
|
+
if (value !== undefined && value !== null)
|
|
1044
|
+
headers[key] = String(value);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
if (!Object.keys(headers).some(key => key.toLowerCase() === 'content-type')) {
|
|
1048
|
+
headers['Content-Type'] = base.content_type;
|
|
1049
|
+
}
|
|
1050
|
+
await client.group.fs.lowlevel.httpPut(uploadUrl, bytes, headers);
|
|
1051
|
+
return client.call('group.fs.complete_upload', {
|
|
1052
|
+
...base,
|
|
1053
|
+
...((session.session_id ?? session.id) !== undefined ? { session_id: session.session_id ?? session.id } : {}),
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
987
1056
|
async function readGroupRulesBytes(client, groupId) {
|
|
988
1057
|
const remoteRef = `${groupId}:${GROUP_RULES_FILE_PATH}`;
|
|
989
1058
|
const ticket = await client.call('group.fs.create_download_ticket', { path: remoteRef });
|