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
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { CodexSessionFileAdapter } from './core/session/adapters/codex-session-f
|
|
|
14
14
|
import { GeminiSessionFileAdapter } from './core/session/adapters/gemini-session-file-adapter.js';
|
|
15
15
|
import { EcagentSessionFileAdapter } from './core/session/adapters/ecagent-session-file-adapter.js';
|
|
16
16
|
import { autoMigrateIfNeeded, loadDefaults, loadAllAgents, migrateIdentitiesIfNeeded, loadDaemonConfig, initializeEckSnapshotsConfig, isFullAccessEnabled } from './config-store.js';
|
|
17
|
+
import { migrateRelationSharedDirectories } from './core/relation/shared-data.js';
|
|
17
18
|
import { DEFAULT_ECWEB_PORT, ecwebService } from './config/daemon-services.js';
|
|
18
19
|
import { ConfigTarget, initConfigManager, onConfigWrite, read as readConfig, shouldFailFastForMissingOwners } from './config/config-manager.js';
|
|
19
20
|
import { ensureRoleConfigV4OnStartup, ensureRoleConfigV5OnStartup } from './config/role-migration-startup.js';
|
|
@@ -53,6 +54,8 @@ import { BootstrapService, completeBootstrapWithWelcome } from './core/bootstrap
|
|
|
53
54
|
import { postBootstrapWelcomeOperationId } from './core/bootstrap-messages.js';
|
|
54
55
|
import { MessageCache } from './core/message/message-cache.js';
|
|
55
56
|
import { CommandHandler, isProcessLevelOwner } from './core/command/command-handler.js';
|
|
57
|
+
import { executeLocalInitializationCommand, AgentInitializationService, hasSuppliedInitialization, readInitialization, parseInitializationArgs, parseAgentWelcomeArgs, resolveInitializationPlan, } from './cli/agent-create.js';
|
|
58
|
+
import { loadAgent } from './config-store.js';
|
|
56
59
|
import { AgentApplicationService } from './core/agent-application-service.js';
|
|
57
60
|
import { EventBus } from './core/event-bus.js';
|
|
58
61
|
import { eventPatternIncludesInternal, getEventCatalog } from './core/event-catalog.js';
|
|
@@ -60,12 +63,13 @@ import { StatsCollector } from './utils/stats.js';
|
|
|
60
63
|
import { AidStatsCollector } from './utils/stats.js';
|
|
61
64
|
import { PermissionGateway } from './core/permission/approval-gateway.js';
|
|
62
65
|
import { InteractionRouter, registerAdapterInteractions } from './core/interaction-router.js';
|
|
66
|
+
import { GroupInviteReviewService } from './core/group/invite-service.js';
|
|
63
67
|
import { AgentDelegationRegistry, authorizeDelegatedAunMsgSend, hasTrustedFullAccessDelegation, trustedExecutionIdentityInput, } from './core/auth/agent-delegation.js';
|
|
64
68
|
import { authorizeOperation, buildAuthSubject, canApprovePersistentFullAccessTrigger, isCrossAgentTriggerOperationAllowed, } from './core/auth/auth-gateway.js';
|
|
65
69
|
import { authorizationDenialData, formatAuthorizationDenial } from './core/auth/authorization-denial.js';
|
|
66
70
|
import { auditFullAccessEvent } from './core/auth/authorization-audit.js';
|
|
67
71
|
import { parsePeerKey } from './core/relation/peer-identity.js';
|
|
68
|
-
import { isHClassPath } from './core/permission/protected-paths.js';
|
|
72
|
+
import { isHClassPath, isSameOrDescendant } from './core/permission/protected-paths.js';
|
|
69
73
|
import { ChannelLoader, tryParseChannelKey } from './core/channel-loader.js';
|
|
70
74
|
import { AgentLoader } from './core/baseagent-loader.js';
|
|
71
75
|
import { EvolAgentRegistry } from './core/evolagent-registry.js';
|
|
@@ -73,6 +77,8 @@ import { createRunnerReloadTransaction, disposeAgentInstances } from './core/run
|
|
|
73
77
|
import { AgentReloadBusyError, AgentReloadCoordinator } from './core/agent-reload-coordinator.js';
|
|
74
78
|
import { buildReloadHooks } from './core/channel-loader.js';
|
|
75
79
|
import { IpcServer } from './ipc.js';
|
|
80
|
+
import { executeTaskResume } from './core/task/task-resume-operation.js';
|
|
81
|
+
import { TASK_RECOVERY_PROMPT } from './core/task/task-recovery-service.js';
|
|
76
82
|
import { logger, setLogLevel } from './utils/logger.js';
|
|
77
83
|
import { remoteAccessService } from './core/auth/remote-access-store.js';
|
|
78
84
|
import { DiagService, executeDiagIpc } from './core/command/diag-service.js';
|
|
@@ -98,6 +104,7 @@ import { DAEMON_RUNTIME_EPOCH_ENV, ensureProcessManagedTempDir } from './cli/tas
|
|
|
98
104
|
import { appendMessageLog, buildOutboundEntry, classifyAunPayloadForLog } from './core/message/message-log.js';
|
|
99
105
|
import { normalizeAunMentionEntries } from './aun/msg/mention-schema.js';
|
|
100
106
|
import { MAIN_PACKAGE_NAME } from './product.js';
|
|
107
|
+
import { sanitizeMenuLogValue } from './core/command/menu-protocol.js';
|
|
101
108
|
import fs from 'fs';
|
|
102
109
|
import crypto from 'crypto';
|
|
103
110
|
import { fileURLToPath } from 'url';
|
|
@@ -529,6 +536,51 @@ main().catch((error) => {
|
|
|
529
536
|
atomicWriteJson(manager.definitionPath(definition.id), definition);
|
|
530
537
|
fs.rmSync(manager.activePath(definition.id), { force: true });
|
|
531
538
|
}
|
|
539
|
+
/**
|
|
540
|
+
* Keep one daemon-owned recovery Trigger for all local Agent sessions. The
|
|
541
|
+
* event-session feedback path resolves the owning Agent from task:error rather
|
|
542
|
+
* than treating the daemon AID as the target Agent.
|
|
543
|
+
*/
|
|
544
|
+
function seedTaskRecoveryTrigger(manager, owner) {
|
|
545
|
+
const now = Date.now();
|
|
546
|
+
const definition = normalizeTriggerDefinition({
|
|
547
|
+
$schema_version: 3.1,
|
|
548
|
+
id: '__task-recovery',
|
|
549
|
+
agentAid: owner.aid,
|
|
550
|
+
enabled: true,
|
|
551
|
+
name: '__task-recovery',
|
|
552
|
+
description: 'System trigger: recover failed tasks for local Agents.',
|
|
553
|
+
createdAt: now,
|
|
554
|
+
updatedAt: now,
|
|
555
|
+
origin: {
|
|
556
|
+
channelKey: 'daemon',
|
|
557
|
+
channelType: 'daemon',
|
|
558
|
+
channelId: owner.originPeerId || owner.aid,
|
|
559
|
+
session: 'main',
|
|
560
|
+
peerId: owner.originPeerId || owner.aid,
|
|
561
|
+
sessionKey: `daemon#${owner.originPeerId || owner.aid}#__task-recovery__`,
|
|
562
|
+
},
|
|
563
|
+
source: {
|
|
564
|
+
type: 'event',
|
|
565
|
+
eventPattern: 'task:error',
|
|
566
|
+
},
|
|
567
|
+
execution: {
|
|
568
|
+
type: 'target_session',
|
|
569
|
+
prompt: TASK_RECOVERY_PROMPT,
|
|
570
|
+
onError: 'retry',
|
|
571
|
+
noopSentinel: '[[NOOP]]',
|
|
572
|
+
},
|
|
573
|
+
feedback: { strategy: 'event_session' },
|
|
574
|
+
reliability: {
|
|
575
|
+
concurrency: 'forbid',
|
|
576
|
+
missedPolicy: 'run_once',
|
|
577
|
+
retry: { maxAttempts: 2, backoffMs: 30_000 },
|
|
578
|
+
},
|
|
579
|
+
});
|
|
580
|
+
fs.mkdirSync(manager.triggerDir(definition.id), { recursive: true });
|
|
581
|
+
atomicWriteJson(manager.definitionPath(definition.id), definition);
|
|
582
|
+
fs.rmSync(manager.activePath(definition.id), { force: true });
|
|
583
|
+
}
|
|
532
584
|
function removeLegacyAgentUpgradeCheck(manager) {
|
|
533
585
|
let existing;
|
|
534
586
|
try {
|
|
@@ -957,6 +1009,10 @@ async function main() {
|
|
|
957
1009
|
}
|
|
958
1010
|
// ── 自动迁移 ──
|
|
959
1011
|
migrateIdentitiesIfNeeded();
|
|
1012
|
+
const relationSharedMigration = migrateRelationSharedDirectories();
|
|
1013
|
+
if (relationSharedMigration.copied > 0) {
|
|
1014
|
+
logger.info(`[migrate] Synced ${relationSharedMigration.copied} relation shared file(s) across ${relationSharedMigration.relations} relation(s)`);
|
|
1015
|
+
}
|
|
960
1016
|
// daemon.json 的旧 ecweb/serviceProxy 结构已在启动前归一化为 services[]。
|
|
961
1017
|
// ── 配置体系初始化(schema 字段不相交硬约束校验)──
|
|
962
1018
|
try {
|
|
@@ -1239,6 +1295,11 @@ async function main() {
|
|
|
1239
1295
|
});
|
|
1240
1296
|
// 交互路由器
|
|
1241
1297
|
const interactionRouter = new InteractionRouter();
|
|
1298
|
+
const groupInviteReviewService = new GroupInviteReviewService(interactionRouter);
|
|
1299
|
+
const removeGroupInviteConfigListener = onConfigWrite(({ target, selector }) => {
|
|
1300
|
+
if (target === ConfigTarget.Agent && selector.self)
|
|
1301
|
+
groupInviteReviewService.configurationChanged(selector.self);
|
|
1302
|
+
});
|
|
1242
1303
|
// 为所有支持权限的 agent 设置 gateway
|
|
1243
1304
|
for (const inst of agentInstances) {
|
|
1244
1305
|
inst.agent.setPermissionGateway?.(permissionGateway);
|
|
@@ -1327,6 +1388,7 @@ async function main() {
|
|
|
1327
1388
|
// 创建命令处理器
|
|
1328
1389
|
const cmdHandler = new CommandHandler(sessionManager, agentMap, messageCache, eventBus, primaryRunnerKey);
|
|
1329
1390
|
let agentApplicationService;
|
|
1391
|
+
let agentInitializationService;
|
|
1330
1392
|
cmdHandler.setAgentDelegationRegistry(agentDelegationRegistry);
|
|
1331
1393
|
cmdHandler.setPermissionGateway(permissionGateway);
|
|
1332
1394
|
cmdHandler.setInteractionRouter(interactionRouter);
|
|
@@ -1372,10 +1434,13 @@ async function main() {
|
|
|
1372
1434
|
dedupPath: daemonMessageDedupPath(),
|
|
1373
1435
|
});
|
|
1374
1436
|
// 设置中断回调(精确中断正在处理的 agent)
|
|
1375
|
-
messageQueue.setInterruptCallback(async (sessionKey, baseagent, evolagentName, reason = 'new_message') => {
|
|
1437
|
+
messageQueue.setInterruptCallback(async (sessionKey, baseagent, evolagentName, reason = 'new_message', timeout) => {
|
|
1376
1438
|
void baseagent;
|
|
1377
1439
|
void evolagentName;
|
|
1378
|
-
|
|
1440
|
+
if (timeout)
|
|
1441
|
+
await responseEngine.timeoutSession(sessionKey, timeout);
|
|
1442
|
+
else
|
|
1443
|
+
await responseEngine.interruptSession(sessionKey, reason);
|
|
1379
1444
|
});
|
|
1380
1445
|
messageQueue.setEventBus(eventBus);
|
|
1381
1446
|
// Restore persisted input before Trigger schedulers start. Trigger-owned work
|
|
@@ -1531,7 +1596,7 @@ async function main() {
|
|
|
1531
1596
|
};
|
|
1532
1597
|
};
|
|
1533
1598
|
const validateTriggerFeedbackChannels = (definition) => {
|
|
1534
|
-
if (definition.feedback.strategy === 'silent')
|
|
1599
|
+
if (definition.feedback.strategy === 'silent' || definition.feedback.strategy === 'event_session')
|
|
1535
1600
|
return;
|
|
1536
1601
|
const target = definition.feedback.strategy === 'target'
|
|
1537
1602
|
? definition.feedback.target
|
|
@@ -1614,6 +1679,9 @@ async function main() {
|
|
|
1614
1679
|
if (!effortDecision.ok)
|
|
1615
1680
|
throw new Error(effortDecision.message || 'trigger effort is not allowed by current role');
|
|
1616
1681
|
}
|
|
1682
|
+
if (!actor.management && definition.feedback.strategy === 'event_session') {
|
|
1683
|
+
throw new Error('event-session feedback requires owner/admin');
|
|
1684
|
+
}
|
|
1617
1685
|
if (!actor.management && definition.feedback.strategy === 'target') {
|
|
1618
1686
|
const target = definition.feedback.target;
|
|
1619
1687
|
const origin = actor.origin;
|
|
@@ -1721,6 +1789,9 @@ async function main() {
|
|
|
1721
1789
|
if (privilegedReason && !persistedFullAccessApproval && !hasDaemonTriggerAuthority(subject)) {
|
|
1722
1790
|
return { allowed: false, reason: `${privilegedReason} requires current DaemonOwner` };
|
|
1723
1791
|
}
|
|
1792
|
+
if (definition.feedback.strategy === 'event_session' && !isManagementRole(role)) {
|
|
1793
|
+
return { allowed: false, reason: 'event-session feedback requires current owner/admin role' };
|
|
1794
|
+
}
|
|
1724
1795
|
if (definition.feedback.strategy === 'target' && !isManagementRole(role)) {
|
|
1725
1796
|
const target = definition.feedback.target;
|
|
1726
1797
|
if (!target
|
|
@@ -1830,6 +1901,7 @@ async function main() {
|
|
|
1830
1901
|
const manager = new TriggerDefinitionManager(owner.aid);
|
|
1831
1902
|
if (opts.seedUpgradeCheck) {
|
|
1832
1903
|
seedUpgradeCheckTrigger(manager, owner);
|
|
1904
|
+
seedTaskRecoveryTrigger(manager, owner);
|
|
1833
1905
|
}
|
|
1834
1906
|
else {
|
|
1835
1907
|
removeLegacyAgentUpgradeCheck(manager);
|
|
@@ -1840,6 +1912,8 @@ async function main() {
|
|
|
1840
1912
|
getChannel: getTriggerChannel,
|
|
1841
1913
|
sessionManager,
|
|
1842
1914
|
messageQueue,
|
|
1915
|
+
recoverTask: request => responseEngine.recoverTask(request),
|
|
1916
|
+
inspectTargetExecution: (sessionId, attemptId, selfAid) => responseEngine.inspectTargetExecution(sessionId, attemptId, selfAid),
|
|
1843
1917
|
eventBus,
|
|
1844
1918
|
tryHandoff: async (input, text, target, binding) => {
|
|
1845
1919
|
if (input.signal?.aborted) {
|
|
@@ -1956,9 +2030,21 @@ async function main() {
|
|
|
1956
2030
|
const inst = channelInstances.find(candidate => candidate.adapter.channelKey === channelKey);
|
|
1957
2031
|
return !!inst && inst.channel.getStatus?.().connected === true;
|
|
1958
2032
|
};
|
|
2033
|
+
cmdHandler.setAgentStorageClientResolver((channelKey, targetAid) => {
|
|
2034
|
+
const inst = channelInstances.find(candidate => candidate.channelType === 'aun'
|
|
2035
|
+
&& (candidate.adapter.channelKey === channelKey || candidate.adapter.channelName === channelKey)
|
|
2036
|
+
&& candidate.channel.getAid?.() === targetAid);
|
|
2037
|
+
if (!inst || inst.channel.getStatus?.().connected !== true)
|
|
2038
|
+
return undefined;
|
|
2039
|
+
// A reconnect replaces the Client; never capture it during startup.
|
|
2040
|
+
const client = inst.channel.getClient?.();
|
|
2041
|
+
return client?.aid === targetAid ? client : undefined;
|
|
2042
|
+
});
|
|
1959
2043
|
const msgBridge = new MessageBridge(defaultProjectPath, sessionManager, processor, messageQueue, cmdHandler, eventBus, primaryAgent?.config.debounce, () => processLevelOwners);
|
|
1960
2044
|
msgBridge.setAgentRegistry(agentRegistry);
|
|
1961
2045
|
msgBridge.setInteractionRouter(interactionRouter);
|
|
2046
|
+
msgBridge.setGroupInviteReviewService(groupInviteReviewService);
|
|
2047
|
+
cmdHandler.setGroupInviteDecisionResolver((selfAid, ownerAid, inviteId, action) => groupInviteReviewService.decideManaged(selfAid, ownerAid, inviteId, action));
|
|
1962
2048
|
msgBridge.setContactBindRuntimeChecker(isContactBindChannelReady);
|
|
1963
2049
|
msgBridge.setAidStatsCollector(aidStatsCollector);
|
|
1964
2050
|
cmdHandler.setContactRequestSubmitter((input) => msgBridge.submitAgentContactRequest(input));
|
|
@@ -1982,7 +2068,7 @@ async function main() {
|
|
|
1982
2068
|
sessionId: envelope.sessionId,
|
|
1983
2069
|
agentAid: owningAgent?.aid,
|
|
1984
2070
|
agentName: envelope.agentName,
|
|
1985
|
-
payload: summarizeOutboundPayload(payload),
|
|
2071
|
+
payload: sanitizeMenuLogValue(summarizeOutboundPayload(payload)),
|
|
1986
2072
|
});
|
|
1987
2073
|
const result = await originalSend(envelope, payload);
|
|
1988
2074
|
// AUN adapters return an explicit receipt. Only a receipt with a remote
|
|
@@ -2552,7 +2638,10 @@ async function main() {
|
|
|
2552
2638
|
catch {
|
|
2553
2639
|
parsed = null;
|
|
2554
2640
|
}
|
|
2555
|
-
const menuResponseContext = () =>
|
|
2641
|
+
const menuResponseContext = () => ({
|
|
2642
|
+
...controlReplyContext(opts, evolMenuResponseTransportMetadata(opts.protectedHeaders?.sdk_version)),
|
|
2643
|
+
...(opts.peerDeviceId ? { toDeviceId: opts.peerDeviceId } : {}),
|
|
2644
|
+
});
|
|
2556
2645
|
const sendControlMenuResponse = async (response) => {
|
|
2557
2646
|
const timedResponse = withMenuProcessingTime(enforceMenuResponseSize(response, 128 * 1024 - 1024), menuTiming);
|
|
2558
2647
|
const request = activeMenuRequest ?? {
|
|
@@ -2637,9 +2726,9 @@ async function main() {
|
|
|
2637
2726
|
return;
|
|
2638
2727
|
}
|
|
2639
2728
|
if (text.toLowerCase() === '/pair') {
|
|
2640
|
-
const pair = remoteAccessService.getPairingCode(opts.peerId);
|
|
2729
|
+
const pair = remoteAccessService.getPairingCode(opts.peerId, Date.now(), 'pair');
|
|
2641
2730
|
const mins = Math.max(0, Math.round((pair.expiresAt - Date.now()) / 60000));
|
|
2642
|
-
const reply = `远程控制配对码:${pair.code}(约 ${mins}
|
|
2731
|
+
const reply = `远程控制配对码:${pair.code}(约 ${mins} 分钟内有效,仅可配对一次)`;
|
|
2643
2732
|
await controlChannel.sendMessage(opts.channelId, reply, controlReplyContext(opts));
|
|
2644
2733
|
return;
|
|
2645
2734
|
}
|
|
@@ -2650,7 +2739,7 @@ async function main() {
|
|
|
2650
2739
|
await sendControlMenuResponse(menuFailure({ id: menuControl.id, ...(menuControl.name?.trim() ? { name: menuControl.name } : {}) }, validationError));
|
|
2651
2740
|
return;
|
|
2652
2741
|
}
|
|
2653
|
-
const deduped = await controlMenuDeduper.execute([opts.channelId, opts.peerId, menuControl.id].join('\u001f'), menuPayloadFingerprint(menuControl.raw), () => cmdHandler.execMenuForControl(parsed, opts.peerId, {
|
|
2742
|
+
const deduped = await controlMenuDeduper.execute([opts.channelId, opts.peerId, opts.peerDeviceId || '', menuControl.id].join('\u001f'), menuPayloadFingerprint(menuControl.raw), () => cmdHandler.execMenuForControl(parsed, opts.peerId, {
|
|
2654
2743
|
encrypted: opts.encrypted,
|
|
2655
2744
|
protectedHeaders: opts.protectedHeaders,
|
|
2656
2745
|
}));
|
|
@@ -2848,6 +2937,41 @@ async function main() {
|
|
|
2848
2937
|
});
|
|
2849
2938
|
}
|
|
2850
2939
|
}
|
|
2940
|
+
async function completeAgentBootstrap(aid) {
|
|
2941
|
+
const aunInstance = channelInstances.find(candidate => {
|
|
2942
|
+
if (candidate.channelType !== 'aun')
|
|
2943
|
+
return false;
|
|
2944
|
+
const owner = agentRegistry.resolveByChannel(candidate.adapter.channelKey)
|
|
2945
|
+
?? agentRegistry.resolveByChannel(candidate.adapter.channelName);
|
|
2946
|
+
return owner?.aid === aid;
|
|
2947
|
+
});
|
|
2948
|
+
const welcome = aunInstance?.channel;
|
|
2949
|
+
const owningAgent = agentRegistry.get(aid);
|
|
2950
|
+
const firstOwnerAid = getFirstStaticAgentOwner(aid);
|
|
2951
|
+
const sessions = aunInstance && firstOwnerAid && owningAgent
|
|
2952
|
+
? {
|
|
2953
|
+
ensurePostBootstrapMainSession: async (owner) => {
|
|
2954
|
+
const ownerAid = owner || firstOwnerAid;
|
|
2955
|
+
const channel = aunInstance.adapter.channelName;
|
|
2956
|
+
const active = await sessionManager.getActiveSession(channel, ownerAid);
|
|
2957
|
+
const ensured = await sessionManager.ensureNewMainSessionForOperation({
|
|
2958
|
+
channel,
|
|
2959
|
+
channelId: ownerAid,
|
|
2960
|
+
projectPath: active?.projectPath || owningAgent.projectPath || defaultProjectPath,
|
|
2961
|
+
baseagent: owningAgent.baseagent || active?.baseagent || primaryBaseagent,
|
|
2962
|
+
operationId: postBootstrapWelcomeOperationId(aid, ownerAid),
|
|
2963
|
+
identityMetadata: {
|
|
2964
|
+
...(active?.metadata ?? {}),
|
|
2965
|
+
channelKey: aunInstance.adapter.channelKey,
|
|
2966
|
+
peerId: ownerAid,
|
|
2967
|
+
},
|
|
2968
|
+
});
|
|
2969
|
+
return { sessionId: ensured.session.id, created: ensured.created };
|
|
2970
|
+
},
|
|
2971
|
+
}
|
|
2972
|
+
: undefined;
|
|
2973
|
+
return completeBootstrapWithWelcome(bootstrapService, aid, welcome, sessions);
|
|
2974
|
+
}
|
|
2851
2975
|
function configureIpc() {
|
|
2852
2976
|
ipcServer.setShutdownExecutor(async (reason) => {
|
|
2853
2977
|
if (!shutdown) {
|
|
@@ -2880,39 +3004,10 @@ async function main() {
|
|
|
2880
3004
|
return { ok: false, code: 'INVALID_CONTROL_TOKEN', error: 'valid local control token is required' };
|
|
2881
3005
|
}
|
|
2882
3006
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
?? agentRegistry.resolveByChannel(candidate.adapter.channelName);
|
|
2888
|
-
return owner?.aid === aid;
|
|
2889
|
-
});
|
|
2890
|
-
const welcome = aunInstance?.channel;
|
|
2891
|
-
const owningAgent = agentRegistry.get(aid);
|
|
2892
|
-
const firstOwnerAid = getFirstStaticAgentOwner(aid);
|
|
2893
|
-
const sessions = aunInstance && firstOwnerAid && owningAgent
|
|
2894
|
-
? {
|
|
2895
|
-
ensurePostBootstrapMainSession: async (owner) => {
|
|
2896
|
-
const ownerAid = owner || firstOwnerAid;
|
|
2897
|
-
const channel = aunInstance.adapter.channelName;
|
|
2898
|
-
const active = await sessionManager.getActiveSession(channel, ownerAid);
|
|
2899
|
-
const ensured = await sessionManager.ensureNewMainSessionForOperation({
|
|
2900
|
-
channel,
|
|
2901
|
-
channelId: ownerAid,
|
|
2902
|
-
projectPath: active?.projectPath || owningAgent.projectPath || defaultProjectPath,
|
|
2903
|
-
baseagent: owningAgent.baseagent || active?.baseagent || primaryBaseagent,
|
|
2904
|
-
operationId: postBootstrapWelcomeOperationId(aid, ownerAid),
|
|
2905
|
-
identityMetadata: {
|
|
2906
|
-
...(active?.metadata ?? {}),
|
|
2907
|
-
channelKey: aunInstance.adapter.channelKey,
|
|
2908
|
-
peerId: ownerAid,
|
|
2909
|
-
},
|
|
2910
|
-
});
|
|
2911
|
-
return { sessionId: ensured.session.id, created: ensured.created };
|
|
2912
|
-
},
|
|
2913
|
-
}
|
|
2914
|
-
: undefined;
|
|
2915
|
-
return completeBootstrapWithWelcome(bootstrapService, aid, welcome, sessions);
|
|
3007
|
+
if (hasSuppliedInitialization(aid) || loadAgent(aid)?.initialization) {
|
|
3008
|
+
return { ok: false, code: 'INITIALIZATION_MANAGED', error: 'Use the initialization service for this Agent' };
|
|
3009
|
+
}
|
|
3010
|
+
return completeAgentBootstrap(aid);
|
|
2916
3011
|
});
|
|
2917
3012
|
ipcServer.setDingtalkContactBindExecutor({
|
|
2918
3013
|
register: (cmd) => registerPendingDingtalkContactBind(cmd),
|
|
@@ -3020,6 +3115,14 @@ async function main() {
|
|
|
3020
3115
|
aidStatsCollector.recordOutbound(params.aid, params.toPeer, Buffer.byteLength(params.text || '', 'utf-8'), params.text, false, params.encrypt, params.chatmode, 'send');
|
|
3021
3116
|
});
|
|
3022
3117
|
ipcServer.setTaskRuntimeContextProvider(({ sessionId }) => responseEngine.getTaskRuntimeContext(sessionId));
|
|
3118
|
+
ipcServer.setTaskRuntimeContextAuthorizer(({ sessionId, delegationToken, delegationCommandHash }) => {
|
|
3119
|
+
// Codex persistent threads carry a command-scoped authorization. Looking
|
|
3120
|
+
// up fresh routing context must not consume the subsequent CLI operation.
|
|
3121
|
+
const authorization = agentDelegationRegistry.validateForContext(delegationToken, sessionId, delegationCommandHash);
|
|
3122
|
+
return authorization.ok
|
|
3123
|
+
? { ok: true }
|
|
3124
|
+
: { ok: false, code: authorization.code, error: authorization.reason };
|
|
3125
|
+
});
|
|
3023
3126
|
ipcServer.setCodexPreToolUseExecutor(async (params) => {
|
|
3024
3127
|
for (const runner of new Set(agentMap.values())) {
|
|
3025
3128
|
if (typeof runner?.evaluatePreToolUse !== 'function')
|
|
@@ -3694,6 +3797,57 @@ async function main() {
|
|
|
3694
3797
|
}),
|
|
3695
3798
|
aunAidStats: () => aidStatsCollector.getAllSnapshots(),
|
|
3696
3799
|
});
|
|
3800
|
+
agentInitializationService = new AgentInitializationService({
|
|
3801
|
+
register: async (aid) => {
|
|
3802
|
+
const { aidCreate } = await import('./aun/aid/identity.js');
|
|
3803
|
+
const created = await aidCreate(aid);
|
|
3804
|
+
await created.client.close();
|
|
3805
|
+
},
|
|
3806
|
+
publish: async (aid, content) => {
|
|
3807
|
+
const { agentmdPut } = await import('./aun/aid/agentmd.js');
|
|
3808
|
+
await agentmdPut(content, { aid });
|
|
3809
|
+
},
|
|
3810
|
+
fetch: async (aid) => {
|
|
3811
|
+
const { agentmdGet } = await import('./aun/aid/agentmd.js');
|
|
3812
|
+
const card = await agentmdGet(aid, { withVerification: true, remoteOnly: true });
|
|
3813
|
+
return { content: card.content, verified: card.verification.status === 'verified' };
|
|
3814
|
+
},
|
|
3815
|
+
hotLoad: async (aid) => {
|
|
3816
|
+
await coreHotLoadAgent(aid);
|
|
3817
|
+
const until = Date.now() + 20_000;
|
|
3818
|
+
while (Date.now() < until) {
|
|
3819
|
+
if (channelInstances.some(inst => inst.channelType === 'aun'
|
|
3820
|
+
&& inst.channel.getAidState?.()?.aid === aid
|
|
3821
|
+
&& inst.channel.getAidState?.()?.status === 'connected'))
|
|
3822
|
+
return;
|
|
3823
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
3824
|
+
}
|
|
3825
|
+
throw Object.assign(new Error('AUN connection unavailable'), { code: 'INITIALIZE_CHANNEL_UNAVAILABLE' });
|
|
3826
|
+
},
|
|
3827
|
+
activate: completeAgentBootstrap,
|
|
3828
|
+
authorize: actor => actor === 'local-control' || (loadDaemonConfig().owners ?? []).includes(actor),
|
|
3829
|
+
usable: aid => {
|
|
3830
|
+
const agent = agentRegistry.get(aid);
|
|
3831
|
+
return !!agent && agent.config.enabled !== false && agentMap.has(`${aid}::${agent.baseagent}`)
|
|
3832
|
+
&& channelInstances.some(inst => inst.channelType === 'aun'
|
|
3833
|
+
&& inst.channel.getAidState?.()?.aid === aid
|
|
3834
|
+
&& inst.channel.getAidState?.()?.status === 'connected');
|
|
3835
|
+
},
|
|
3836
|
+
});
|
|
3837
|
+
agentApplicationService.setInitializationService(agentInitializationService);
|
|
3838
|
+
ipcServer.setInitializationExecutor(async (cmd) => executeLocalInitializationCommand(agentInitializationService, cmd));
|
|
3839
|
+
for (const entry of fs.readdirSync(resolvePaths().agentsDir, { withFileTypes: true })) {
|
|
3840
|
+
if (!entry.isDirectory())
|
|
3841
|
+
continue;
|
|
3842
|
+
try {
|
|
3843
|
+
const record = readInitialization(entry.name);
|
|
3844
|
+
if (record?.status === 'in_progress')
|
|
3845
|
+
agentInitializationService.resume(entry.name, record.actor);
|
|
3846
|
+
}
|
|
3847
|
+
catch {
|
|
3848
|
+
logger.warn('[Initialization] Recovery requires review for an incomplete operation');
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3697
3851
|
cmdHandler.setAgentApplicationService(agentApplicationService);
|
|
3698
3852
|
ipcServer.setAgentApplicationService(agentApplicationService);
|
|
3699
3853
|
ipcServer.setStatsProvider(() => statsCollector.getSnapshot());
|
|
@@ -3796,6 +3950,8 @@ async function main() {
|
|
|
3796
3950
|
? {
|
|
3797
3951
|
ok: true,
|
|
3798
3952
|
aid: subject.dataScope === 'daemon' ? (params.targetAid ?? delegation.grant.selfAid) : delegation.grant.selfAid,
|
|
3953
|
+
dataScope: subject.dataScope,
|
|
3954
|
+
management: isManagementRole(subject.role),
|
|
3799
3955
|
}
|
|
3800
3956
|
: { ok: false, code: decision.code, error: decision.reason };
|
|
3801
3957
|
}
|
|
@@ -3823,26 +3979,41 @@ async function main() {
|
|
|
3823
3979
|
return fail('INVALID_DELEGATION', 'delegation does not match the current session');
|
|
3824
3980
|
}
|
|
3825
3981
|
const taskAid = delegation.grant.selfAid;
|
|
3982
|
+
let welcomeArgs;
|
|
3983
|
+
if (sub === 'welcome') {
|
|
3984
|
+
try {
|
|
3985
|
+
welcomeArgs = parseAgentWelcomeArgs(argv.slice(2));
|
|
3986
|
+
}
|
|
3987
|
+
catch (error) {
|
|
3988
|
+
return fail('INVALID_ARGS', error.message);
|
|
3989
|
+
}
|
|
3990
|
+
if (delegation.grant.chatType !== 'private')
|
|
3991
|
+
return fail('NOT_ALLOWED', 'welcome requires a private conversation');
|
|
3992
|
+
}
|
|
3826
3993
|
const targetAid = sub === 'list'
|
|
3827
3994
|
? undefined
|
|
3828
3995
|
: sub === 'persona'
|
|
3829
3996
|
? taskAid
|
|
3830
|
-
: sub === '
|
|
3831
|
-
?
|
|
3832
|
-
: sub === '
|
|
3833
|
-
? (argv[2] && !argv[2].startsWith('--') ? argv[2] :
|
|
3834
|
-
:
|
|
3997
|
+
: sub === 'welcome'
|
|
3998
|
+
? taskAid
|
|
3999
|
+
: sub === 'show'
|
|
4000
|
+
? (argv[2] && !argv[2].startsWith('--') ? argv[2] : taskAid)
|
|
4001
|
+
: sub === 'reload'
|
|
4002
|
+
? (argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined)
|
|
4003
|
+
: (argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined);
|
|
3835
4004
|
const operation = sub === 'list' ? 'agent.list'
|
|
3836
4005
|
: sub === 'show' ? 'agent.show'
|
|
3837
4006
|
: sub === 'persona' ? 'agent.persona'
|
|
3838
|
-
: sub === '
|
|
3839
|
-
: sub === '
|
|
3840
|
-
: sub === '
|
|
3841
|
-
: sub === '
|
|
3842
|
-
: sub === '
|
|
4007
|
+
: sub === 'welcome' ? 'agent.welcome'
|
|
4008
|
+
: sub === 'initialize' || (sub === 'new' && argv.includes('--initialize')) ? 'agent.initialize'
|
|
4009
|
+
: sub === 'new' ? 'agent.create'
|
|
4010
|
+
: sub === 'enable' ? 'agent.enable'
|
|
4011
|
+
: sub === 'disable' ? 'agent.disable'
|
|
4012
|
+
: sub === 'reload' ? 'agent.reload'
|
|
4013
|
+
: sub === 'delete' ? 'agent.delete' : undefined;
|
|
3843
4014
|
if (!operation)
|
|
3844
4015
|
return fail('INVALID_ARGS', `unsupported managed agent command: ${sub}`);
|
|
3845
|
-
if (sub === 'new' && !argv.includes('--non-interactive')) {
|
|
4016
|
+
if (sub === 'new' && !argv.includes('--non-interactive') && !argv.includes('--initialize')) {
|
|
3846
4017
|
return fail('MANAGED_NON_INTERACTIVE_REQUIRED', 'interactive Agent creation is unavailable in a managed task', 'MANAGED_NON_INTERACTIVE_REQUIRED');
|
|
3847
4018
|
}
|
|
3848
4019
|
if (sub === 'delete' && argv.includes('--purge') && !argv.includes('--confirm-purge')) {
|
|
@@ -3871,7 +4042,7 @@ async function main() {
|
|
|
3871
4042
|
subject,
|
|
3872
4043
|
intent: {
|
|
3873
4044
|
operation,
|
|
3874
|
-
scope: operation === 'agent.show' || operation === 'agent.persona'
|
|
4045
|
+
scope: operation === 'agent.show' || operation === 'agent.persona' || operation === 'agent.welcome'
|
|
3875
4046
|
? 'agent'
|
|
3876
4047
|
: operation === 'agent.reload' && targetAid
|
|
3877
4048
|
? 'agent'
|
|
@@ -3882,6 +4053,7 @@ async function main() {
|
|
|
3882
4053
|
aid: targetAid ?? taskAid,
|
|
3883
4054
|
taskAgentAid: taskAid,
|
|
3884
4055
|
targetAgentAid: targetAid ?? taskAid,
|
|
4056
|
+
...(welcomeArgs ? { action: welcomeArgs.action } : {}),
|
|
3885
4057
|
},
|
|
3886
4058
|
},
|
|
3887
4059
|
auditMetadata: { taskId: delegation.grant.taskId, messageId: delegation.grant.messageId },
|
|
@@ -3933,6 +4105,7 @@ async function main() {
|
|
|
3933
4105
|
: { config: null, agent_md: null, project: null, data: null },
|
|
3934
4106
|
...(subject.dataScope === 'daemon' ? {} : { redacted: true }),
|
|
3935
4107
|
...(agent.createProgress ? { createProgress: agent.createProgress } : {}),
|
|
4108
|
+
...(agent.initialization ? { initialization: agent.initialization } : {}),
|
|
3936
4109
|
} };
|
|
3937
4110
|
}
|
|
3938
4111
|
if (operation === 'agent.persona') {
|
|
@@ -3967,6 +4140,48 @@ async function main() {
|
|
|
3967
4140
|
...(result.saved ? { saved: true } : {}),
|
|
3968
4141
|
} };
|
|
3969
4142
|
}
|
|
4143
|
+
if (operation === 'agent.welcome') {
|
|
4144
|
+
if (subject.role !== 'owner' && !(welcomeArgs?.action === 'show' && subject.role === 'admin')) {
|
|
4145
|
+
return fail('NOT_ALLOWED', 'welcome requires the current Agent Owner (admin may read)');
|
|
4146
|
+
}
|
|
4147
|
+
const { agentWelcome } = await import('./cli/agent.js');
|
|
4148
|
+
const result = await agentWelcome(taskAid, { text: welcomeArgs?.text, trustedLocal: true });
|
|
4149
|
+
if (!result.ok)
|
|
4150
|
+
return fail(result.code ?? 'INTERNAL', result.error);
|
|
4151
|
+
return { ok: true, result: {
|
|
4152
|
+
ok: true,
|
|
4153
|
+
aid: taskAid,
|
|
4154
|
+
content: result.content,
|
|
4155
|
+
...(result.path ? { path: result.path } : {}),
|
|
4156
|
+
...(result.saved ? { saved: true } : {}),
|
|
4157
|
+
...(result.bytes !== undefined ? { bytes: result.bytes } : {}),
|
|
4158
|
+
...(result.sha256 ? { sha256: result.sha256 } : {}),
|
|
4159
|
+
} };
|
|
4160
|
+
}
|
|
4161
|
+
if (operation === 'agent.initialize') {
|
|
4162
|
+
try {
|
|
4163
|
+
const parsed = parseInitializationArgs(argv.slice(1));
|
|
4164
|
+
const actor = delegation.grant.actorId;
|
|
4165
|
+
if (parsed.resume)
|
|
4166
|
+
return { ok: true, result: agentInitializationService.resume(parsed.aid, actor) };
|
|
4167
|
+
const createPermission = authorizeOperation({
|
|
4168
|
+
source: 'agent-tool', subject,
|
|
4169
|
+
intent: { operation: 'agent.create', scope: 'control', source: 'agent-tool', args: { aid: parsed.aid } },
|
|
4170
|
+
auditMetadata: { taskId: delegation.grant.taskId, messageId: delegation.grant.messageId },
|
|
4171
|
+
});
|
|
4172
|
+
if (!createPermission.allow)
|
|
4173
|
+
return fail(createPermission.code, createPermission.reason);
|
|
4174
|
+
if (!argv.includes('--owner') && !argv.includes('--owners'))
|
|
4175
|
+
return fail('INITIALIZE_OWNER_MISMATCH', 'Explicit Owner required');
|
|
4176
|
+
const plan = resolveInitializationPlan(argv.slice(1));
|
|
4177
|
+
if (!plan.owners.includes(actor))
|
|
4178
|
+
return fail('INITIALIZE_OWNER_MISMATCH', 'The authenticated requesting Owner must be retained');
|
|
4179
|
+
return { ok: true, result: agentInitializationService.start(plan, actor, parsed.dryRun) };
|
|
4180
|
+
}
|
|
4181
|
+
catch (error) {
|
|
4182
|
+
return fail(error.code ?? 'INVALID_ARGS', error.message);
|
|
4183
|
+
}
|
|
4184
|
+
}
|
|
3970
4185
|
if (operation === 'agent.create') {
|
|
3971
4186
|
const aid = argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined;
|
|
3972
4187
|
if (!aid)
|
|
@@ -4094,6 +4309,11 @@ async function main() {
|
|
|
4094
4309
|
const result = await execAgentAction(sub, { aid: targetAid ?? taskAid, force: argv.includes('--force') }, delegation.grant.actorId, eventBus, agentApplicationService);
|
|
4095
4310
|
return 'error' in result ? fail(result.code, result.error) : { ok: true, result: { ok: true, ...(result.data ?? {}) } };
|
|
4096
4311
|
});
|
|
4312
|
+
ipcServer.setTaskResumeExecutor(params => executeTaskResume(params, {
|
|
4313
|
+
sessions: sessionManager,
|
|
4314
|
+
authorizeManaged: authorizeManagedAgentOperation,
|
|
4315
|
+
recover: request => responseEngine.recoverTask(request),
|
|
4316
|
+
}));
|
|
4097
4317
|
ipcServer.setQueueOperationExecutor(async (params) => {
|
|
4098
4318
|
const operation = `ec.queue.${params.action ?? 'read'}`;
|
|
4099
4319
|
const authorization = await authorizeManagedAgentOperation(params, operation);
|
|
@@ -4134,6 +4354,38 @@ async function main() {
|
|
|
4134
4354
|
const authorization = await authorizeManagedAgentOperation({ ...params, targetAid: params.aid }, params.operation);
|
|
4135
4355
|
return authorization.ok ? { ok: true } : authorization;
|
|
4136
4356
|
});
|
|
4357
|
+
ipcServer.setStorageUploadExecutor(async (params) => {
|
|
4358
|
+
const authorization = await authorizeManagedAgentOperation({ ...params, targetAid: params.aid }, 'storage.upload');
|
|
4359
|
+
if (!authorization.ok)
|
|
4360
|
+
return authorization;
|
|
4361
|
+
const session = await sessionManager.getSessionById(params.sessionId);
|
|
4362
|
+
if (!session)
|
|
4363
|
+
return { ok: false, code: 'SESSION_NOT_FOUND', error: 'current session not found' };
|
|
4364
|
+
try {
|
|
4365
|
+
const projectPath = fs.realpathSync(path.resolve(session.projectPath));
|
|
4366
|
+
const requestedFile = path.resolve(session.projectPath, params.localFile);
|
|
4367
|
+
const requestedStat = fs.lstatSync(requestedFile);
|
|
4368
|
+
if (requestedStat.isSymbolicLink()) {
|
|
4369
|
+
return { ok: false, code: 'INVALID_LOCAL_FILE', error: 'Upload source must not be a symbolic link' };
|
|
4370
|
+
}
|
|
4371
|
+
const localFile = fs.realpathSync(requestedFile);
|
|
4372
|
+
const stat = fs.lstatSync(localFile);
|
|
4373
|
+
if (!isSameOrDescendant(localFile, projectPath) || isHClassPath(localFile)) {
|
|
4374
|
+
return { ok: false, code: 'INVALID_LOCAL_PATH', error: 'Upload source must be an unprotected file inside the current session project' };
|
|
4375
|
+
}
|
|
4376
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4377
|
+
return { ok: false, code: 'INVALID_LOCAL_FILE', error: 'Upload source must be a regular non-symlink file' };
|
|
4378
|
+
}
|
|
4379
|
+
const { storageUpload } = await import('./aun/storage/index.js');
|
|
4380
|
+
const result = await storageUpload(authorization.aid, localFile, params.remotePath, { isPublic: params.isPublic });
|
|
4381
|
+
return result.ok
|
|
4382
|
+
? { ok: true, objectKey: result.objectKey, publicUrl: result.publicUrl }
|
|
4383
|
+
: { ok: false, code: 'STORAGE_UPLOAD_FAILED', error: result.error };
|
|
4384
|
+
}
|
|
4385
|
+
catch (error) {
|
|
4386
|
+
return { ok: false, code: 'INVALID_LOCAL_FILE', error: error instanceof Error ? error.message : String(error) };
|
|
4387
|
+
}
|
|
4388
|
+
});
|
|
4137
4389
|
ipcServer.setTriggerExecutor(async (cmd) => {
|
|
4138
4390
|
const schedulerFor = (agentAid) => {
|
|
4139
4391
|
const scheduler = triggerSchedulers.get(agentAid);
|
|
@@ -4537,6 +4789,8 @@ async function main() {
|
|
|
4537
4789
|
timestamp: Date.now()
|
|
4538
4790
|
});
|
|
4539
4791
|
// 断开插件系统的渠道
|
|
4792
|
+
removeGroupInviteConfigListener();
|
|
4793
|
+
await shutdownStep('stop group invitation review', () => groupInviteReviewService.dispose());
|
|
4540
4794
|
await shutdownStep('disconnect channels', () => channelLoader.disconnectAll(channelInstances));
|
|
4541
4795
|
for (const inst of channelInstances) {
|
|
4542
4796
|
const type = inst.channelType || inst.adapter.channelName;
|