evolcore 0.0.26 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/bin/codex-managed-acl.ps1 +43 -0
- package/dist/agents/baseagent-availability.js +68 -0
- package/dist/agents/claude-runner.js +123 -22
- package/dist/agents/codex/app-server-client.js +63 -26
- package/dist/agents/codex-runner.js +316 -411
- package/dist/agents/ecagent-runner.js +170 -25
- package/dist/agents/gemini-runner.js +6 -0
- package/dist/agents/runner-types.js +50 -2
- package/dist/aun/aid/agentmd.js +73 -31
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/control-aid.js +180 -1
- package/dist/aun/aid/identity.js +3 -3
- package/dist/aun/group/history.js +303 -0
- package/dist/aun/group/identity.js +43 -0
- package/dist/aun/group/index.js +5 -0
- package/dist/aun/{msg/group.js → group/operations.js} +161 -38
- package/dist/aun/{menu-client.js → menu/client.js} +12 -7
- package/dist/aun/menu/index.js +2 -0
- package/dist/aun/menu/transport.js +49 -0
- package/dist/aun/msg/index.js +2 -1
- package/dist/aun/msg/managed-operation.js +84 -18
- package/dist/aun/msg/mention-schema.js +51 -0
- package/dist/aun/msg/p2p.js +13 -8
- package/dist/aun/msg/upload.js +43 -88
- package/dist/aun/outbox.js +29 -7
- package/dist/aun/rpc/client.js +1 -0
- package/dist/aun/storage/client.js +39 -50
- package/dist/channels/aun.js +522 -233
- package/dist/channels/daemon.js +10 -6
- package/dist/cli/agent-command.js +108 -6
- package/dist/cli/agent-create.js +515 -2
- package/dist/cli/agent.js +109 -8
- package/dist/cli/aun-commands.js +191 -42
- package/dist/cli/config.js +8 -5
- package/dist/cli/contact.js +2 -2
- package/dist/cli/ctl-command.js +2 -2
- package/dist/cli/daemon-commands.js +35 -23
- package/dist/cli/diag.js +2 -2
- package/dist/cli/fs-command.js +3 -3
- package/dist/cli/handoff-command.js +6 -6
- package/dist/cli/index.js +8 -2
- package/dist/cli/init.js +34 -1
- package/dist/cli/managed-command-guard.js +2 -1
- package/dist/cli/menu-client.js +9 -5
- package/dist/cli/model.js +3 -3
- package/dist/cli/queue-command.js +2 -2
- package/dist/cli/response.js +2 -2
- package/dist/cli/restart-monitor.js +16 -2
- package/dist/cli/task-command.js +59 -0
- package/dist/cli/task-context.js +97 -49
- package/dist/cli/trigger-command.js +20 -10
- package/dist/config/builtin-roles.js +10 -0
- package/dist/config/config-field-policy.js +11 -0
- package/dist/config/config-manager.js +32 -4
- package/dist/config/config-operation-service.js +20 -5
- package/dist/config/contact-book-store.js +1 -1
- package/dist/config/contact-book.js +1 -1
- package/dist/config/contact-operation-service.js +1 -1
- package/dist/config/peer-role-resolver.js +1 -1
- package/dist/config/resolved-config-op.js +3 -0
- package/dist/config-store.js +1 -1
- package/dist/core/agent-application-service.js +5 -0
- package/dist/core/audit/event-key.js +17 -2
- package/dist/core/audit/log-integrity.js +34 -8
- package/dist/core/auth/agent-delegation.js +48 -14
- package/dist/core/auth/auth-gateway.js +2 -0
- package/dist/core/auth/authorization-audit.js +34 -38
- package/dist/core/auth/operation-authorizer.js +67 -5
- package/dist/core/auth/operation-catalog.js +110 -0
- package/dist/core/auth/remote-access-store.js +115 -9
- package/dist/core/bootstrap-messages.js +66 -7
- package/dist/core/bootstrap-service.js +110 -19
- package/dist/core/command/agent-control.js +88 -7
- package/dist/core/command/agent-storage-menu.js +443 -0
- package/dist/core/command/cli-intent-parser.js +19 -0
- package/dist/core/command/command-handler.js +76 -39
- package/dist/core/command/data-root-resolver.js +273 -0
- package/dist/core/command/group-menu.js +7 -2
- package/dist/core/command/menu-catalog.js +34 -4
- package/dist/core/command/menu-handler.js +348 -77
- package/dist/core/command/menu-protocol.js +40 -6
- package/dist/core/command/role-menu.js +2 -2
- package/dist/core/command/slash-handler.js +37 -22
- package/dist/core/event-catalog.js +4 -0
- package/dist/core/evolagent-registry.js +28 -2
- package/dist/core/group/invite-service.js +924 -0
- package/dist/core/interaction-router.js +22 -8
- package/dist/core/message/im-renderer.js +76 -15
- package/dist/core/message/message-bridge.js +94 -11
- package/dist/core/message/message-log.js +5 -3
- package/dist/core/message/message-queue.js +73 -41
- package/dist/core/message/response-engine.js +709 -117
- package/dist/core/permission/approval-gateway.js +36 -3
- package/dist/core/permission/ec-command-parser.js +61 -29
- package/dist/core/permission/protected-paths.js +134 -16
- package/dist/core/permission/sandbox-runtime.js +72 -3
- package/dist/core/permission/tool-error-code.js +15 -0
- package/dist/core/permission/tool-policy.js +7 -7
- package/dist/core/relation/peer-identity.js +57 -6
- package/dist/core/relation/shared-data.js +106 -0
- package/dist/core/role/runtime-policy.js +64 -0
- package/dist/core/runtime-lock.js +10 -26
- package/dist/core/session/runner-task-history.js +170 -0
- package/dist/core/session/session-manager.js +34 -6
- package/dist/core/session/session-mapper.js +41 -0
- package/dist/core/session/session-turn-coordinator.js +37 -7
- package/dist/core/session/session-turns.js +48 -7
- package/dist/core/task/task-recovery-service.js +176 -0
- package/dist/core/task/task-resume-operation.js +32 -0
- package/dist/eck/group-rules-sync.js +5 -3
- package/dist/eck/kit-renderer.js +1 -0
- package/dist/index.js +308 -54
- package/dist/ipc.js +141 -15
- package/dist/paths.js +17 -4
- package/dist/product.js +2 -0
- package/dist/trigger/event-source.js +19 -0
- package/dist/trigger/feedback.js +233 -40
- package/dist/trigger/parser.js +55 -5
- package/dist/trigger/patch.js +9 -0
- package/dist/trigger/scheduler.js +30 -4
- package/dist/trigger/validation.js +20 -3
- package/dist/utils/ecweb-utils.js +1 -0
- package/dist/utils/error-utils.js +40 -2
- package/dist/utils/logger.js +23 -13
- package/dist/utils/tool-summary.js +59 -3
- package/dist/utils/welcome.js +174 -1
- package/ecagent/dist/harness/agent-harness.js +3 -0
- package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
- package/kits/docs/INDEX.md +0 -6
- package/kits/docs/channels/aun.md +15 -2
- package/kits/docs/channels/feishu.md +1 -1
- package/kits/docs/context-assembly.md +29 -17
- package/kits/docs/evolcore/INDEX.md +8 -3
- package/kits/docs/evolcore/agent-create.md +39 -7
- package/kits/docs/evolcore/agent.md +33 -1
- package/kits/docs/evolcore/aid.md +9 -1
- package/kits/docs/evolcore/config.md +40 -1
- package/kits/docs/evolcore/group-collaboration.md +1 -1
- package/kits/docs/evolcore/group.md +117 -2
- package/kits/docs/evolcore/menu-client.md +16 -0
- package/kits/docs/evolcore/msg.md +3 -0
- package/kits/docs/evolcore/storage.md +3 -0
- package/kits/docs/evolcore/task.md +14 -0
- package/kits/docs/evolcore/trigger.md +51 -3
- package/kits/docs/venues/group.md +5 -0
- package/kits/eck_manifest.json +27 -0
- package/kits/rules/01-overview.md +11 -7
- package/kits/rules/04-relation.md +2 -1
- package/kits/rules/05-venue.md +1 -1
- package/kits/rules/06-channel.md +6 -4
- package/kits/schemas/agent-config.schema.12.json +25 -1
- package/kits/schemas/daemon.schema.6.json +2 -2
- package/kits/schemas/defaults.schema.5.json +1 -1
- package/kits/schemas/relation-config.schema.1.json +1 -1
- package/kits/schemas/relation-config.schema.5.json +1 -1
- package/kits/schemas/role-config.schema.1.json +14 -0
- package/kits/templates/roles/member.json +5 -0
- package/kits/templates/roles/visitor.json +5 -0
- package/kits/templates/system-fragments/baseagent.md +1 -1
- package/kits/templates/system-fragments/bootstrap.md +26 -9
- package/kits/templates/system-fragments/channel.md +8 -44
- package/kits/templates/system-fragments/commands.md +10 -2
- package/kits/templates/system-fragments/group-unread-history.md +7 -0
- package/kits/templates/system-fragments/reply.md +56 -0
- package/package.json +7 -3
- package/dist/aun/group-identity.js +0 -9
- /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
- /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
|
@@ -23,7 +23,7 @@ import { displaySessionTitle } from '../core/session/session-title.js';
|
|
|
23
23
|
import { isNonAgentSessionChannel } from '../core/system-channels.js';
|
|
24
24
|
import { printCodeStats } from './code-stats.js';
|
|
25
25
|
import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
|
|
26
|
-
import {
|
|
26
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
27
27
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
|
|
28
28
|
import { rotateStdoutLog } from '../utils/log-writer.js';
|
|
29
29
|
import { inspectDataMigrationRequirement } from '../core/data-migration.js';
|
|
@@ -40,6 +40,8 @@ export function ensureCodexHookBeforeLifecycle(onRepaired) {
|
|
|
40
40
|
try {
|
|
41
41
|
const usesCodex = loadDefaults()?.active_baseagent === 'codex'
|
|
42
42
|
|| loadAllAgents().agents.some(agent => {
|
|
43
|
+
if (agent.enabled === false)
|
|
44
|
+
return false;
|
|
43
45
|
try {
|
|
44
46
|
return resolveEffective({ self: agent.aid }).active_baseagent === 'codex';
|
|
45
47
|
}
|
|
@@ -146,7 +148,7 @@ function rejectPidIsolatedLifecycle(action, status, ping) {
|
|
|
146
148
|
}
|
|
147
149
|
async function tryDelegatedDaemonRestart(socketPath) {
|
|
148
150
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
149
|
-
const delegationToken =
|
|
151
|
+
const delegationToken = readDelegationCredential();
|
|
150
152
|
if (!sessionId || !delegationToken)
|
|
151
153
|
return false;
|
|
152
154
|
const response = await ipcQuery(socketPath, {
|
|
@@ -2720,17 +2722,18 @@ function findAliveEcweb(p) {
|
|
|
2720
2722
|
return alive[0] ?? null;
|
|
2721
2723
|
}
|
|
2722
2724
|
/**
|
|
2723
|
-
* 轻量 HTTP 就绪探测:
|
|
2724
|
-
* 不走 /api/pair-code
|
|
2725
|
-
* 根路径由 serveStatic 处理,返回 index.html,无副作用。
|
|
2725
|
+
* 轻量 HTTP 就绪探测:ECWeb 的健康端点必须返回明确的服务标识。
|
|
2726
|
+
* 不走 /api/pair-code(会触发配对码刷新副作用),也不依赖静态页面内容。
|
|
2726
2727
|
*/
|
|
2727
2728
|
async function probeEcwebReady(port) {
|
|
2728
2729
|
try {
|
|
2729
|
-
const res = await fetch(`http://127.0.0.1:${port}
|
|
2730
|
-
method: 'GET',
|
|
2730
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
2731
2731
|
signal: AbortSignal.timeout(2000),
|
|
2732
2732
|
});
|
|
2733
|
-
|
|
2733
|
+
if (!res.ok)
|
|
2734
|
+
return false;
|
|
2735
|
+
const body = await res.json();
|
|
2736
|
+
return body.ok === true && body.service === 'ecweb';
|
|
2734
2737
|
}
|
|
2735
2738
|
catch {
|
|
2736
2739
|
return false;
|
|
@@ -2756,8 +2759,9 @@ async function waitForExistingEcweb(p, timeoutMs = 3_000) {
|
|
|
2756
2759
|
}
|
|
2757
2760
|
/**
|
|
2758
2761
|
* 输出 ECWeb 状态。判定口径:
|
|
2759
|
-
* 1.
|
|
2760
|
-
* 2.
|
|
2762
|
+
* 1. HTTP 是否就绪——探测 ECWeb 专用 /api/health 端点。
|
|
2763
|
+
* 2. 进程是否存活(instance/ 下的 pid 文件 + isProcessRunning)仅用于补充诊断;
|
|
2764
|
+
* 某些 CLI 运行在隔离 PID namespace 中,看不到宿主 ECWeb PID 是正常情况。
|
|
2761
2765
|
*/
|
|
2762
2766
|
async function printEcwebStatus(p) {
|
|
2763
2767
|
try {
|
|
@@ -2773,6 +2777,15 @@ async function printEcwebStatus(p) {
|
|
|
2773
2777
|
// still provide an authoritative runtime status without local config access.
|
|
2774
2778
|
}
|
|
2775
2779
|
const entries = readEcwebInstanceEntries(p);
|
|
2780
|
+
// Probe before consulting PID visibility. The daemon and CLI can be in
|
|
2781
|
+
// different PID namespaces while sharing the host network namespace.
|
|
2782
|
+
let readyEntry;
|
|
2783
|
+
for (const entry of entries) {
|
|
2784
|
+
if (await probeEcwebReady(entry.record.port)) {
|
|
2785
|
+
readyEntry = entry;
|
|
2786
|
+
break;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2776
2789
|
const aliveEntries = [];
|
|
2777
2790
|
for (const entry of entries) {
|
|
2778
2791
|
if (platform.isProcessRunning(entry.record.pid)) {
|
|
@@ -2781,22 +2794,21 @@ async function printEcwebStatus(p) {
|
|
|
2781
2794
|
else {
|
|
2782
2795
|
// A stale EC Web record must never be used to report the PID of an
|
|
2783
2796
|
// unrelated process that later inherited the port.
|
|
2784
|
-
|
|
2785
|
-
|
|
2797
|
+
// Keep a record whose dedicated health endpoint just proved live: the
|
|
2798
|
+
// PID may be hidden by a namespace boundary rather than actually dead.
|
|
2799
|
+
if (entry.filePath !== readyEntry?.filePath) {
|
|
2800
|
+
try {
|
|
2801
|
+
fs.unlinkSync(entry.filePath);
|
|
2802
|
+
}
|
|
2803
|
+
catch { }
|
|
2786
2804
|
}
|
|
2787
|
-
catch { }
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
|
-
let readyEntry;
|
|
2791
|
-
for (const entry of aliveEntries) {
|
|
2792
|
-
if (await probeEcwebReady(entry.record.port)) {
|
|
2793
|
-
readyEntry = entry;
|
|
2794
|
-
break;
|
|
2795
2805
|
}
|
|
2796
2806
|
}
|
|
2797
2807
|
if (readyEntry) {
|
|
2798
2808
|
console.log('');
|
|
2799
|
-
|
|
2809
|
+
const pidVisible = aliveEntries.some(entry => entry.filePath === readyEntry.filePath);
|
|
2810
|
+
const pidText = pidVisible ? `PID: ${readyEntry.record.pid}` : `PID: ${readyEntry.record.pid}(当前 namespace 不可见)`;
|
|
2811
|
+
console.log(`🔭 ECWeb: 运行中 (${pidText}) http://localhost:${readyEntry.record.port}`);
|
|
2800
2812
|
return;
|
|
2801
2813
|
}
|
|
2802
2814
|
const occupiedPids = new Set();
|
|
@@ -2991,7 +3003,7 @@ export async function startEcwebIfEnabled(p, options = {}) {
|
|
|
2991
3003
|
console.log(`✓ ECWeb ${actionLabel} (PID: ${pid}) http://localhost:${port}`);
|
|
2992
3004
|
if (pair) {
|
|
2993
3005
|
const mins = Math.max(0, Math.round((pair.expiresAt - Date.now()) / 60000));
|
|
2994
|
-
console.log(` 配对码: ${pair.code} (约 ${mins}
|
|
3006
|
+
console.log(` 配对码: ${pair.code} (约 ${mins} 分钟内有效,仅可配对一次,已配对过的浏览器无需重新配对)`);
|
|
2995
3007
|
}
|
|
2996
3008
|
else {
|
|
2997
3009
|
console.log(' daemon 尚未提供配对码;EvolCore 启动后可通过 /pair 或 ECWeb 页面获取');
|
|
@@ -3027,7 +3039,7 @@ async function printEcwebAccess(port) {
|
|
|
3027
3039
|
}
|
|
3028
3040
|
if (pair) {
|
|
3029
3041
|
const mins = Math.max(0, Math.round((pair.expiresAt - Date.now()) / 60000));
|
|
3030
|
-
console.log(` 配对码: ${pair.code} (约 ${mins}
|
|
3042
|
+
console.log(` 配对码: ${pair.code} (约 ${mins} 分钟内有效,仅可配对一次,token 缓存 7 天,有访问自动续期)`);
|
|
3031
3043
|
}
|
|
3032
3044
|
else {
|
|
3033
3045
|
console.log(' 配对码: 暂不可用(稍后重试 ec watch web,或查看 logs/watch-web.log)');
|
package/dist/cli/diag.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ipcQuery } from '../ipc.js';
|
|
2
2
|
import { resolvePaths } from '../paths.js';
|
|
3
|
-
import {
|
|
3
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
4
|
import { parseDiagArgs } from '../core/command/diag-service.js';
|
|
5
5
|
import { wantsHelp } from './help.js';
|
|
6
6
|
export async function cmdDiag(args) {
|
|
@@ -17,7 +17,7 @@ export async function cmdDiag(args) {
|
|
|
17
17
|
type: 'diag', argv,
|
|
18
18
|
...(process.env.EVOLCORE_SESSION_ID ? {
|
|
19
19
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
20
|
-
delegationToken:
|
|
20
|
+
delegationToken: readDelegationCredential(),
|
|
21
21
|
} : {}),
|
|
22
22
|
}, 30_000) ?? { ok: false, code: 'DAEMON_UNAVAILABLE', message: 'daemon 未返回结果,请检查其运行状态;发送结果尚未确认' };
|
|
23
23
|
}
|
package/dist/cli/fs-command.js
CHANGED
|
@@ -5,8 +5,8 @@ import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
|
5
5
|
import { agentmdGet, getAidStore, isValidAid, loadClient, SLOT } from '../aun/aid/index.js';
|
|
6
6
|
import { ipcQuery } from '../ipc.js';
|
|
7
7
|
import { resolvePaths } from '../paths.js';
|
|
8
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
9
|
-
import { downloadGroupFsBytes } from '../aun/group
|
|
8
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
9
|
+
import { downloadGroupFsBytes } from '../aun/group/index.js';
|
|
10
10
|
class FsCliError extends Error {
|
|
11
11
|
code;
|
|
12
12
|
suggestion;
|
|
@@ -209,7 +209,7 @@ export async function cmdFs(args) {
|
|
|
209
209
|
}
|
|
210
210
|
async function runManagedFs(args, formatJson) {
|
|
211
211
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
212
|
-
const delegationToken =
|
|
212
|
+
const delegationToken = readDelegationCredential();
|
|
213
213
|
const fail = (code, message) => {
|
|
214
214
|
if (formatJson)
|
|
215
215
|
console.log(JSON.stringify({ ok: false, code, error: message }));
|
|
@@ -4,7 +4,7 @@ import { ipcQuery } from '../ipc.js';
|
|
|
4
4
|
import { HANDOFF_QUERY_DEFAULT_LIMIT, HANDOFF_QUERY_MAX_LIMIT, HANDOFF_STATES } from '../core/handoff/types.js';
|
|
5
5
|
import { HANDOFF_ID_RE } from '../core/handoff/store.js';
|
|
6
6
|
import { isHelpFlag, wantsHelp } from './help.js';
|
|
7
|
-
import {
|
|
7
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
8
8
|
function parseLimit(value) {
|
|
9
9
|
const limit = Number(value);
|
|
10
10
|
if (!value || !Number.isInteger(limit) || limit < 1 || limit > HANDOFF_QUERY_MAX_LIMIT) {
|
|
@@ -186,7 +186,7 @@ Commands:
|
|
|
186
186
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
187
187
|
handoffId: parsed.handoffId,
|
|
188
188
|
content: parsed.content,
|
|
189
|
-
delegationToken:
|
|
189
|
+
delegationToken: readDelegationCredential(),
|
|
190
190
|
}, 5000);
|
|
191
191
|
if (!result) {
|
|
192
192
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -216,7 +216,7 @@ Commands:
|
|
|
216
216
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
217
217
|
handoffId: parsed.handoffId,
|
|
218
218
|
content: parsed.content,
|
|
219
|
-
delegationToken:
|
|
219
|
+
delegationToken: readDelegationCredential(),
|
|
220
220
|
}, 5000);
|
|
221
221
|
if (!result) {
|
|
222
222
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -235,7 +235,7 @@ Commands:
|
|
|
235
235
|
}
|
|
236
236
|
const result = await ipcQuery(resolvePaths().socket, {
|
|
237
237
|
type: 'handoff-status', sessionId: process.env.EVOLCORE_SESSION_ID, handoffId,
|
|
238
|
-
delegationToken:
|
|
238
|
+
delegationToken: readDelegationCredential(),
|
|
239
239
|
}, 5000);
|
|
240
240
|
if (!result) {
|
|
241
241
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -267,7 +267,7 @@ Commands:
|
|
|
267
267
|
state: parsed.state,
|
|
268
268
|
filterSessionId: parsed.sessionId,
|
|
269
269
|
limit: parsed.limit,
|
|
270
|
-
delegationToken:
|
|
270
|
+
delegationToken: readDelegationCredential(),
|
|
271
271
|
}, 5000);
|
|
272
272
|
if (!result) {
|
|
273
273
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -310,7 +310,7 @@ Commands:
|
|
|
310
310
|
agent: parsed.agent,
|
|
311
311
|
handoffId: parsed.handoffId,
|
|
312
312
|
limit: parsed.limit,
|
|
313
|
-
delegationToken:
|
|
313
|
+
delegationToken: readDelegationCredential(),
|
|
314
314
|
}, 5000);
|
|
315
315
|
if (!result) {
|
|
316
316
|
console.error('✗ daemon 暂时不可用');
|
package/dist/cli/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import fs from 'fs';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { getPackageRoot, resolvePaths } from '../paths.js';
|
|
7
7
|
import { ipcQuery } from '../ipc.js';
|
|
8
|
-
import {
|
|
8
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
9
9
|
import { cmdInit } from './init.js';
|
|
10
10
|
import { cmdInitWechat, cmdInitFeishu, cmdInitDingtalk, cmdInitQQBot, cmdInitWecom, cmdInitAun } from './init-channel.js';
|
|
11
11
|
import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
|
|
@@ -34,6 +34,7 @@ Agent 与会话:
|
|
|
34
34
|
agent 管理 EvolAgent
|
|
35
35
|
ctl 当前托管会话的控制命令
|
|
36
36
|
queue 查询或操作 agent 消息队列
|
|
37
|
+
task 恢复暂停或异常中断的会话任务
|
|
37
38
|
trigger 管理定时与事件触发器
|
|
38
39
|
handoff 查询和完成跨会话回流
|
|
39
40
|
model 查看或设置模型与推理强度
|
|
@@ -247,7 +248,7 @@ export async function main(args) {
|
|
|
247
248
|
}
|
|
248
249
|
if (process.env.EVOLCORE_SESSION_ID) {
|
|
249
250
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
250
|
-
const delegationToken =
|
|
251
|
+
const delegationToken = readDelegationCredential();
|
|
251
252
|
const result = await ipcQuery(resolvePaths().socket, {
|
|
252
253
|
type: 'status.auth', sessionId, delegationToken,
|
|
253
254
|
});
|
|
@@ -328,6 +329,11 @@ export async function main(args) {
|
|
|
328
329
|
case 'queue':
|
|
329
330
|
await cmdQueue(args.slice(1));
|
|
330
331
|
break;
|
|
332
|
+
case 'task': {
|
|
333
|
+
const { cmdTask } = await import('./task-command.js');
|
|
334
|
+
await cmdTask(args.slice(1));
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
331
337
|
case 'trigger':
|
|
332
338
|
{
|
|
333
339
|
const { cmdTrigger } = await import('./trigger-command.js');
|
package/dist/cli/init.js
CHANGED
|
@@ -7,7 +7,7 @@ import { commandExists } from '../utils/cross-platform.js';
|
|
|
7
7
|
import { scanInstances } from '../utils/instance-registry.js';
|
|
8
8
|
import { saveDefaultsSafe, loadAllAgents, loadDaemonConfig, saveDaemonConfig } from '../config-store.js';
|
|
9
9
|
import { ecwebService, setEcwebEnabled } from '../config/daemon-services.js';
|
|
10
|
-
import { generateControlAid, resolveControlAidDomain } from '../aun/aid/control-aid.js';
|
|
10
|
+
import { ensureControlAgentMd, generateControlAid, resolveControlAidDomain } from '../aun/aid/control-aid.js';
|
|
11
11
|
import { getCodexAppServerAvailability } from '../agents/codex-runner.js';
|
|
12
12
|
import { DEFAULT_ECAGENT_BASE_URL, resolveEcagentConfig } from '../agents/baseagent.js';
|
|
13
13
|
import { defaultProjectsRoot } from '../utils/project-path.js';
|
|
@@ -484,6 +484,12 @@ export async function initTail(options = {}) {
|
|
|
484
484
|
let ownerBindingInterrupted = false;
|
|
485
485
|
if (daemonConfig.aid) {
|
|
486
486
|
console.log(`✓ 控制 AID 已存在: ${daemonConfig.aid}`);
|
|
487
|
+
try {
|
|
488
|
+
await ensureControlAgentMd(daemonConfig.aid);
|
|
489
|
+
}
|
|
490
|
+
catch (e) {
|
|
491
|
+
console.error(`⚠️ 控制 AID agent.md 补全失败(本次继续,后续启动会重试): ${e?.message || e}`);
|
|
492
|
+
}
|
|
487
493
|
}
|
|
488
494
|
else {
|
|
489
495
|
try {
|
|
@@ -861,6 +867,33 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
861
867
|
fail('CONTROL_AID_CREATE_FAILED', `control AID creation failed: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
862
868
|
}
|
|
863
869
|
}
|
|
870
|
+
if (controlAid) {
|
|
871
|
+
const certPath = path.join(resolvePaths().root, 'AIDs', controlAid, 'public', 'cert.pem');
|
|
872
|
+
if (!fs.existsSync(certPath)) {
|
|
873
|
+
// An externally supplied/pre-created AID without a local certificate
|
|
874
|
+
// cannot be signed or uploaded by this process. Avoid entering the SDK
|
|
875
|
+
// network path during non-interactive init; later daemon startup can
|
|
876
|
+
// retry once the identity material is provisioned.
|
|
877
|
+
console.error(`control AID agent.md publish skipped: local certificate not found for ${controlAid}`);
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
try {
|
|
881
|
+
await ensureControlAgentMd(controlAid);
|
|
882
|
+
}
|
|
883
|
+
catch (e) {
|
|
884
|
+
// A registered control AID remains usable when the Name Service is
|
|
885
|
+
// temporarily unavailable; startup and the next init retry publication.
|
|
886
|
+
if (format === 'json') {
|
|
887
|
+
// Keep the successful init result machine-readable; surface the
|
|
888
|
+
// warning through stderr so stdout remains valid JSON.
|
|
889
|
+
console.error(`control AID agent.md publish warning: ${e?.message || e}`);
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
console.error(`⚠️ 控制 AID agent.md 补全失败(本次继续,后续启动会重试): ${e?.message || e}`);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
864
897
|
// ── 9. 写 daemon.json(aid + owners + ecweb)──
|
|
865
898
|
try {
|
|
866
899
|
const next = {
|
|
@@ -20,6 +20,7 @@ const MANAGED_TASK_COMMANDS = new Set([
|
|
|
20
20
|
'stats',
|
|
21
21
|
'status',
|
|
22
22
|
'storage',
|
|
23
|
+
'task',
|
|
23
24
|
'trigger',
|
|
24
25
|
'version',
|
|
25
26
|
'-v',
|
|
@@ -30,7 +31,7 @@ export class ManagedCommandNotAllowedError extends Error {
|
|
|
30
31
|
command;
|
|
31
32
|
code = 'NOT_ALLOWED';
|
|
32
33
|
constructor(command) {
|
|
33
|
-
super(`Command ${command} is not available in a managed Agent task`);
|
|
34
|
+
super(`Command ${command} is not available in a managed Agent task; run it from the host terminal after the task completes`);
|
|
34
35
|
this.command = command;
|
|
35
36
|
this.name = 'ManagedCommandNotAllowedError';
|
|
36
37
|
}
|
package/dist/cli/menu-client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { getArgValue, wantsHelp } from './help.js';
|
|
3
|
-
import { executeMenuClientRequest, MenuClientError } from '../aun/menu
|
|
4
|
-
import {
|
|
3
|
+
import { executeMenuClientRequest, MenuClientError } from '../aun/menu/index.js';
|
|
4
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
5
5
|
function parseDurationMs(value) {
|
|
6
6
|
if (value === undefined)
|
|
7
7
|
return undefined;
|
|
@@ -94,12 +94,16 @@ export async function cmdMenuClient(args) {
|
|
|
94
94
|
}
|
|
95
95
|
let response;
|
|
96
96
|
if (process.env.EVOLCORE_SESSION_ID) {
|
|
97
|
-
const { ipcQuery } = await import('../ipc.js');
|
|
97
|
+
const { ipcQuery, IpcTransportError } = await import('../ipc.js');
|
|
98
98
|
const { resolvePaths } = await import('../paths.js');
|
|
99
99
|
const result = await ipcQuery(resolvePaths().socket, {
|
|
100
100
|
type: 'menu-client.request', argv: args, sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
101
|
-
delegationToken:
|
|
102
|
-
}, 250_000)
|
|
101
|
+
delegationToken: readDelegationCredential(),
|
|
102
|
+
}, 250_000, { throwOnError: true }).catch(error => {
|
|
103
|
+
if (!(error instanceof IpcTransportError))
|
|
104
|
+
throw error;
|
|
105
|
+
throw new MenuClientError(error.code, error.message);
|
|
106
|
+
});
|
|
103
107
|
if (!result?.ok)
|
|
104
108
|
throw new MenuClientError(result?.code ?? 'DAEMON_UNAVAILABLE', result?.error ?? 'Managed Menu daemon is unavailable');
|
|
105
109
|
response = result.response;
|
package/dist/cli/model.js
CHANGED
|
@@ -20,7 +20,7 @@ import { ipcQuery } from '../ipc.js';
|
|
|
20
20
|
import { parsePeerKey } from '../core/relation/peer-identity.js';
|
|
21
21
|
import { resolvePeerRoleDetail } from '../config/peer-role-resolver.js';
|
|
22
22
|
import { getFieldPermission } from '../config/roles.js';
|
|
23
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
23
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
24
24
|
import { formatModelCheck, runModelCheck } from '../core/model/model-diagnostics.js';
|
|
25
25
|
import { validateRuntimeStringFieldOverride } from '../core/role/runtime-policy.js';
|
|
26
26
|
const ALL_EFFORTS = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'auto'];
|
|
@@ -61,7 +61,7 @@ async function runCtlCommand(cmd, formatJson, timeoutMs = 10_000) {
|
|
|
61
61
|
type: 'ctl',
|
|
62
62
|
cmd,
|
|
63
63
|
sessionId,
|
|
64
|
-
delegationToken:
|
|
64
|
+
delegationToken: readDelegationCredential(),
|
|
65
65
|
}, timeoutMs);
|
|
66
66
|
if (!result)
|
|
67
67
|
fail(formatJson, 'DAEMON_UNAVAILABLE', '无法连接 evolcore 服务');
|
|
@@ -80,7 +80,7 @@ async function runManagedConfigOperation(args, formatJson) {
|
|
|
80
80
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
81
81
|
if (!sessionId)
|
|
82
82
|
fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID 未设置');
|
|
83
|
-
const delegationToken =
|
|
83
|
+
const delegationToken = readDelegationCredential();
|
|
84
84
|
if (!delegationToken) {
|
|
85
85
|
fail(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} 未设置`);
|
|
86
86
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolvePaths } from '../paths.js';
|
|
2
2
|
import { ipcQuery } from '../ipc.js';
|
|
3
|
-
import {
|
|
3
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
4
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
5
5
|
export async function cmdQueue(args) {
|
|
6
6
|
if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
|
|
@@ -98,7 +98,7 @@ JSON 时间字段:
|
|
|
98
98
|
after,
|
|
99
99
|
before,
|
|
100
100
|
sessionId: managed,
|
|
101
|
-
delegationToken:
|
|
101
|
+
delegationToken: readDelegationCredential(),
|
|
102
102
|
} : {
|
|
103
103
|
type: 'queue-snapshot',
|
|
104
104
|
agent,
|
package/dist/cli/response.js
CHANGED
|
@@ -17,7 +17,7 @@ import { ResponseModeRegistry } from '../response-system/registry.js';
|
|
|
17
17
|
import { registerBuiltinModes } from '../response-system/modes/index.js';
|
|
18
18
|
import { ipcQuery } from '../ipc.js';
|
|
19
19
|
import { resolvePaths } from '../paths.js';
|
|
20
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
20
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
21
21
|
const RESPONSE_MODE_FIELD = 'responseMode';
|
|
22
22
|
const RESPONSE_MODE_PARAMS_FIELD = 'responseModeParams';
|
|
23
23
|
/**
|
|
@@ -59,7 +59,7 @@ function fail(formatJson, code, message) {
|
|
|
59
59
|
}
|
|
60
60
|
async function managedConfig(fieldArgs, formatJson) {
|
|
61
61
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
62
|
-
const delegationToken =
|
|
62
|
+
const delegationToken = readDelegationCredential();
|
|
63
63
|
if (!sessionId)
|
|
64
64
|
fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
65
65
|
if (!delegationToken)
|
|
@@ -17,6 +17,8 @@ import { inspectDataMigrationRequirement } from '../core/data-migration.js';
|
|
|
17
17
|
import { DAEMON_SHUTDOWN_TIMEOUT_MS, requestDaemonShutdown } from './daemon-commands.js';
|
|
18
18
|
import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
|
|
19
19
|
const execFileAsync = promisify(execFile);
|
|
20
|
+
// Bound network notifications so they cannot hold up recovery after shutdown.
|
|
21
|
+
const OWNER_NOTIFICATION_TIMEOUT_MS = 5000;
|
|
20
22
|
/**
|
|
21
23
|
* The package this monitor operates on, which is not always the one it runs
|
|
22
24
|
* from.
|
|
@@ -480,6 +482,18 @@ async function sendHealSummary(p, attempts, log) {
|
|
|
480
482
|
function sleep(ms) {
|
|
481
483
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
482
484
|
}
|
|
485
|
+
function withTimeout(promise, timeoutMs) {
|
|
486
|
+
let timer;
|
|
487
|
+
const timeout = new Promise((_, reject) => {
|
|
488
|
+
timer = setTimeout(() => reject(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs);
|
|
489
|
+
// Keep the monitor alive until recovery can resume, even if the SDK's
|
|
490
|
+
// pending operation has no referenced handles of its own.
|
|
491
|
+
});
|
|
492
|
+
return Promise.race([promise, timeout]).finally(() => {
|
|
493
|
+
if (timer)
|
|
494
|
+
clearTimeout(timer);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
483
497
|
function normalizePath(value) {
|
|
484
498
|
return value.replace(/[\\/]+/g, '/').toLowerCase();
|
|
485
499
|
}
|
|
@@ -1009,12 +1023,12 @@ async function notifyDaemonOwners(p, message, log) {
|
|
|
1009
1023
|
const text = formatDaemonOwnerNotice(p, message);
|
|
1010
1024
|
for (const owner of validOwners) {
|
|
1011
1025
|
try {
|
|
1012
|
-
const result = await msgSend({
|
|
1026
|
+
const result = await withTimeout(msgSend({
|
|
1013
1027
|
from: daemonAid,
|
|
1014
1028
|
to: owner,
|
|
1015
1029
|
body: { mode: 'text', text },
|
|
1016
1030
|
slotId: 'restart-monitor',
|
|
1017
|
-
});
|
|
1031
|
+
}), OWNER_NOTIFICATION_TIMEOUT_MS);
|
|
1018
1032
|
if (!result.ok) {
|
|
1019
1033
|
log(`Daemon owner notification failed for ${owner}: ${result.error}`);
|
|
1020
1034
|
continue;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { resolvePaths } from '../paths.js';
|
|
2
|
+
import { ipcQuery } from '../ipc.js';
|
|
3
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
|
+
import { wantsHelp } from './help.js';
|
|
5
|
+
const TASK_HELP = `用法: ec task resume <sessionId> [--format json]
|
|
6
|
+
|
|
7
|
+
恢复指定 EvolCore 会话的暂停任务或异常中断任务。
|
|
8
|
+
暂停时释放工具门控;异常中断时继续原 baseagent 会话。
|
|
9
|
+
已完成、正在执行或等待必要输入/审批的任务不会重复启动。
|
|
10
|
+
|
|
11
|
+
独立 CLI 使用本地 control token;托管任务使用当前会话的 delegation,
|
|
12
|
+
需有 Agent 管理权限,普通托管任务只能恢复本 Agent 的会话。`;
|
|
13
|
+
export async function cmdTask(args) {
|
|
14
|
+
if (!args.length || wantsHelp(args)) {
|
|
15
|
+
console.log(TASK_HELP);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const json = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
|
|
19
|
+
const printError = (code, error) => {
|
|
20
|
+
if (json)
|
|
21
|
+
console.log(JSON.stringify({ ok: false, code, error }));
|
|
22
|
+
else
|
|
23
|
+
console.error(error);
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
};
|
|
26
|
+
const targetSessionId = args[1]?.trim();
|
|
27
|
+
if (args[0] !== 'resume' || !targetSessionId || targetSessionId.startsWith('-')
|
|
28
|
+
|| !(args.length === 2 || (args.length === 4 && args[2] === '--format' && args[3] === 'json'))) {
|
|
29
|
+
printError('INVALID_ARGUMENT', TASK_HELP);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
33
|
+
const delegationToken = readDelegationCredential();
|
|
34
|
+
if (sessionId !== undefined && !sessionId.trim()) {
|
|
35
|
+
printError('INVALID_DELEGATION', 'EVOLCORE_SESSION_ID 不能为空');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (sessionId && !delegationToken) {
|
|
39
|
+
printError('DELEGATION_REQUIRED', '托管任务缺少 delegation token');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const result = await ipcQuery(resolvePaths().socket, {
|
|
43
|
+
type: 'task.resume',
|
|
44
|
+
targetSessionId,
|
|
45
|
+
...(sessionId ? { sessionId, delegationToken } : {}),
|
|
46
|
+
}, 10_000);
|
|
47
|
+
if (!result) {
|
|
48
|
+
printError('IPC_UNAVAILABLE', '无法连接 EvolCore 服务;请查询任务状态后再决定是否重试');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (json)
|
|
52
|
+
console.log(JSON.stringify(result));
|
|
53
|
+
else if ('message' in result)
|
|
54
|
+
console.log(result.message);
|
|
55
|
+
else
|
|
56
|
+
console.error(result.error);
|
|
57
|
+
if (!result.ok)
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
}
|