evolcore 0.0.26 → 0.0.28
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 +36 -0
- package/bin/codex-managed-acl.ps1 +43 -0
- package/dist/agents/baseagent-availability.js +68 -0
- package/dist/agents/baseagent.js +10 -5
- package/dist/agents/claude-runner.js +123 -22
- package/dist/agents/codex/app-server-client.js +70 -26
- package/dist/agents/codex/catalog.js +7 -1
- package/dist/agents/codex-runner.js +363 -421
- 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} +13 -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 +544 -239
- 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 +111 -162
- package/dist/cli/diag.js +3 -3
- 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 +13 -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 +81 -19
- 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 +105 -40
- package/dist/core/command/data-root-resolver.js +273 -0
- package/dist/core/command/diag-service.js +292 -27
- 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 +364 -96
- package/dist/core/command/menu-protocol.js +43 -6
- package/dist/core/command/role-menu.js +2 -2
- package/dist/core/command/slash-handler.js +61 -37
- 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 +94 -16
- package/dist/core/message/message-bridge.js +140 -13
- 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 +729 -118
- package/dist/core/permission/approval-gateway.js +36 -3
- package/dist/core/permission/ec-command-parser.js +76 -36
- 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 +8 -8
- 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 +38 -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 +322 -207
- package/dist/ipc.js +141 -15
- package/dist/paths.js +17 -4
- package/dist/product.js +3 -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/atomic-write.js +98 -0
- package/dist/utils/cross-platform.js +87 -16
- 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/npm-ops.js +119 -4
- package/dist/utils/package-version-info.js +244 -0
- package/dist/utils/tool-summary.js +59 -3
- package/dist/utils/welcome.js +174 -1
- package/dist/utils/windows-shell-trust.js +37 -0
- 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 +23 -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
package/dist/cli/agent.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import {
|
|
3
|
+
import { SESSION_ID_ENV } from '../product.js';
|
|
4
|
+
import { resolvePaths, agentMdPath as getAgentMdPathFromPaths, agentPersonalDir, agentWelcomePath, aunPath as defaultAunPath } from '../paths.js';
|
|
4
5
|
import { loadDefaults, loadAllAgents, loadAgent, saveAgent, ensureAgentDirSkeleton } from '../config-store.js';
|
|
5
6
|
import { initConfigManager } from '../config/config-manager.js';
|
|
6
7
|
import { resolveConfigCommand } from '../config/resolved-config-op.js';
|
|
@@ -10,16 +11,21 @@ import { CONFIG_SCHEMA_VERSION } from '../types.js';
|
|
|
10
11
|
import { ensureInitialRoleRegistry } from '../config/role-service.js';
|
|
11
12
|
import { agentProjectRootFromDefaults, deriveAgentProjectPath } from '../utils/project-path.js';
|
|
12
13
|
import { isValidChannelName } from '../core/channel-loader.js';
|
|
13
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
14
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
14
15
|
import { readTaskRuntimeContextFromEnv } from './task-context.js';
|
|
16
|
+
import { isValidAid } from '../aun/aid/validation.js';
|
|
15
17
|
import { isHClassPath, isLClassPath, isSameOrDescendant } from '../core/permission/protected-paths.js';
|
|
18
|
+
import { findPostBootstrapWelcomeOutbox } from '../core/bootstrap-messages.js';
|
|
19
|
+
import { resolveAgentLifecycle } from '../config/lifecycle.js';
|
|
20
|
+
import { initializationSummary } from './agent-create.js';
|
|
21
|
+
import { parseAgentWelcomeMetadata, readAgentWelcomeTemplate, renderPostBootstrapWelcomeMessage, saveAgentWelcomeTemplate, validateWelcomeTemplate } from '../utils/welcome.js';
|
|
16
22
|
export { agentCreateInteractive, agentCreateNonInteractive, parseAgentOwnerArgs, resolveAgentCreatePlan, validateAgentCreatePlan, validateAgentOwnerOptions, } from './agent-create.js';
|
|
17
23
|
/** Route agent lifecycle commands from a managed task through daemon IPC. */
|
|
18
24
|
export async function runManagedAgentOperation(argv) {
|
|
19
25
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
20
26
|
if (!sessionId)
|
|
21
27
|
return { ok: false, code: 'MANAGED_ONLY', error: 'agent operation is not running in a managed task' };
|
|
22
|
-
const delegationToken =
|
|
28
|
+
const delegationToken = readDelegationCredential();
|
|
23
29
|
if (!delegationToken) {
|
|
24
30
|
return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
|
|
25
31
|
}
|
|
@@ -74,6 +80,7 @@ function toAgentListItem(info, stale = false) {
|
|
|
74
80
|
name: info.name,
|
|
75
81
|
personalName: info.personalName || null,
|
|
76
82
|
status: stale && storedStatus !== 'disabled' && storedStatus !== 'error' ? 'unknown' : storedStatus,
|
|
83
|
+
lifecycle: info.lifecycle ?? null,
|
|
77
84
|
channels: info.channels || [],
|
|
78
85
|
projectPath: toPosix(info.projectPath || null),
|
|
79
86
|
baseagent: info.baseagent || null,
|
|
@@ -158,6 +165,27 @@ export async function agentShow(aid) {
|
|
|
158
165
|
registry.loadAll();
|
|
159
166
|
const agent = registry.get(aid);
|
|
160
167
|
if (!agent) {
|
|
168
|
+
const init = initializationSummary(aid);
|
|
169
|
+
if (init) {
|
|
170
|
+
return {
|
|
171
|
+
ok: true,
|
|
172
|
+
aid,
|
|
173
|
+
status: 'initializing',
|
|
174
|
+
lifecycle: loadAgent(aid)?.lifecycle ?? null,
|
|
175
|
+
identity: { name: null, description: null },
|
|
176
|
+
config: { baseagent: null, model: null, effort: null, chatmode: null, channels: [] },
|
|
177
|
+
connection: null,
|
|
178
|
+
sessions: { active: 0, last_activity: null },
|
|
179
|
+
paths: {
|
|
180
|
+
config: toPosix(path.join(p.agentsDir, aid, 'config.json')),
|
|
181
|
+
agent_md: toPosix(getAgentMdPath(aid)),
|
|
182
|
+
project: null,
|
|
183
|
+
data: toPosix(path.join(p.agentsDir, aid, 'data')),
|
|
184
|
+
},
|
|
185
|
+
initialization: init,
|
|
186
|
+
stale: true,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
161
189
|
const allList = registry.list();
|
|
162
190
|
const available = allList.map((i) => i.name).join(', ');
|
|
163
191
|
return { ok: false, error: `Agent "${aid}" not found.${available ? ` Available: ${available}` : ''}` };
|
|
@@ -203,6 +231,7 @@ export async function agentShow(aid) {
|
|
|
203
231
|
project: toPosix(agentInfo.projectPath || null),
|
|
204
232
|
data: toPosix(path.join(p.agentsDir, aid, 'data')),
|
|
205
233
|
},
|
|
234
|
+
...(initializationSummary(aid) ? { initialization: initializationSummary(aid) } : {}),
|
|
206
235
|
...(stale ? { stale: true } : {}),
|
|
207
236
|
};
|
|
208
237
|
}
|
|
@@ -362,7 +391,7 @@ async function runManagedAgentConfig(args, options) {
|
|
|
362
391
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
363
392
|
if (!sessionId || options.trustedLocal)
|
|
364
393
|
return { managed: false };
|
|
365
|
-
const delegationToken =
|
|
394
|
+
const delegationToken = readDelegationCredential();
|
|
366
395
|
if (!delegationToken) {
|
|
367
396
|
return {
|
|
368
397
|
managed: true,
|
|
@@ -469,7 +498,7 @@ export async function agentSet(aid, key, rawValue, options = {}) {
|
|
|
469
498
|
return { ok: true, aid, key, value, reloaded };
|
|
470
499
|
}
|
|
471
500
|
export const AGENT_PERSONA_MAX_BYTES = 64 * 1024;
|
|
472
|
-
function validatePersonaContent(content) {
|
|
501
|
+
export function validatePersonaContent(content) {
|
|
473
502
|
if (content.includes('\0'))
|
|
474
503
|
return 'persona 只能包含文本内容';
|
|
475
504
|
if (Buffer.byteLength(content, 'utf8') > AGENT_PERSONA_MAX_BYTES) {
|
|
@@ -569,6 +598,78 @@ export async function agentPersona(aid, options = {}) {
|
|
|
569
598
|
return { ok: false, code: 'WRITE_FAILED', error: e?.message || String(e) };
|
|
570
599
|
}
|
|
571
600
|
}
|
|
601
|
+
/** Read or replace the current Agent's confirmed Bootstrap welcome template. */
|
|
602
|
+
export async function agentWelcome(aid, options = {}) {
|
|
603
|
+
if (!isValidAid(aid))
|
|
604
|
+
return { ok: false, code: 'INVALID_ARGS', error: 'Invalid Agent AID' };
|
|
605
|
+
if (options.text !== undefined) {
|
|
606
|
+
const validation = validateWelcomeTemplate(options.text);
|
|
607
|
+
if (!validation.valid)
|
|
608
|
+
return { ok: false, code: 'INVALID_ARGS', error: validation.errors.join('; ') };
|
|
609
|
+
}
|
|
610
|
+
const managedSession = !!process.env[SESSION_ID_ENV] && !options.trustedLocal;
|
|
611
|
+
const managedArgs = options.text !== undefined
|
|
612
|
+
? ['welcome', '--text', options.text]
|
|
613
|
+
: ['welcome', 'show'];
|
|
614
|
+
if (managedSession) {
|
|
615
|
+
if (readTaskRuntimeContextFromEnv()?.selfAid !== aid) {
|
|
616
|
+
return { ok: false, code: 'SELF_AGENT_REQUIRED', error: 'welcome only targets the current Agent' };
|
|
617
|
+
}
|
|
618
|
+
const managed = await runManagedAgentOperation(managedArgs);
|
|
619
|
+
if (!managed.ok)
|
|
620
|
+
return managed;
|
|
621
|
+
return {
|
|
622
|
+
ok: true,
|
|
623
|
+
aid,
|
|
624
|
+
content: managed.content ?? null,
|
|
625
|
+
...(managed.path ? { path: managed.path } : {}),
|
|
626
|
+
...(managed.saved ? { saved: true } : {}),
|
|
627
|
+
...(managed.bytes !== undefined ? { bytes: managed.bytes } : {}),
|
|
628
|
+
...(managed.sha256 ? { sha256: managed.sha256 } : {}),
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
const config = loadAgent(aid);
|
|
632
|
+
if (!config)
|
|
633
|
+
return { ok: false, code: 'NOT_FOUND', error: 'Agent not found' };
|
|
634
|
+
if (options.text === undefined) {
|
|
635
|
+
try {
|
|
636
|
+
return { ok: true, aid, content: readAgentWelcomeTemplate(aid), path: agentWelcomePath(aid) };
|
|
637
|
+
}
|
|
638
|
+
catch (e) {
|
|
639
|
+
return { ok: false, code: 'READ_FAILED', error: e instanceof Error ? e.message : String(e) };
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (resolveAgentLifecycle(config) !== 'bootstrapping' || config.initialization) {
|
|
643
|
+
return { ok: false, code: 'INVALID_LIFECYCLE', error: 'welcome can only be saved during conversational Bootstrap' };
|
|
644
|
+
}
|
|
645
|
+
try {
|
|
646
|
+
if (findPostBootstrapWelcomeOutbox(aid, { includeTerminal: true }).length) {
|
|
647
|
+
if (readAgentWelcomeTemplate(aid) === options.text) {
|
|
648
|
+
return { ok: true, aid, content: options.text, saved: true, path: agentWelcomePath(aid), bytes: Buffer.byteLength(options.text, 'utf8') };
|
|
649
|
+
}
|
|
650
|
+
return { ok: false, code: 'WELCOME_FROZEN', error: 'welcome delivery has already been prepared; resume ready with the saved text' };
|
|
651
|
+
}
|
|
652
|
+
const mdPath = getAgentMdPath(aid);
|
|
653
|
+
const metadata = parseAgentWelcomeMetadata(fs.existsSync(mdPath) ? fs.readFileSync(mdPath, 'utf8') : '');
|
|
654
|
+
try {
|
|
655
|
+
for (const owner of config.owners?.length ? config.owners : [aid]) {
|
|
656
|
+
renderPostBootstrapWelcomeMessage({
|
|
657
|
+
template: options.text, agentName: metadata.name || aid.split('.')[0], agentAid: aid,
|
|
658
|
+
agentDescription: metadata.description, agentTags: metadata.tags,
|
|
659
|
+
ownerAid: owner, ownerName: owner.split('.')[0],
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
return { ok: false, code: 'WELCOME_INVALID', error: error.message };
|
|
665
|
+
}
|
|
666
|
+
const saved = saveAgentWelcomeTemplate(aid, options.text);
|
|
667
|
+
return { ok: true, aid, content: options.text, ...saved, saved: true };
|
|
668
|
+
}
|
|
669
|
+
catch (e) {
|
|
670
|
+
return { ok: false, code: 'WRITE_FAILED', error: e instanceof Error ? e.message : String(e) };
|
|
671
|
+
}
|
|
672
|
+
}
|
|
572
673
|
/**
|
|
573
674
|
* Add or overwrite a channel instance on a per-agent config.
|
|
574
675
|
*
|
|
@@ -704,7 +805,7 @@ export async function agentReady(aid) {
|
|
|
704
805
|
}
|
|
705
806
|
const p = resolvePaths();
|
|
706
807
|
try {
|
|
707
|
-
const delegationToken = managedSessionId ?
|
|
808
|
+
const delegationToken = managedSessionId ? readDelegationCredential() : undefined;
|
|
708
809
|
if (managedSessionId && !delegationToken) {
|
|
709
810
|
return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
|
|
710
811
|
}
|
|
@@ -714,11 +815,11 @@ export async function agentReady(aid) {
|
|
|
714
815
|
...(managedSessionId ? { sessionId: managedSessionId, delegationToken } : {}),
|
|
715
816
|
}, 30_000);
|
|
716
817
|
if (!result)
|
|
717
|
-
return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the
|
|
818
|
+
return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the EvolCore daemon; agent ready requires daemon IPC' };
|
|
718
819
|
if (!result.ok) {
|
|
719
820
|
return { ok: false, code: result.code, error: result.error || 'Failed to complete bootstrap' };
|
|
720
821
|
}
|
|
721
|
-
return { ok: true, aid, reloaded: true };
|
|
822
|
+
return { ...result, ok: true, aid, reloaded: result.reloaded === true };
|
|
722
823
|
}
|
|
723
824
|
catch (e) {
|
|
724
825
|
return {
|
package/dist/cli/aun-commands.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { agentMdPath, resolvePaths, resolveRoot } from '../paths.js';
|
|
4
|
-
import { isExplicitGroupId } from '../aun/group
|
|
4
|
+
import { isExplicitGroupId, normalizeGroupAid, sameGroupAid } from '../aun/group/index.js';
|
|
5
5
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
6
6
|
import { ipcQuery } from '../ipc.js';
|
|
7
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
7
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
8
8
|
import { isManagementRole } from '../config/builtin-roles.js';
|
|
9
9
|
import { readBestTaskRuntimeContext } from './task-context.js';
|
|
10
10
|
// ==================== AID ====================
|
|
@@ -107,7 +107,7 @@ async function runManagedAid(args, formatJson) {
|
|
|
107
107
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
108
108
|
if (!sessionId)
|
|
109
109
|
failManagedAid(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
110
|
-
const delegationToken =
|
|
110
|
+
const delegationToken = readDelegationCredential();
|
|
111
111
|
if (!delegationToken) {
|
|
112
112
|
failManagedAid(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
113
113
|
}
|
|
@@ -184,7 +184,7 @@ async function runManagedGroup(args, formatJson) {
|
|
|
184
184
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
185
185
|
if (!sessionId)
|
|
186
186
|
failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
187
|
-
const delegationToken =
|
|
187
|
+
const delegationToken = readDelegationCredential();
|
|
188
188
|
if (!delegationToken) {
|
|
189
189
|
failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
190
190
|
}
|
|
@@ -214,7 +214,7 @@ async function runManagedMsg(args, formatJson) {
|
|
|
214
214
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
215
215
|
if (!sessionId)
|
|
216
216
|
failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
217
|
-
const delegationToken =
|
|
217
|
+
const delegationToken = readDelegationCredential();
|
|
218
218
|
if (!delegationToken) {
|
|
219
219
|
failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
220
220
|
}
|
|
@@ -274,7 +274,7 @@ function validateManagedGroupScope(from, groupId, runtime, formatJson) {
|
|
|
274
274
|
if (runtime.channel !== 'aun' || runtime.chatType !== 'group') {
|
|
275
275
|
failManagedGroup(formatJson, 'ARGUMENT_MISMATCH', `当前角色 ${runtime.peerRole} 只能在 AUN 群聊任务中操作当前群`);
|
|
276
276
|
}
|
|
277
|
-
if (!runtime.channelId || groupId
|
|
277
|
+
if (!runtime.channelId || !sameGroupAid(groupId, runtime.channelId)) {
|
|
278
278
|
failManagedGroup(formatJson, 'ARGUMENT_MISMATCH', `当前角色 ${runtime.peerRole} 只能操作当前群 ${runtime.channelId ?? '<unknown>'},不能操作 ${groupId}`);
|
|
279
279
|
}
|
|
280
280
|
}
|
|
@@ -307,6 +307,27 @@ function renderManagedGroupResult(args, result, formatJson) {
|
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
309
|
const sub = args[0];
|
|
310
|
+
if (sub === 'history') {
|
|
311
|
+
if (result.mode === 'message')
|
|
312
|
+
console.log(result.content);
|
|
313
|
+
else {
|
|
314
|
+
console.log('本地群历史:' + result.count + ' 条');
|
|
315
|
+
for (const message of result.messages ?? []) {
|
|
316
|
+
console.log('[' + message.time + '] ' + message.from + ' → ' + message.to
|
|
317
|
+
+ ' thread=' + (message.threadId || 'main') + '\n' + message.content);
|
|
318
|
+
if (message.content_truncated)
|
|
319
|
+
console.log('正文尚未读完');
|
|
320
|
+
if (message.content_truncated && message.msgId) {
|
|
321
|
+
console.log('--all --message ' + message.msgId + ' --offset ' + message.next_offset);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (result.next_offset != null)
|
|
326
|
+
console.log('next_offset=' + result.next_offset);
|
|
327
|
+
if (result.has_more)
|
|
328
|
+
console.log('还有更多历史');
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
310
331
|
if (sub === 'list') {
|
|
311
332
|
if (!result.items?.length)
|
|
312
333
|
console.log('(没有加入任何群)');
|
|
@@ -317,8 +338,35 @@ function renderManagedGroupResult(args, result, formatJson) {
|
|
|
317
338
|
}
|
|
318
339
|
return;
|
|
319
340
|
}
|
|
341
|
+
if (sub === 'blocklist') {
|
|
342
|
+
const items = result.items ?? [];
|
|
343
|
+
console.log(items.length ? `共 ${result.total ?? items.length} 条屏蔽:` : '(没有屏蔽成员)');
|
|
344
|
+
for (const item of items) {
|
|
345
|
+
console.log(` ${item.subject ?? item.aid ?? '-'} blocked_by=${item.blocked_by ?? '-'} reason=${item.reason ?? ''}`);
|
|
346
|
+
}
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (sub === 'member-statuses') {
|
|
350
|
+
console.log(`成员上报状态(共 ${result.items?.length ?? 0} 名成员):`);
|
|
351
|
+
for (const item of result.items ?? []) {
|
|
352
|
+
console.log(` ${item.aid ?? '-'} online_status=${item.online_status || '(未上报)'} work_status=${item.work_status || '(未上报)'}`);
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (sub === 'report-status') {
|
|
357
|
+
console.log('✓ 已上报当前成员状态');
|
|
358
|
+
console.log(JSON.stringify(result.data?.status ?? {}, null, 2));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (sub === 'block' || sub === 'unblock') {
|
|
362
|
+
const target = result.data?.block?.subject ?? result.data?.subject ?? args[3];
|
|
363
|
+
console.log(`✓ 已${sub === 'block' ? '屏蔽' : '取消屏蔽'} ${target} 接收群消息`);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
320
366
|
if (sub === 'create') {
|
|
321
|
-
console.log(`✓ 已创建群 ${result.group?.group_id ?? '-'}`);
|
|
367
|
+
console.log(`✓ 已创建群 ${result.group?.group_aid ?? result.group?.group_id ?? '-'}`);
|
|
368
|
+
if (result.warning)
|
|
369
|
+
console.warn(result.warning);
|
|
322
370
|
return;
|
|
323
371
|
}
|
|
324
372
|
if (sub === 'rules' && args[3] === 'get' && result.status === 'ok') {
|
|
@@ -338,7 +386,7 @@ function renderManagedGroupResult(args, result, formatJson) {
|
|
|
338
386
|
return;
|
|
339
387
|
}
|
|
340
388
|
if (sub === 'accept-invite' || sub === 'reject-invite' || sub === 'revoke-invite') {
|
|
341
|
-
console.log(`✓ group ${sub} 完成`);
|
|
389
|
+
console.log(typeof result.message === 'string' ? result.message : `✓ group ${sub} 完成`);
|
|
342
390
|
return;
|
|
343
391
|
}
|
|
344
392
|
console.log(`✓ group ${sub} 完成`);
|
|
@@ -992,15 +1040,47 @@ Options:
|
|
|
992
1040
|
const operation = { ls: 'storage.list', quota: 'storage.quota', upload: 'storage.upload', download: 'storage.download', rm: 'storage.delete' }[sub];
|
|
993
1041
|
if (!operation)
|
|
994
1042
|
failManagedGroup(formatJson, 'NOT_ALLOWED', `unsupported managed storage command: ${sub}`);
|
|
995
|
-
const delegationToken =
|
|
1043
|
+
const delegationToken = readDelegationCredential();
|
|
996
1044
|
if (!delegationToken)
|
|
997
1045
|
failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
1046
|
+
if (sub === 'upload') {
|
|
1047
|
+
const localFile = args[2];
|
|
1048
|
+
const remotePath = args[3];
|
|
1049
|
+
if (!localFile || !remotePath) {
|
|
1050
|
+
console.error('用法: ec storage upload <aid> <local-file> <remote-path> [--public]');
|
|
1051
|
+
process.exit(1);
|
|
1052
|
+
}
|
|
1053
|
+
if (!fs.existsSync(localFile)) {
|
|
1054
|
+
console.error(`❌ 文件不存在: ${localFile}`);
|
|
1055
|
+
process.exit(1);
|
|
1056
|
+
}
|
|
1057
|
+
const result = await ipcQuery(resolvePaths().socket, {
|
|
1058
|
+
type: 'storage.upload',
|
|
1059
|
+
aid,
|
|
1060
|
+
localFile,
|
|
1061
|
+
remotePath,
|
|
1062
|
+
isPublic: args.includes('--public'),
|
|
1063
|
+
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
1064
|
+
delegationToken,
|
|
1065
|
+
}, null);
|
|
1066
|
+
if (!result)
|
|
1067
|
+
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
1068
|
+
if (!result.ok)
|
|
1069
|
+
failManagedGroup(formatJson, result.code || 'STORAGE_UPLOAD_FAILED', result.error || 'Storage upload failed');
|
|
1070
|
+
if (formatJson)
|
|
1071
|
+
console.log(JSON.stringify({ ok: true, objectKey: remotePath, isPublic: args.includes('--public'), ref: `${aid}/${remotePath}`, publicUrl: result.publicUrl ?? null }));
|
|
1072
|
+
else {
|
|
1073
|
+
console.log(`✓ 已上传: ${remotePath}${args.includes('--public') ? ' (公开)' : ''}`);
|
|
1074
|
+
if (result.publicUrl)
|
|
1075
|
+
console.log(` 🔗 访问: ${result.publicUrl}`);
|
|
1076
|
+
else
|
|
1077
|
+
console.log(` 引用: ${aid}/${remotePath}`);
|
|
1078
|
+
console.log(` 下载: ec storage download ${aid} ${aid}/${remotePath}`);
|
|
1079
|
+
}
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
998
1082
|
const authorization = await ipcQuery(resolvePaths().socket, {
|
|
999
|
-
type: 'storage.auth',
|
|
1000
|
-
operation,
|
|
1001
|
-
aid,
|
|
1002
|
-
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
1003
|
-
delegationToken,
|
|
1083
|
+
type: 'storage.auth', operation, aid, sessionId: process.env.EVOLCORE_SESSION_ID, delegationToken,
|
|
1004
1084
|
}, 10_000);
|
|
1005
1085
|
if (!authorization)
|
|
1006
1086
|
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
@@ -1443,26 +1523,12 @@ Options:
|
|
|
1443
1523
|
console.error(`❌ --return 仅支持 required|none: ${returnPolicyRaw}`);
|
|
1444
1524
|
process.exit(1);
|
|
1445
1525
|
}
|
|
1446
|
-
//
|
|
1447
|
-
let lastPctShown = -1;
|
|
1526
|
+
// SDK 尚未提供字节进度回调,只展示上传开始和成功完成。
|
|
1448
1527
|
const onUploadProgress = formatJson ? undefined : (info) => {
|
|
1449
|
-
if (info.phase === '
|
|
1450
|
-
|
|
1451
|
-
if (info.phase === '
|
|
1452
|
-
|
|
1453
|
-
if (pct === lastPctShown && info.bytes < info.total)
|
|
1454
|
-
return;
|
|
1455
|
-
lastPctShown = pct;
|
|
1456
|
-
const mb = (n) => (n / 1024 / 1024).toFixed(2);
|
|
1457
|
-
const eol = info.bytes >= info.total ? '\n' : '\r';
|
|
1458
|
-
process.stderr.write(` ⏫ uploading: ${pct}% (${mb(info.bytes)}/${mb(info.total)} MB)${eol}`);
|
|
1459
|
-
}
|
|
1460
|
-
else if (info.phase === 'session-create') {
|
|
1461
|
-
process.stderr.write(' ⏫ requesting upload session...\n');
|
|
1462
|
-
}
|
|
1463
|
-
else if (info.phase === 'session-complete') {
|
|
1464
|
-
process.stderr.write(' ⏫ finalizing upload...\n');
|
|
1465
|
-
}
|
|
1528
|
+
if (info.phase === 'upload')
|
|
1529
|
+
process.stderr.write(' ⏫ uploading...\n');
|
|
1530
|
+
else if (info.phase === 'done')
|
|
1531
|
+
process.stderr.write(' ✓ upload complete\n');
|
|
1466
1532
|
};
|
|
1467
1533
|
const result = await msgSend({ from, to, body, encrypt, thread, returnPolicy: returnPolicyRaw, handoffContext: getArgValue(args, '--handoff-context'), onUploadProgress, ...commonOpts });
|
|
1468
1534
|
if (!result.ok) {
|
|
@@ -1633,6 +1699,23 @@ export async function cmdGroup(args) {
|
|
|
1633
1699
|
const aunPath = resolveAunPath(args);
|
|
1634
1700
|
const formatJson = getArgValue(args, '--format') === 'json';
|
|
1635
1701
|
const appSlot = getArgValue(args, '--app');
|
|
1702
|
+
if (sub === 'history' && wantsHelp(args)) {
|
|
1703
|
+
console.log(`用法: ec group history <self-aid> <group-aid> --unread|--all [options]
|
|
1704
|
+
本地 messages.jsonl 查询,不访问 Gateway,不推进 group pull/ack 游标。
|
|
1705
|
+
--unread 返回最早未读的未提及背景,并自动记录本页已读
|
|
1706
|
+
--all 浏览群会话历史(返回最近 N 条),不改变已读状态
|
|
1707
|
+
--limit <N> 默认 50,范围 1–500;另有 24 KiB 单页消息预算
|
|
1708
|
+
--thread <main|all|id> 当前群任务缺省继承当前话题;其他调用缺省 all
|
|
1709
|
+
--direction <in|out|all> 按方向筛选,默认 all
|
|
1710
|
+
--before/--after <time> 按接收时间筛选,开区间;epoch 毫秒或 ISO 时间
|
|
1711
|
+
--format <text|json> 默认 text
|
|
1712
|
+
--message <msg-id> 配合 --all 查看指定长消息正文
|
|
1713
|
+
--offset <bytes> 配合 --message 从 next_offset 继续读取,默认 0
|
|
1714
|
+
--unread 返回的消息会记为已读;--all(包括 --all --message)始终只读,之后仍可回看。
|
|
1715
|
+
visitor 不开放历史;群权限仍由托管会话校验。
|
|
1716
|
+
旧日志通过 --all 查询,只有带本地未提及标记的新记录参与 --unread。`);
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1636
1719
|
const rulesActionHelp = sub === 'rules' && isHelpFlag(args[3]);
|
|
1637
1720
|
if (!sub || isHelpFlag(sub) || (wantsHelp(args) && !rulesActionHelp)) {
|
|
1638
1721
|
console.log(`用法: ec group <command> <from-aid> [args...] [options]
|
|
@@ -1643,6 +1726,7 @@ export async function cmdGroup(args) {
|
|
|
1643
1726
|
send <from> <group-id> --payload <json> 发送自定义 payload
|
|
1644
1727
|
pull <from> <group-id> [--after-seq N] [--limit N] --app <name> 拉取群消息(必须使用独立 slot)
|
|
1645
1728
|
ack <from> <group-id> <seq> [--app <name>] 确认已读
|
|
1729
|
+
history <from> <group-id> [--unread|--all] 查询本地群消息历史
|
|
1646
1730
|
|
|
1647
1731
|
群管理:
|
|
1648
1732
|
create <from> <name> [--visibility public|private] [--description D]
|
|
@@ -1673,6 +1757,11 @@ export async function cmdGroup(args) {
|
|
|
1673
1757
|
owner <from> <group-id> <new-owner-aid> 转让群主
|
|
1674
1758
|
ban <from> <group-id> [<member-aid>] [--duration N] 封禁成员;不带 member-aid 时列出封禁
|
|
1675
1759
|
unban <from> <group-id> <member-aid> 解封成员
|
|
1760
|
+
block <from> <group-id> <member-aid> [--reason R] 屏蔽成员接收群消息
|
|
1761
|
+
unblock <from> <group-id> <member-aid> 取消屏蔽
|
|
1762
|
+
blocklist <from> <group-id> 查看屏蔽列表(群管理员)
|
|
1763
|
+
report-status <from> <group-id> --online-status O --work-status W 上报自己的状态
|
|
1764
|
+
member-statuses <from> <group-id> 查看成员上报状态(独立于 online)
|
|
1676
1765
|
|
|
1677
1766
|
Options:
|
|
1678
1767
|
--app <name> 指定应用 slot(独立消费通道,不影响 daemon)
|
|
@@ -1688,7 +1777,7 @@ Options:
|
|
|
1688
1777
|
--as <type> 附件类型:image|video|voice|file(仅 --file 模式)
|
|
1689
1778
|
--text <说明> 附件说明文字(仅 --file 模式)
|
|
1690
1779
|
--transcript <text> 语音转写(仅 --as voice)
|
|
1691
|
-
--group-id <aid> 指定自定义群 AID(仅 create
|
|
1780
|
+
--group-id <aid> 指定自定义群 AID(仅 create);省略时生成 g- 加五位随机数字
|
|
1692
1781
|
--member-type <type> 定向邀请成员类型:human|agent(仅 invite)
|
|
1693
1782
|
-- end-of-options:其后所有参数按正文处理
|
|
1694
1783
|
(用于发送恰好等于某 flag 的文本,如 send a g -- --encrypt)
|
|
@@ -1703,7 +1792,11 @@ Options:
|
|
|
1703
1792
|
ec group members sender.example.invalid 12345.example.invalid
|
|
1704
1793
|
|
|
1705
1794
|
查询真实群 AID:
|
|
1706
|
-
ec group list <发送方AID
|
|
1795
|
+
ec group list <发送方AID>
|
|
1796
|
+
|
|
1797
|
+
群 AID 使用 base.issuer(如 ontology.example.invalid、g-12345.example.invalid)。
|
|
1798
|
+
群命令支持本域 base 简写;不再支持 group.issuer/base 或 base@issuer。
|
|
1799
|
+
g- 是名称的一部分,会完整保留;默认命名格式为 g-10000 至 g-99999。`);
|
|
1707
1800
|
return;
|
|
1708
1801
|
}
|
|
1709
1802
|
const from = args[1];
|
|
@@ -1720,13 +1813,55 @@ Options:
|
|
|
1720
1813
|
printGroupSendAidHint();
|
|
1721
1814
|
process.exit(1);
|
|
1722
1815
|
}
|
|
1723
|
-
if (process.env.EVOLCORE_SESSION_ID && sub !== 'send') {
|
|
1816
|
+
if ((process.env.EVOLCORE_SESSION_ID || (sub === 'history' && readDelegationCredential())) && sub !== 'send') {
|
|
1724
1817
|
const result = await runManagedGroup(args, formatJson);
|
|
1725
1818
|
renderManagedGroupResult(args, result, formatJson);
|
|
1726
1819
|
return;
|
|
1727
1820
|
}
|
|
1728
|
-
const { groupSend, groupPull, groupAck, groupCreate, groupInfo, groupList, groupUpdate, groupDissolve, groupSuspend, groupResume, groupJoin, groupLeave, groupInvite, groupInvites, groupAcceptInvite, groupRejectInvite, groupRevokeInvite, groupKick, groupMembers, groupOnline, groupSetRole, groupTransferOwner, groupBan, groupUnban, groupBanlist, groupRules, groupUpdateRules, groupRulesFileGet, groupRulesFileSet, groupRulesFilePublish, } = await import('../aun/msg/index.js');
|
|
1821
|
+
const { groupSend, groupPull, groupAck, groupHistory, parseGroupHistoryArgs, groupCreate, groupInfo, groupList, groupUpdate, groupDissolve, groupSuspend, groupResume, groupJoin, groupLeave, groupInvite, groupInvites, groupAcceptInvite, groupRejectInvite, groupRevokeInvite, groupKick, groupMembers, groupOnline, groupSetRole, groupTransferOwner, groupBan, groupUnban, groupBanlist, groupBlock, groupUnblock, groupBlocklist, groupReportStatus, groupMemberStatuses, groupRules, groupUpdateRules, groupRulesFileGet, groupRulesFileSet, groupRulesFilePublish, } = await import('../aun/msg/index.js');
|
|
1729
1822
|
const commonOpts = { aunPath, slotId: appSlot };
|
|
1823
|
+
if (['block', 'unblock', 'blocklist', 'report-status', 'member-statuses'].includes(sub)) {
|
|
1824
|
+
// Share validation with the daemon; standalone connection options stay local.
|
|
1825
|
+
const operationArgs = [];
|
|
1826
|
+
for (let i = 0; i < args.length; i++) {
|
|
1827
|
+
if (args[i] === '--aun-path' || args[i] === '--app') {
|
|
1828
|
+
if (args[i + 1] === undefined || args[i + 1].startsWith('--')) {
|
|
1829
|
+
failManagedGroup(formatJson, 'INVALID_ARGUMENT', `${args[i]} requires a value`);
|
|
1830
|
+
}
|
|
1831
|
+
i++;
|
|
1832
|
+
}
|
|
1833
|
+
else {
|
|
1834
|
+
operationArgs.push(args[i]);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
const { resolveManagedGroupOperation } = await import('../aun/msg/managed-operation.js');
|
|
1838
|
+
const parsed = resolveManagedGroupOperation(operationArgs);
|
|
1839
|
+
if (!parsed.ok)
|
|
1840
|
+
failManagedGroup(formatJson, parsed.code, parsed.reason);
|
|
1841
|
+
const command = parsed.command;
|
|
1842
|
+
const base = { from: command.from, groupId: command.groupId, ...commonOpts };
|
|
1843
|
+
let result;
|
|
1844
|
+
switch (sub) {
|
|
1845
|
+
case 'block':
|
|
1846
|
+
result = await groupBlock({ ...base, memberAid: command.memberAid, reason: command.reason });
|
|
1847
|
+
break;
|
|
1848
|
+
case 'unblock':
|
|
1849
|
+
result = await groupUnblock({ ...base, memberAid: command.memberAid });
|
|
1850
|
+
break;
|
|
1851
|
+
case 'blocklist':
|
|
1852
|
+
result = await groupBlocklist(base);
|
|
1853
|
+
break;
|
|
1854
|
+
case 'report-status':
|
|
1855
|
+
result = await groupReportStatus({ ...base, onlineStatus: command.onlineStatus, workStatus: command.workStatus });
|
|
1856
|
+
break;
|
|
1857
|
+
default:
|
|
1858
|
+
result = await groupMemberStatuses(base);
|
|
1859
|
+
}
|
|
1860
|
+
if (!result.ok)
|
|
1861
|
+
failManagedGroup(formatJson, result.code ?? 'GROUP_OPERATION_FAILED', result.error);
|
|
1862
|
+
renderManagedGroupResult(operationArgs, result, formatJson);
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1730
1865
|
// 通用 group_id 提取(第三参数)
|
|
1731
1866
|
const requireGroupId = () => {
|
|
1732
1867
|
const gid = args[2];
|
|
@@ -1735,12 +1870,14 @@ Options:
|
|
|
1735
1870
|
printGroupSendAidHint();
|
|
1736
1871
|
process.exit(1);
|
|
1737
1872
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1873
|
+
try {
|
|
1874
|
+
return normalizeGroupAid(gid, from.slice(from.indexOf('.') + 1));
|
|
1875
|
+
}
|
|
1876
|
+
catch (error) {
|
|
1877
|
+
console.error(`❌ 第 2 个位置参数 <group-aid> 不是有效群 AID: ${gid}: ${error.message}`);
|
|
1740
1878
|
printGroupSendAidHint();
|
|
1741
1879
|
process.exit(1);
|
|
1742
1880
|
}
|
|
1743
|
-
return gid;
|
|
1744
1881
|
};
|
|
1745
1882
|
// 收集 --mention(可多次;每次的值支持逗号分隔多个 aid)
|
|
1746
1883
|
const collectMentions = () => {
|
|
@@ -1853,6 +1990,16 @@ Options:
|
|
|
1853
1990
|
return parts.join(' ');
|
|
1854
1991
|
};
|
|
1855
1992
|
// ---- 消息 ----
|
|
1993
|
+
if (sub === 'history') {
|
|
1994
|
+
try {
|
|
1995
|
+
const result = groupHistory(parseGroupHistoryArgs(args));
|
|
1996
|
+
renderManagedGroupResult(args, result, formatJson);
|
|
1997
|
+
}
|
|
1998
|
+
catch (error) {
|
|
1999
|
+
failManagedGroup(formatJson, error.code || 'HISTORY_READ_FAILED', error instanceof Error ? error.message : String(error));
|
|
2000
|
+
}
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
1856
2003
|
if (sub === 'send') {
|
|
1857
2004
|
const groupId = requireGroupId();
|
|
1858
2005
|
// Group sends use the dedicated AUN message daemon route rather than the
|
|
@@ -2050,9 +2197,11 @@ Options:
|
|
|
2050
2197
|
});
|
|
2051
2198
|
outputResult(result, () => {
|
|
2052
2199
|
const r = result;
|
|
2053
|
-
console.log(`✓ 已创建群 ${r.group?.group_id}`);
|
|
2200
|
+
console.log(`✓ 已创建群 ${r.group?.group_aid ?? r.group?.group_id}`);
|
|
2054
2201
|
console.log(` 名称: ${r.group?.name}`);
|
|
2055
2202
|
console.log(` 可见性: ${r.group?.visibility}`);
|
|
2203
|
+
if (r.warning)
|
|
2204
|
+
console.warn(r.warning);
|
|
2056
2205
|
});
|
|
2057
2206
|
return;
|
|
2058
2207
|
}
|
|
@@ -2450,7 +2599,7 @@ Options:
|
|
|
2450
2599
|
});
|
|
2451
2600
|
return;
|
|
2452
2601
|
}
|
|
2453
|
-
console.error(`未知子命令: ${sub}\n用法: ec group [send|pull|ack|create|list|info|update|dissolve|suspend|resume|rules|join|leave|invite|invites|accept-invite|reject-invite|revoke-invite|kick|members|online|role|owner|ban|unban]`);
|
|
2602
|
+
console.error(`未知子命令: ${sub}\n用法: ec group [send|pull|ack|history|create|list|info|update|dissolve|suspend|resume|rules|join|leave|invite|invites|accept-invite|reject-invite|revoke-invite|kick|members|online|role|owner|ban|unban|block|unblock|blocklist|report-status|member-statuses]`);
|
|
2454
2603
|
process.exit(1);
|
|
2455
2604
|
}
|
|
2456
2605
|
// ==================== Main ====================
|
package/dist/cli/config.js
CHANGED
|
@@ -4,7 +4,7 @@ import { resolveConfigCommand } from '../config/resolved-config-op.js';
|
|
|
4
4
|
import { AUTHENTICATED_CONFIG_ROLE_ENV, executeResolvedConfigCommandAsync, } from '../config/config-operation-service.js';
|
|
5
5
|
import { ipcQuery } from '../ipc.js';
|
|
6
6
|
import { resolvePaths } from '../paths.js';
|
|
7
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
7
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
8
8
|
import { splitConfigBatchGetArgv } from './cli-argv.js';
|
|
9
9
|
function emit(formatJson, payload, text) {
|
|
10
10
|
if (formatJson)
|
|
@@ -128,7 +128,7 @@ function managedSession(formatJson) {
|
|
|
128
128
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
129
129
|
if (!sessionId)
|
|
130
130
|
fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
131
|
-
const delegationToken =
|
|
131
|
+
const delegationToken = readDelegationCredential();
|
|
132
132
|
if (!delegationToken) {
|
|
133
133
|
fail(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
134
134
|
}
|
|
@@ -158,10 +158,13 @@ async function runManagedConfig(args, formatJson) {
|
|
|
158
158
|
renderConfigExecution(response.result, formatJson);
|
|
159
159
|
}
|
|
160
160
|
function renderBatchGet(results, formatJson) {
|
|
161
|
-
|
|
161
|
+
// Unsupported runner fields are compatibility misses, not a failure of the
|
|
162
|
+
// supported fields in the same aggregate request. Keep the per-field error
|
|
163
|
+
// while allowing clients to consume the successful values.
|
|
164
|
+
const batchOk = results.every(entry => entry.ok || entry.code === 'UNSUPPORTED_FIELD');
|
|
162
165
|
if (formatJson) {
|
|
163
166
|
console.log(JSON.stringify({
|
|
164
|
-
ok:
|
|
167
|
+
ok: batchOk,
|
|
165
168
|
results: results.map(entry => entry.ok
|
|
166
169
|
? getResultPayload(entry)
|
|
167
170
|
: { ok: false, field: entry.field, code: entry.code, error: entry.error }),
|
|
@@ -175,7 +178,7 @@ function renderBatchGet(results, formatJson) {
|
|
|
175
178
|
console.error(`${entry.field}: Error: ${entry.error} (${entry.code})`);
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
|
-
if (!
|
|
181
|
+
if (!batchOk)
|
|
179
182
|
process.exit(1);
|
|
180
183
|
}
|
|
181
184
|
async function runDirectBatchGet(fields, rest, formatJson) {
|
package/dist/cli/contact.js
CHANGED
|
@@ -2,7 +2,7 @@ import { resolvePaths } from '../paths.js';
|
|
|
2
2
|
import { loadAllAgents } from '../config-store.js';
|
|
3
3
|
import { executeResolvedContactCommand, resolveContactCommand, } from '../config/contact-operation-service.js';
|
|
4
4
|
import { ipcQuery } from '../ipc.js';
|
|
5
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
5
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
6
6
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
7
7
|
export async function cmdContact(args) {
|
|
8
8
|
if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
|
|
@@ -39,7 +39,7 @@ function output(value, json) {
|
|
|
39
39
|
}
|
|
40
40
|
async function runManaged(args, json) {
|
|
41
41
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
42
|
-
const delegationToken =
|
|
42
|
+
const delegationToken = readDelegationCredential();
|
|
43
43
|
if (!delegationToken)
|
|
44
44
|
fail(`${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`, 'DELEGATION_REQUIRED');
|
|
45
45
|
let response = null;
|
package/dist/cli/ctl-command.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolvePaths } from '../paths.js';
|
|
2
2
|
import { ipcQuery } from '../ipc.js';
|
|
3
3
|
import { isHelpFlag, wantsHelp } from './help.js';
|
|
4
|
-
import {
|
|
4
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
5
5
|
// ==================== Ctl ====================
|
|
6
6
|
const CTL_HELP = `用法: ec ctl <command> [args...]
|
|
7
7
|
|
|
@@ -47,7 +47,7 @@ export async function cmdCtl(args) {
|
|
|
47
47
|
type: 'ctl',
|
|
48
48
|
cmd,
|
|
49
49
|
sessionId,
|
|
50
|
-
delegationToken:
|
|
50
|
+
delegationToken: readDelegationCredential(),
|
|
51
51
|
}, 10_000);
|
|
52
52
|
if (!result) {
|
|
53
53
|
console.error('错误: 无法连接 evolcore 服务');
|