evolcore 0.0.31 → 0.0.33
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 +35 -0
- package/bin/install-codex-managed-hooks.mjs +124 -37
- package/dist/agents/claude-runner.js +29 -2
- package/dist/agents/codex/app-server-client.js +3 -0
- package/dist/agents/codex/diagnostics.js +76 -44
- package/dist/agents/codex-runner.js +51 -24
- package/dist/agents/ecagent-runner.js +9 -13
- package/dist/agents/gemini-runner.js +4 -0
- package/dist/aun/aid/store.js +0 -81
- package/dist/aun/group/fs-download.js +1 -10
- package/dist/aun/group/operations.js +0 -1
- package/dist/aun/msg/history.js +1 -0
- package/dist/aun/msg/managed-operation.js +130 -32
- package/dist/aun/msg/p2p.js +0 -1
- package/dist/aun/outbox.js +50 -1
- package/dist/aun/service-proxy.js +12 -18
- package/dist/aun/storage/index.js +29 -0
- package/dist/channels/aun.js +38 -137
- package/dist/channels/daemon.js +257 -2
- package/dist/cli/agent-command.js +64 -31
- package/dist/cli/agent-create.js +43 -24
- package/dist/cli/agent.js +16 -70
- package/dist/cli/aun-commands.js +512 -32
- package/dist/cli/contact.js +8 -2
- package/dist/cli/ctl-command.js +1 -2
- package/dist/cli/daemon-commands.js +82 -13
- package/dist/cli/debug-mode.js +154 -0
- package/dist/cli/diag.js +2 -2
- package/dist/cli/handoff-command.js +18 -5
- package/dist/cli/index.js +81 -64
- package/dist/cli/init.js +2 -2
- package/dist/cli/managed-command-guard.js +5 -0
- package/dist/cli/memory-command.js +93 -12
- package/dist/cli/model.js +14 -138
- package/dist/cli/queue-command.js +51 -0
- package/dist/cli/response.js +5 -54
- package/dist/cli/session-command.js +194 -0
- package/dist/cli/skill-command.js +85 -3
- package/dist/cli/stats.js +10 -4
- package/dist/cli/task-command.js +1 -0
- package/dist/cli/task-context.js +16 -0
- package/dist/cli/thread-command.js +620 -0
- package/dist/cli/trigger-command.js +76 -50
- package/dist/config/builtin-roles.js +9 -7
- package/dist/config/config-field-policy.js +2 -3
- package/dist/config/config-manager.js +7 -2
- package/dist/config/resolved-config-op.js +3 -0
- package/dist/config-store.js +15 -0
- package/dist/core/agent-ipc-registration.js +65 -22
- package/dist/core/auth/agent-delegation.js +42 -2
- package/dist/core/auth/debug-context.js +139 -0
- package/dist/core/auth/delegation-authorization.js +1 -0
- package/dist/core/auth/operation-authorizer.js +24 -1
- package/dist/core/auth/operation-catalog.js +44 -3
- package/dist/core/background-session/session-cleanup.js +212 -0
- package/dist/core/background-session/types.js +10 -0
- package/dist/core/bootstrap-messages.js +1 -1
- package/dist/core/bootstrap-service.js +6 -3
- package/dist/core/command/command-handler.js +224 -45
- package/dist/core/command/diag-service.js +5 -1
- package/dist/core/command/memory-slash.js +6 -2
- package/dist/core/command/menu-catalog.js +48 -1
- package/dist/core/command/menu-handler.js +92 -16
- package/dist/core/command/menu-protocol.js +24 -1
- package/dist/core/command/skill-slash.js +322 -0
- package/dist/core/command/slash-gate.js +6 -4
- package/dist/core/command/slash-handler.js +193 -13
- package/dist/core/command/topic-slash.js +528 -0
- package/dist/core/evolagent-registry.js +20 -5
- package/dist/core/handoff/ipc-registration.js +38 -0
- package/dist/core/handoff/runtime.js +5 -11
- package/dist/core/handoff/store.js +5 -0
- package/dist/core/ipc-registration.js +210 -9
- package/dist/core/memory/consolidation-context.js +49 -16
- package/dist/core/memory/consolidation-ops-records.js +35 -0
- package/dist/core/memory/consolidation-queue-format.js +21 -0
- package/dist/core/memory/consolidation.js +174 -180
- package/dist/core/message/aun-ipc-sender.js +207 -8
- package/dist/core/message/im-renderer.js +149 -6
- package/dist/core/message/message-bridge.js +13 -3
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +131 -3
- package/dist/core/message/peer-mode.js +6 -1
- package/dist/core/message/response-engine.js +379 -69
- package/dist/core/message/subtask-tool-projection.js +140 -0
- package/dist/core/model/catalog-service.js +17 -12
- package/dist/core/permission/ec-command-parser.js +126 -7
- package/dist/core/permission/sandbox-runtime.js +14 -1
- package/dist/core/session/session-idle-monitor.js +249 -22
- package/dist/core/session/session-manager.js +54 -9
- package/dist/core/skill/command-parser.js +13 -0
- package/dist/core/skill/index-generator.js +4 -1
- package/dist/core/skill/startup.js +41 -0
- package/dist/core/skill/switch-resolver.js +55 -29
- package/dist/core/task/task-recovery-service.js +2 -0
- package/dist/core/task/task-resume-operation.js +11 -0
- package/dist/core/thread/command-parser.js +125 -0
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +95 -0
- package/dist/core/thread/thread-context-storage.js +131 -0
- package/dist/core/thread/thread-operation.js +258 -0
- package/dist/core/thread/thread-route.js +33 -0
- package/dist/core/thread/thread-service.js +777 -0
- package/dist/core/thread/types.js +1 -0
- package/dist/eck/message-renderer.js +35 -0
- package/dist/index.js +10 -7
- package/dist/ipc.js +234 -17
- package/dist/paths.js +23 -0
- package/dist/response-system/engines/v1/proactive-flow.js +169 -80
- package/dist/trigger/authorization.js +59 -29
- package/dist/trigger/feedback.js +7 -1
- package/dist/trigger/ipc-service.js +49 -35
- package/dist/trigger/parser.js +63 -1
- package/dist/trigger/script-sandbox.js +58 -77
- package/dist/trigger/validation.js +14 -0
- package/dist/utils/error-utils.js +22 -1
- package/kits/docs/AUTHORING.md +1 -1
- package/kits/docs/channels/aun.md +8 -0
- package/kits/docs/context-assembly.md +1 -0
- package/kits/docs/evolcore/INDEX.md +3 -2
- package/kits/docs/evolcore/agent-create.md +39 -28
- package/kits/docs/evolcore/agent.md +19 -4
- package/kits/docs/evolcore/ec-capabilities.md +4 -0
- package/kits/docs/evolcore/group-collaboration.md +3 -5
- package/kits/docs/evolcore/group.md +3 -4
- package/kits/docs/evolcore/memory-consolidation.md +1 -1
- package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
- package/kits/docs/evolcore/menu-protocol.md +7 -0
- package/kits/docs/evolcore/msg.md +5 -8
- package/kits/docs/evolcore/task.md +2 -0
- package/kits/docs/evolcore/thread-chain.md +267 -0
- package/kits/docs/evolcore/trigger.md +2 -2
- package/kits/docs/prompt-loading-architecture.md +1 -0
- package/kits/eck_manifest.json +61 -26
- package/kits/eck_message_manifest.json +169 -10
- package/kits/rules/01-overview.md +0 -9
- package/kits/rules/05-venue.md +1 -1
- package/kits/rules/06-channel.md +7 -1
- package/kits/rules/07-memory-and-thread.md +202 -0
- package/kits/schemas/relation-config.schema.9.json +18 -3
- package/kits/schemas/role-config.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.2.json +6 -6
- package/kits/schemas/single-session.schema.3.json +6 -6
- package/kits/skills/.switches.json +12 -1
- package/kits/skills/ec-group/SKILL.md +234 -0
- package/kits/skills/ec-skill/SKILL.md +10 -1
- package/kits/skills/ec-skill/scripts/cli.mjs +15 -1
- package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
- package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
- package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
- package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
- package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
- package/kits/skills/thread-ops/SKILL.md +492 -0
- package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
- package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
- package/kits/skills/wechat-article-reader/SKILL.md +97 -0
- package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
- package/kits/templates/bootstrap-welcome.md +7 -7
- package/kits/templates/memory-consolidation/forget.md +5 -0
- package/kits/templates/memory-consolidation/generalize.md +5 -0
- package/kits/templates/memory-consolidation/profile.md +5 -0
- package/kits/templates/memory-consolidation/promote.md +5 -0
- package/kits/templates/message-fragments/item.md +2 -1
- package/kits/templates/message-fragments/thread-context.md +6 -0
- package/kits/templates/message-fragments/trigger-session.md +2 -0
- package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
- package/kits/templates/roles/member.json +2 -0
- package/kits/templates/roles/visitor.json +2 -0
- package/kits/templates/system-fragments/bootstrap.md +66 -72
- package/kits/templates/system-fragments/channel.md +3 -6
- package/kits/templates/system-fragments/commands.md +2 -1
- package/kits/templates/system-fragments/managed-runtime.md +15 -0
- package/kits/templates/system-fragments/reply.md +3 -2
- package/kits/templates/system-fragments/session.md +5 -14
- package/package.json +3 -1
- package/kits/docs/evolcore/group-fs.md +0 -17
- package/kits/docs/venues/aun-group.md +0 -45
- package/kits/docs/venues/group.md +0 -43
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -50,6 +50,8 @@ function renderOneItem(item, sessionVars, sessionCache, contentSentinel) {
|
|
|
50
50
|
};
|
|
51
51
|
const isOwnerHint = item.kind === 'owner-hint';
|
|
52
52
|
const isHandoff = item.kind === 'handoff';
|
|
53
|
+
const isThreadContext = item.kind === 'thread-context';
|
|
54
|
+
const isTriggerMsg = item.kind === 'trigger';
|
|
53
55
|
const handoffPreviousSentinel = `\x00ECMSG-HANDOFF-PREV-${randomUUID()}\x00`;
|
|
54
56
|
const requiredReplacements = (item.handoff?.requiredEntries ?? []).map(entry => ({
|
|
55
57
|
entry,
|
|
@@ -131,6 +133,39 @@ function renderOneItem(item, sessionVars, sessionCache, contentSentinel) {
|
|
|
131
133
|
injectTime: isOwnerHint
|
|
132
134
|
? formatLocalTime(item.injectTime ?? item.timestamp ?? Date.now(), sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
133
135
|
: undefined,
|
|
136
|
+
// T4: 跨会话上下文(thread-inbox 注入)
|
|
137
|
+
isThreadContext,
|
|
138
|
+
threadContextOriginThreadId: item.threadContext?.originThreadId,
|
|
139
|
+
threadContextOriginPeer: item.threadContext?.originPeer,
|
|
140
|
+
threadContextTime: item.timestamp !== undefined
|
|
141
|
+
? formatLocalTime(item.timestamp, sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
142
|
+
: undefined,
|
|
143
|
+
threadContextGapHasNewMessages: item.threadContext?.gapDetection.hasNewMessages === true,
|
|
144
|
+
threadContextGapCount: item.threadContext?.gapDetection.count,
|
|
145
|
+
// M1: 空洞检测失败(来源话题的 messages.jsonl 缺失/损坏)时,gapDetection 保守返回
|
|
146
|
+
// hasNewMessages=false,与"确实无新消息"渲染结果相同。透出 error 让模板提示"无法检测",
|
|
147
|
+
// 避免 agent 把检测失败误读成"来源话题无更新"。
|
|
148
|
+
threadContextGapError: item.threadContext?.gapDetection.error,
|
|
149
|
+
threadContextGapRange: (() => {
|
|
150
|
+
const g = item.threadContext?.gapDetection;
|
|
151
|
+
if (!g?.hasNewMessages || g.firstTimestamp === undefined || g.lastTimestamp === undefined)
|
|
152
|
+
return undefined;
|
|
153
|
+
const tz = sessionVars.timezone ? String(sessionVars.timezone) : undefined;
|
|
154
|
+
return `${formatLocalTime(g.firstTimestamp, tz)} - ${formatLocalTime(g.lastTimestamp, tz)}`;
|
|
155
|
+
})(),
|
|
156
|
+
threadContextTriggerId: item.threadContext?.triggerId,
|
|
157
|
+
// T9: trigger 消息专属信封变量
|
|
158
|
+
isTriggerMsg,
|
|
159
|
+
triggerMsgId: isTriggerMsg ? item.triggerInfo?.triggerId : undefined,
|
|
160
|
+
triggerMsgName: isTriggerMsg ? item.triggerInfo?.triggerName : undefined,
|
|
161
|
+
triggerMsgFireTime: isTriggerMsg && item.triggerInfo?.fireTime !== undefined
|
|
162
|
+
? formatLocalTime(item.triggerInfo.fireTime, sessionVars.timezone ? String(sessionVars.timezone) : undefined)
|
|
163
|
+
: undefined,
|
|
164
|
+
// T10: labels 路由 key(默认 'default')+ 动态展开 triggerMsgLabel_<key>
|
|
165
|
+
triggerMsgKind: isTriggerMsg ? (item.triggerInfo?.labels?.kind ?? 'default') : undefined,
|
|
166
|
+
...(isTriggerMsg && item.triggerInfo?.labels
|
|
167
|
+
? Object.fromEntries(Object.entries(item.triggerInfo.labels).map(([k, v]) => [`triggerMsgLabel_${k}`, v]))
|
|
168
|
+
: {}),
|
|
134
169
|
// msg send 跨会话一次性上下文
|
|
135
170
|
isHandoff,
|
|
136
171
|
handoffKind: item.handoff?.kind,
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { createSessionIdentityResolver } from './config/peer-role-resolver.js';
|
|
|
22
22
|
import { initializeStartupConfig, prepareStartupConfig, recordStartupConfig } from './config/boot-log.js';
|
|
23
23
|
import { CONFIG_SCHEMA_VERSION } from './types.js';
|
|
24
24
|
import { SessionManager } from './core/session/session-manager.js';
|
|
25
|
-
import { SessionIdleMonitor,
|
|
25
|
+
import { SessionIdleMonitor, readSessionLoopIdleSeconds } from './core/session/session-idle-monitor.js';
|
|
26
26
|
import { ClaudeAgentPlugin } from './agents/claude-runner.js';
|
|
27
27
|
import { CodexAgentPlugin } from './agents/codex-runner.js';
|
|
28
28
|
import { GeminiAgentPlugin } from './agents/gemini-runner.js';
|
|
@@ -426,13 +426,15 @@ async function main() {
|
|
|
426
426
|
getSessionById: sessionId => sessionManager.getSessionById(sessionId),
|
|
427
427
|
isSessionBusy: sessionId => messageQueue.isProcessing(sessionId) || messageQueue.getQueueLength(sessionId) > 0,
|
|
428
428
|
getSessionIdleTriggerIds: () => triggerSchedulers.sessionIdleTriggerIds(),
|
|
429
|
-
getSessionIdleSeconds:
|
|
429
|
+
getSessionIdleSeconds: readSessionLoopIdleSeconds,
|
|
430
430
|
getSessionEncrypt: sessionId => sessionManager.getSessionEncrypt(sessionId),
|
|
431
|
+
isCurrentMainSession: session => sessionManager.getActiveSessionSync(session.channel, session.channelId)?.id === session.id,
|
|
431
432
|
});
|
|
432
433
|
sessionIdleMonitor.start();
|
|
433
434
|
onConfigWrite(({ target, selector }) => {
|
|
434
|
-
if (target === ConfigTarget.Relation && selector.self)
|
|
435
|
-
sessionIdleMonitor.
|
|
435
|
+
if (target === ConfigTarget.Relation && selector.self && selector.peerKey) {
|
|
436
|
+
void sessionIdleMonitor.refreshRelation(selector.self, selector.peerKey);
|
|
437
|
+
}
|
|
436
438
|
});
|
|
437
439
|
onShutdown(() => sessionIdleMonitor.stop());
|
|
438
440
|
const targetSessionLocks = new TargetSessionLockRegistry();
|
|
@@ -490,10 +492,11 @@ async function main() {
|
|
|
490
492
|
sessionManager,
|
|
491
493
|
getAgent: aid => agentRegistry.get(aid),
|
|
492
494
|
agentMap,
|
|
493
|
-
releaseSlot: aid => consolidationQueue.release(aid),
|
|
495
|
+
releaseSlot: (aid, sessionId) => consolidationQueue.release(aid, sessionId),
|
|
494
496
|
enqueueConsolidation,
|
|
495
497
|
sendFeedback: sendConsolidationFeedback,
|
|
496
498
|
});
|
|
499
|
+
consolidationQueue.setFinalizer(finishConsolidationSession);
|
|
497
500
|
registerConsolidationSessionEvents({
|
|
498
501
|
eventBus,
|
|
499
502
|
permissionGateway,
|
|
@@ -640,11 +643,11 @@ async function main() {
|
|
|
640
643
|
getAgentRuntimeError: () => agentRuntimeError,
|
|
641
644
|
daemonAid: daemonCfg.aid,
|
|
642
645
|
getControlAidState: () => controlChannel?.getAidState(),
|
|
643
|
-
}), async (
|
|
646
|
+
}), async (argv, sessionId, delegationToken, delegationCommandHash) => {
|
|
644
647
|
const delegation = agentDelegationRegistry.validate(delegationToken, sessionId, delegationCommandHash);
|
|
645
648
|
if (!delegation.ok)
|
|
646
649
|
return { ok: false, code: delegation.code, error: delegation.reason };
|
|
647
|
-
return cmdHandler.
|
|
650
|
+
return cmdHandler.handleManagedCliOperation(argv, sessionId, delegation.grant);
|
|
648
651
|
});
|
|
649
652
|
ipcServer.setDaemonRuntimeEpoch(agentDelegationRegistry.getRuntimeEpoch());
|
|
650
653
|
const { reloadHooks, reloadCoordinator } = createAgentReloadRuntime({
|
package/dist/ipc.js
CHANGED
|
@@ -17,10 +17,12 @@ import { getProcessStartTime, isSameOrOlderProcess } from './utils/process-intro
|
|
|
17
17
|
import { classifyProcessTree, ProcessTreeSampler, readProcessMetrics } from './utils/process-tree-stats.js';
|
|
18
18
|
import { readSystemMemoryUsage } from './utils/system-memory.js';
|
|
19
19
|
import { hashCurrentDelegatedCommand, hashDelegatedCommandArgv } from './core/auth/agent-delegation.js';
|
|
20
|
+
import { resolveSkillRefreshArgv } from './core/skill/command-parser.js';
|
|
20
21
|
import { normalizeAunMentionEntries } from './aun/msg/mention-schema.js';
|
|
21
22
|
import { remoteAccessService } from './core/auth/remote-access-store.js';
|
|
22
23
|
import { setModelCatalogDaemonOwner } from './core/model/model-catalog.js';
|
|
23
24
|
import { RUNTIME_ENVIRONMENT_NAMES, setRuntimeEnvironmentOverride } from './config/runtime-env.js';
|
|
25
|
+
import { MAIN_CLI_BIN } from './product.js';
|
|
24
26
|
const isWindows = process.platform === 'win32';
|
|
25
27
|
const isNamedPipe = (p) => isWindows && p.toLowerCase().startsWith('\\\\.\\pipe\\');
|
|
26
28
|
const CPU_SAMPLE_INTERVAL_MS = 1000;
|
|
@@ -75,6 +77,16 @@ const LOCAL_CONTROL_COMMANDS = new Set([
|
|
|
75
77
|
'remote-auth.redeem',
|
|
76
78
|
'remote-auth.validate',
|
|
77
79
|
]);
|
|
80
|
+
const MEMORY_COMMAND_ENDPOINTS = new Set([
|
|
81
|
+
'memory.note', 'memory.note.update', 'memory.note.drop', 'memory.note.list',
|
|
82
|
+
'memory.create', 'memory.update', 'memory.archive', 'memory.demote', 'memory.consolidate', 'memory.feedback',
|
|
83
|
+
]);
|
|
84
|
+
const DELEGATED_ARGV_ENDPOINTS = new Set([
|
|
85
|
+
'agent.op', 'config.op', 'contact.op', 'aid.op', 'group.op', 'msg.op', 'fs.op',
|
|
86
|
+
'ctl', 'diag', 'menu-client.request', 'task.resume', 'queue.op', 'storage.auth', 'storage.upload',
|
|
87
|
+
'trigger.op', 'skill.refresh', 'thread.op', 'local-command-context', 'evolagent.bootstrapComplete', ...MEMORY_COMMAND_ENDPOINTS,
|
|
88
|
+
'handoff-return', 'handoff-recover-return', 'handoff-status', 'handoff-list', 'handoff-trace',
|
|
89
|
+
]);
|
|
78
90
|
let ipcQuerySequence = 0;
|
|
79
91
|
function ipcLogToken(value, fallback = 'unknown') {
|
|
80
92
|
const token = String(value ?? '').replace(/[^A-Za-z0-9_.:-]/g, '_').slice(0, 128);
|
|
@@ -94,9 +106,17 @@ function nextIpcQueryId(cmd) {
|
|
|
94
106
|
function requiresLocalControlToken(cmd) {
|
|
95
107
|
// Managed calls use task delegation. Standalone queries must not gain
|
|
96
108
|
// management scope merely by omitting (or emptying) sessionId.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
const type = String(cmd.type ?? '');
|
|
110
|
+
const sessionId = typeof cmd.sessionId === 'string' && cmd.sessionId.trim();
|
|
111
|
+
const delegated = typeof cmd.delegationToken === 'string' && cmd.delegationToken.trim();
|
|
112
|
+
if (cmd.type === 'evolagent.initialize' || LOCAL_CONTROL_COMMANDS.has(type))
|
|
113
|
+
return true;
|
|
114
|
+
if (type === 'debug-issue-token')
|
|
115
|
+
return true;
|
|
116
|
+
if (type === 'skill.refresh' || type === 'thread.op')
|
|
117
|
+
return !sessionId || !delegated;
|
|
118
|
+
return ['evolagent.bootstrapComplete', 'diag', 'handoff-status', 'handoff-list', 'handoff-trace', 'task.resume'].includes(type)
|
|
119
|
+
&& !sessionId;
|
|
100
120
|
}
|
|
101
121
|
/** Preserve the pipe DACL and grant only the provisioned Codex users data I/O. */
|
|
102
122
|
function grantWindowsSandboxPipeAccess(endpoint) {
|
|
@@ -153,6 +173,7 @@ export class IpcServer {
|
|
|
153
173
|
aunAidStatsRecorder;
|
|
154
174
|
menuExecutor;
|
|
155
175
|
agentOperationExecutor;
|
|
176
|
+
skillRefreshExecutor;
|
|
156
177
|
initializationExecutor;
|
|
157
178
|
statsProvider;
|
|
158
179
|
agentStatsProvider;
|
|
@@ -171,6 +192,7 @@ export class IpcServer {
|
|
|
171
192
|
shutdownExecutor;
|
|
172
193
|
taskRuntimeContextProvider;
|
|
173
194
|
debugTaskRuntimeContextProvider;
|
|
195
|
+
debugIssueTokenExecutor;
|
|
174
196
|
taskRuntimeContextAuthorizer;
|
|
175
197
|
codexPreToolUseExecutor;
|
|
176
198
|
aunMsgSender;
|
|
@@ -188,6 +210,7 @@ export class IpcServer {
|
|
|
188
210
|
groupOperationExecutor;
|
|
189
211
|
msgOperationExecutor;
|
|
190
212
|
fsOperationExecutor;
|
|
213
|
+
threadOperationExecutor;
|
|
191
214
|
dingtalkContactBindExecutor;
|
|
192
215
|
feishuContactBindExecutor;
|
|
193
216
|
qqbotContactBindExecutor;
|
|
@@ -275,6 +298,9 @@ export class IpcServer {
|
|
|
275
298
|
setAgentOperationExecutor(executor) {
|
|
276
299
|
this.agentOperationExecutor = executor;
|
|
277
300
|
}
|
|
301
|
+
setSkillRefreshExecutor(executor) {
|
|
302
|
+
this.skillRefreshExecutor = executor;
|
|
303
|
+
}
|
|
278
304
|
setConfigOperationExecutor(executor) {
|
|
279
305
|
this.configOperationExecutor = executor;
|
|
280
306
|
}
|
|
@@ -293,6 +319,9 @@ export class IpcServer {
|
|
|
293
319
|
setFsOperationExecutor(executor) {
|
|
294
320
|
this.fsOperationExecutor = executor;
|
|
295
321
|
}
|
|
322
|
+
setThreadOperationExecutor(executor) {
|
|
323
|
+
this.threadOperationExecutor = executor;
|
|
324
|
+
}
|
|
296
325
|
setAgentReloadExecutor(executor) {
|
|
297
326
|
this.agentReloadExecutor = executor;
|
|
298
327
|
}
|
|
@@ -428,7 +457,7 @@ export class IpcServer {
|
|
|
428
457
|
setTriggerExecutor(executor) {
|
|
429
458
|
this.triggerExecutor = executor;
|
|
430
459
|
}
|
|
431
|
-
/** Inject daemon-level consolidation launcher
|
|
460
|
+
/** Inject daemon-level consolidation launcher (BackgroundSessionLauncher, via executor closure). */
|
|
432
461
|
setConsolidationLaunchExecutor(executor) {
|
|
433
462
|
this.consolidationLaunchExecutor = executor;
|
|
434
463
|
}
|
|
@@ -444,15 +473,17 @@ export class IpcServer {
|
|
|
444
473
|
setTaskRuntimeContextProvider(provider) {
|
|
445
474
|
this.taskRuntimeContextProvider = provider;
|
|
446
475
|
}
|
|
447
|
-
/** 仅开发仓(npm link)安装注册;正式安装不调用,debug 请求一律走正常路径。 */
|
|
448
476
|
setDebugTaskRuntimeContextProvider(provider) {
|
|
449
477
|
this.debugTaskRuntimeContextProvider = provider;
|
|
450
478
|
}
|
|
479
|
+
/** debug 模式:注册 debug-issue-token executor,仅 EVOLCORE_DEBUG_MODE=1 时由 index.ts 调用。 */
|
|
480
|
+
setDebugIssueTokenExecutor(executor) {
|
|
481
|
+
this.debugIssueTokenExecutor = executor;
|
|
482
|
+
}
|
|
451
483
|
/**
|
|
452
|
-
* memory
|
|
453
|
-
* 再由开发仓专用的 provider 从会话文件重建。
|
|
484
|
+
* memory 命令取运行时上下文:查正在运行的任务。
|
|
454
485
|
*/
|
|
455
|
-
async resolveMemoryTaskCtx(sessionId, debug) {
|
|
486
|
+
async resolveMemoryTaskCtx(sessionId, debug = false) {
|
|
456
487
|
const active = this.taskRuntimeContextProvider?.({ sessionId });
|
|
457
488
|
if (active || !debug || !this.debugTaskRuntimeContextProvider)
|
|
458
489
|
return active;
|
|
@@ -468,6 +499,14 @@ export class IpcServer {
|
|
|
468
499
|
setAunMsgSender(sender) {
|
|
469
500
|
this.aunMsgSender = sender;
|
|
470
501
|
}
|
|
502
|
+
hasAunMsgSender() {
|
|
503
|
+
return this.aunMsgSender !== undefined;
|
|
504
|
+
}
|
|
505
|
+
async sendAunMsg(params) {
|
|
506
|
+
if (!this.aunMsgSender)
|
|
507
|
+
throw new Error('aunMsgSender not configured');
|
|
508
|
+
return this.aunMsgSender(params);
|
|
509
|
+
}
|
|
471
510
|
setDiagExecutor(executor) { this.diagExecutor = executor; }
|
|
472
511
|
setMenuClientExecutor(executor) { this.menuClientExecutor = executor; }
|
|
473
512
|
/** Inject internal handoff result return executor for `ec handoff return`. */
|
|
@@ -917,6 +956,7 @@ export class IpcServer {
|
|
|
917
956
|
}
|
|
918
957
|
if (typeof cmd.delegationToken === 'string' && cmd.delegationToken
|
|
919
958
|
&& this.daemonRuntimeEpoch
|
|
959
|
+
&& cmd.daemonRuntimeEpoch !== undefined
|
|
920
960
|
&& cmd.daemonRuntimeEpoch !== this.daemonRuntimeEpoch) {
|
|
921
961
|
logger.warn(`[IPC] stale delegation rejected: session=${ipcLogToken(cmd.sessionId ?? cmd.originSessionId ?? cmd.actorSessionId)} type=${ipcLogToken(cmd.type)} cause=daemon_runtime_epoch_mismatch`);
|
|
922
962
|
return {
|
|
@@ -925,6 +965,75 @@ export class IpcServer {
|
|
|
925
965
|
error: 'The task delegation token belongs to a previous daemon runtime; start a new task authorization and do not retry this command in the current task',
|
|
926
966
|
};
|
|
927
967
|
}
|
|
968
|
+
if (typeof cmd.delegationToken === 'string'
|
|
969
|
+
&& (DELEGATED_ARGV_ENDPOINTS.has(cmd.type) || (cmd.type === 'aun-msg-send' && cmd.argv !== undefined))) {
|
|
970
|
+
if (!Array.isArray(cmd.argv) || cmd.argv.some(value => typeof value !== 'string')) {
|
|
971
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Invalid command argv' };
|
|
972
|
+
}
|
|
973
|
+
const expectedHash = hashDelegatedCommandArgv([
|
|
974
|
+
MAIN_CLI_BIN,
|
|
975
|
+
...(cmd.type === 'menu-client.request' ? ['menu-client'] : []),
|
|
976
|
+
...cmd.argv,
|
|
977
|
+
]);
|
|
978
|
+
if (!expectedHash || cmd.delegationCommandHash !== expectedHash) {
|
|
979
|
+
return { ok: false, code: 'INVALID_DELEGATION', error: 'Command hash does not match the submitted argv' };
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
if (cmd.argv !== undefined && ['handoff-status', 'handoff-list', 'handoff-trace'].includes(cmd.type)) {
|
|
983
|
+
try {
|
|
984
|
+
const { parseList, parseTrace } = await import('./cli/handoff-command.js');
|
|
985
|
+
if (!Array.isArray(cmd.argv) || cmd.argv[0] !== 'handoff' || `handoff-${cmd.argv[1]}` !== cmd.type) {
|
|
986
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Handoff endpoint does not match argv' };
|
|
987
|
+
}
|
|
988
|
+
if (cmd.type === 'handoff-list') {
|
|
989
|
+
const parsed = parseList(cmd.argv.slice(2));
|
|
990
|
+
cmd = { ...cmd, agent: parsed.agent, state: parsed.state, filterSessionId: parsed.sessionId, limit: parsed.limit };
|
|
991
|
+
}
|
|
992
|
+
else {
|
|
993
|
+
const parsed = parseTrace(cmd.argv.slice(2));
|
|
994
|
+
if (cmd.type === 'handoff-status' && cmd.argv.length !== 3)
|
|
995
|
+
throw new Error('Invalid handoff status arguments');
|
|
996
|
+
cmd = { ...cmd, agent: parsed.agent, handoffId: parsed.handoffId, limit: parsed.limit };
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
catch (error) {
|
|
1000
|
+
return { ok: false, code: 'INVALID_ARGUMENT', error: error instanceof Error ? error.message : String(error) };
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
if (MEMORY_COMMAND_ENDPOINTS.has(cmd.type)) {
|
|
1004
|
+
if (typeof cmd.sessionId !== 'string' || !cmd.sessionId)
|
|
1005
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'missing sessionId' };
|
|
1006
|
+
if (cmd.debug === true) {
|
|
1007
|
+
if (cmd.delegationToken || !this.hasValidControlToken(cmd.controlToken)) {
|
|
1008
|
+
return { ok: false, code: 'INVALID_CONTROL_TOKEN', error: 'Memory debug requires a local control token, not task delegation' };
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
else {
|
|
1012
|
+
if (!this.taskRuntimeContextAuthorizer)
|
|
1013
|
+
return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Memory authorization is not configured' };
|
|
1014
|
+
if (!Array.isArray(cmd.argv) || cmd.argv.some((value) => typeof value !== 'string') || cmd.argv.includes('--debug')) {
|
|
1015
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Managed memory requires argv without --debug' };
|
|
1016
|
+
}
|
|
1017
|
+
const authorization = this.taskRuntimeContextAuthorizer({
|
|
1018
|
+
sessionId: cmd.sessionId, delegationToken: cmd.delegationToken,
|
|
1019
|
+
delegationCommandHash: cmd.delegationCommandHash, consumeApproval: true,
|
|
1020
|
+
});
|
|
1021
|
+
if (!authorization.ok)
|
|
1022
|
+
return authorization;
|
|
1023
|
+
}
|
|
1024
|
+
if (cmd.argv !== undefined) {
|
|
1025
|
+
try {
|
|
1026
|
+
const { resolveMemoryCommandArgv } = await import('./cli/memory-command.js');
|
|
1027
|
+
const operation = resolveMemoryCommandArgv(cmd.argv);
|
|
1028
|
+
if (operation.type !== cmd.type)
|
|
1029
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Memory endpoint does not match argv' };
|
|
1030
|
+
cmd = { ...operation, sessionId: cmd.sessionId, debug: cmd.debug === true };
|
|
1031
|
+
}
|
|
1032
|
+
catch (error) {
|
|
1033
|
+
return { ok: false, code: 'INVALID_ARGUMENT', error: error instanceof Error ? error.message : String(error) };
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
928
1037
|
switch (cmd.type) {
|
|
929
1038
|
case 'diag':
|
|
930
1039
|
return this.diagExecutor ? this.diagExecutor(cmd) : { ok: false, code: 'NOT_CONFIGURED', message: '诊断入口未配置' };
|
|
@@ -1168,6 +1277,7 @@ export class IpcServer {
|
|
|
1168
1277
|
sessionId: cmd.sessionId,
|
|
1169
1278
|
delegationToken: typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined,
|
|
1170
1279
|
delegationCommandHash: typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined,
|
|
1280
|
+
argv: Array.isArray(cmd.argv) ? cmd.argv : undefined,
|
|
1171
1281
|
});
|
|
1172
1282
|
}
|
|
1173
1283
|
case 'status.auth': {
|
|
@@ -1191,6 +1301,7 @@ export class IpcServer {
|
|
|
1191
1301
|
return { ok: false, code: 'INVALID_REQUEST', error: 'invalid storage operation' };
|
|
1192
1302
|
}
|
|
1193
1303
|
return await this.storageAuthorizationExecutor({
|
|
1304
|
+
argv: cmd.argv,
|
|
1194
1305
|
sessionId: cmd.sessionId,
|
|
1195
1306
|
aid: cmd.aid,
|
|
1196
1307
|
operation: cmd.operation,
|
|
@@ -1208,6 +1319,7 @@ export class IpcServer {
|
|
|
1208
1319
|
return { ok: false, code: 'INVALID_REQUEST', error: 'missing sessionId, aid, localFile, or remotePath' };
|
|
1209
1320
|
}
|
|
1210
1321
|
return await this.storageUploadExecutor({
|
|
1322
|
+
argv: cmd.argv,
|
|
1211
1323
|
sessionId: cmd.sessionId,
|
|
1212
1324
|
aid: cmd.aid,
|
|
1213
1325
|
localFile: cmd.localFile,
|
|
@@ -1235,9 +1347,10 @@ export class IpcServer {
|
|
|
1235
1347
|
}
|
|
1236
1348
|
}
|
|
1237
1349
|
case 'task.resume': {
|
|
1238
|
-
const allowed = new Set(['type', 'targetSessionId', 'sessionId', 'delegationToken',
|
|
1350
|
+
const allowed = new Set(['type', 'argv', 'targetSessionId', 'sessionId', 'delegationToken',
|
|
1239
1351
|
'delegationCommandHash', 'controlToken', 'daemonRuntimeEpoch', 'requestId', 'id']);
|
|
1240
1352
|
if (Object.keys(cmd).some(key => !allowed.has(key))
|
|
1353
|
+
|| (cmd.argv !== undefined && (!Array.isArray(cmd.argv) || cmd.argv.some((value) => typeof value !== 'string')))
|
|
1241
1354
|
|| typeof cmd.targetSessionId !== 'string' || !cmd.targetSessionId.trim()
|
|
1242
1355
|
|| (cmd.sessionId !== undefined && (typeof cmd.sessionId !== 'string' || !cmd.sessionId.trim()))) {
|
|
1243
1356
|
return { ok: false, code: 'INVALID_REQUEST', error: 'task.resume accepts only a target session and caller credentials' };
|
|
@@ -1250,6 +1363,7 @@ export class IpcServer {
|
|
|
1250
1363
|
try {
|
|
1251
1364
|
return await this.taskResumeExecutor({
|
|
1252
1365
|
targetSessionId: cmd.targetSessionId,
|
|
1366
|
+
argv: Array.isArray(cmd.argv) ? cmd.argv : undefined,
|
|
1253
1367
|
sessionId: cmd.sessionId,
|
|
1254
1368
|
delegationToken: typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined,
|
|
1255
1369
|
delegationCommandHash: typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined,
|
|
@@ -1260,6 +1374,34 @@ export class IpcServer {
|
|
|
1260
1374
|
return { ok: false, code: 'TASK_RESUME_FAILED', error: error instanceof Error ? error.message : String(error) };
|
|
1261
1375
|
}
|
|
1262
1376
|
}
|
|
1377
|
+
case 'local-command-context': {
|
|
1378
|
+
if (!Array.isArray(cmd.argv) || cmd.argv.some((value) => typeof value !== 'string')
|
|
1379
|
+
|| !['skill', 'stats'].includes(cmd.argv[0]) || typeof cmd.sessionId !== 'string' || !cmd.sessionId
|
|
1380
|
+
|| typeof cmd.delegationToken !== 'string' || !cmd.delegationToken) {
|
|
1381
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Local command requires argv and task credentials' };
|
|
1382
|
+
}
|
|
1383
|
+
if (!this.taskRuntimeContextAuthorizer || !this.taskRuntimeContextProvider) {
|
|
1384
|
+
return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Command authorization is unavailable' };
|
|
1385
|
+
}
|
|
1386
|
+
const authorization = this.taskRuntimeContextAuthorizer({
|
|
1387
|
+
sessionId: cmd.sessionId, delegationToken: cmd.delegationToken,
|
|
1388
|
+
delegationCommandHash: cmd.delegationCommandHash, consumeApproval: true,
|
|
1389
|
+
});
|
|
1390
|
+
if (!authorization.ok)
|
|
1391
|
+
return authorization;
|
|
1392
|
+
const context = this.taskRuntimeContextProvider({ sessionId: cmd.sessionId });
|
|
1393
|
+
if (!context?.selfAid || !context.peerRole || context.peerRole === 'none') {
|
|
1394
|
+
return { ok: false, code: 'NOT_ALLOWED', error: 'Current task identity and role are unavailable' };
|
|
1395
|
+
}
|
|
1396
|
+
if (cmd.argv[0] === 'stats' && cmd.argv.some((value) => /^--(?:sql|rebuild)(?:=|$)/.test(value))) {
|
|
1397
|
+
return { ok: false, code: 'NOT_ALLOWED', error: 'Managed stats cannot use --sql or --rebuild' };
|
|
1398
|
+
}
|
|
1399
|
+
if (cmd.argv[0] === 'skill' && context.permissionMode === 'readonly'
|
|
1400
|
+
&& ['create', 'install', 'remove', 'enable', 'disable'].includes(cmd.argv[1])) {
|
|
1401
|
+
return { ok: false, code: 'NOT_ALLOWED', error: 'Readonly tasks cannot modify skills' };
|
|
1402
|
+
}
|
|
1403
|
+
return { ok: true, context };
|
|
1404
|
+
}
|
|
1263
1405
|
case 'task-runtime-context': {
|
|
1264
1406
|
if (!this.taskRuntimeContextProvider)
|
|
1265
1407
|
return { ok: false, error: 'task runtime context not configured' };
|
|
@@ -1272,13 +1414,35 @@ export class IpcServer {
|
|
|
1272
1414
|
sessionId: cmd.sessionId,
|
|
1273
1415
|
delegationToken: typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined,
|
|
1274
1416
|
delegationCommandHash: typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined,
|
|
1417
|
+
consumeApproval: false,
|
|
1275
1418
|
});
|
|
1276
1419
|
if (!authorization.ok)
|
|
1277
1420
|
return authorization;
|
|
1278
1421
|
const context = this.taskRuntimeContextProvider({ sessionId: cmd.sessionId }) ?? null;
|
|
1279
1422
|
return { ok: true, context };
|
|
1280
1423
|
}
|
|
1424
|
+
case 'debug-issue-token': {
|
|
1425
|
+
if (cmd.delegationToken)
|
|
1426
|
+
return { ok: false, code: 'NOT_ALLOWED', error: 'Managed tasks cannot issue debug tokens' };
|
|
1427
|
+
// 仅 EVOLCORE_DEBUG_MODE=1 时由 index.ts 注册 executor;非 debug 模式直接拒绝
|
|
1428
|
+
if (!this.debugIssueTokenExecutor) {
|
|
1429
|
+
return { ok: false, error: 'debug mode is not enabled; start daemon with: ec start --debug' };
|
|
1430
|
+
}
|
|
1431
|
+
if (typeof cmd.sessionId !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(cmd.sessionId)) {
|
|
1432
|
+
return { ok: false, error: 'missing sessionId' };
|
|
1433
|
+
}
|
|
1434
|
+
return this.debugIssueTokenExecutor({ sessionId: cmd.sessionId });
|
|
1435
|
+
}
|
|
1281
1436
|
case 'aun-msg-send': {
|
|
1437
|
+
if (cmd.argv !== undefined) {
|
|
1438
|
+
if (!this.aunMsgSender)
|
|
1439
|
+
return { ok: false, code: 'NOT_CONFIGURED', error: 'AUN sender is not configured' };
|
|
1440
|
+
return this.aunMsgSender({
|
|
1441
|
+
aid: '', to: '', scope: 'msg', argv: cmd.argv,
|
|
1442
|
+
originSessionId: cmd.originSessionId, originMessageId: cmd.originMessageId,
|
|
1443
|
+
delegationToken: cmd.delegationToken, delegationCommandHash: cmd.delegationCommandHash,
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1282
1446
|
if (cmd.handoffContext !== undefined && (typeof cmd.handoffContext !== 'string'
|
|
1283
1447
|
|| !cmd.handoffContext.trim() || cmd.handoffContext.length > 64 * 1024 || cmd.scope === 'group')) {
|
|
1284
1448
|
return { ok: false, code: 'INVALID_HANDOFF_CONTEXT', error: 'Private handoff context must contain 1–65536 characters' };
|
|
@@ -1336,7 +1500,6 @@ export class IpcServer {
|
|
|
1336
1500
|
: undefined,
|
|
1337
1501
|
encrypt: typeof cmd.encrypt === 'boolean' ? cmd.encrypt : undefined,
|
|
1338
1502
|
thread: typeof cmd.thread === 'string' ? cmd.thread : undefined,
|
|
1339
|
-
returnPolicy: cmd.returnPolicy === 'required' || cmd.returnPolicy === 'none' ? cmd.returnPolicy : undefined,
|
|
1340
1503
|
handoffContext: cmd.handoffContext,
|
|
1341
1504
|
originSessionId: typeof cmd.originSessionId === 'string' ? cmd.originSessionId : undefined,
|
|
1342
1505
|
originMessageId: typeof cmd.originMessageId === 'string' ? cmd.originMessageId : undefined,
|
|
@@ -1356,6 +1519,7 @@ export class IpcServer {
|
|
|
1356
1519
|
return { ok: false, code: 'HANDOFF_RETURN_CONTENT_REQUIRED', error: 'missing content' };
|
|
1357
1520
|
try {
|
|
1358
1521
|
return await this.handoffReturnExecutor({
|
|
1522
|
+
argv: cmd.argv,
|
|
1359
1523
|
sessionId: typeof cmd.sessionId === 'string' ? cmd.sessionId : undefined,
|
|
1360
1524
|
handoffId: typeof cmd.handoffId === 'string' ? cmd.handoffId : undefined,
|
|
1361
1525
|
content: cmd.content,
|
|
@@ -1378,6 +1542,7 @@ export class IpcServer {
|
|
|
1378
1542
|
return { ok: false, code: 'HANDOFF_RETURN_CONTENT_REQUIRED', error: 'missing content' };
|
|
1379
1543
|
try {
|
|
1380
1544
|
return await this.handoffRecoverReturnExecutor({
|
|
1545
|
+
argv: cmd.argv,
|
|
1381
1546
|
sessionId: cmd.sessionId,
|
|
1382
1547
|
handoffId: cmd.handoffId,
|
|
1383
1548
|
content: cmd.content,
|
|
@@ -1444,10 +1609,13 @@ export class IpcServer {
|
|
|
1444
1609
|
case 'ctl': {
|
|
1445
1610
|
if (!this.commandExecutor)
|
|
1446
1611
|
return { ok: false, error: 'ctl not configured' };
|
|
1447
|
-
const {
|
|
1448
|
-
if (!
|
|
1449
|
-
return { ok: false, error: 'missing
|
|
1450
|
-
|
|
1612
|
+
const { sessionId, argv } = cmd;
|
|
1613
|
+
if (!sessionId || !Array.isArray(argv))
|
|
1614
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'missing argv or sessionId' };
|
|
1615
|
+
if (argv.some(value => typeof value !== 'string')) {
|
|
1616
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Invalid command argv' };
|
|
1617
|
+
}
|
|
1618
|
+
return await this.commandExecutor(argv, sessionId, typeof cmd.delegationToken === 'string' ? cmd.delegationToken : undefined, typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined);
|
|
1451
1619
|
}
|
|
1452
1620
|
case 'memory.note': {
|
|
1453
1621
|
const { sessionId, slug, content, tags, speakers } = cmd;
|
|
@@ -1577,6 +1745,7 @@ export class IpcServer {
|
|
|
1577
1745
|
contextFilePath: r.contextFilePath,
|
|
1578
1746
|
...(r.logFile ? { logFile: r.logFile } : {}),
|
|
1579
1747
|
mode: effectiveMode,
|
|
1748
|
+
...(r.queued ? { queued: r.queued } : {}),
|
|
1580
1749
|
};
|
|
1581
1750
|
}
|
|
1582
1751
|
catch (e) {
|
|
@@ -1845,6 +2014,16 @@ export class IpcServer {
|
|
|
1845
2014
|
}
|
|
1846
2015
|
return await this.fsOperationExecutor(argv, sessionId, delegationToken, typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined);
|
|
1847
2016
|
}
|
|
2017
|
+
case 'thread.op': {
|
|
2018
|
+
if (!this.threadOperationExecutor)
|
|
2019
|
+
return { ok: false, code: 'NOT_CONFIGURED', error: 'thread.op not configured' };
|
|
2020
|
+
const delegated = typeof cmd.delegationToken === 'string' && cmd.delegationToken.trim();
|
|
2021
|
+
const req = {
|
|
2022
|
+
...cmd,
|
|
2023
|
+
localControl: !delegated && this.hasValidControlToken(cmd.controlToken),
|
|
2024
|
+
};
|
|
2025
|
+
return await this.threadOperationExecutor(req);
|
|
2026
|
+
}
|
|
1848
2027
|
case 'evolagent.initialize': {
|
|
1849
2028
|
if (cmd.sessionId || cmd.delegationToken)
|
|
1850
2029
|
return { ok: false, code: 'NOT_ALLOWED', error: 'Managed callers must use agent.op' };
|
|
@@ -1864,11 +2043,38 @@ export class IpcServer {
|
|
|
1864
2043
|
}
|
|
1865
2044
|
return await this.agentOperationExecutor(argv, sessionId, delegationToken, typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined);
|
|
1866
2045
|
}
|
|
2046
|
+
case 'skill.refresh': {
|
|
2047
|
+
if (!this.skillRefreshExecutor) {
|
|
2048
|
+
return { ok: false, code: 'NOT_CONFIGURED', error: 'skill.refresh not configured' };
|
|
2049
|
+
}
|
|
2050
|
+
let { aid } = cmd;
|
|
2051
|
+
const { sessionId, delegationToken } = cmd;
|
|
2052
|
+
if (typeof aid !== 'string' || !aid) {
|
|
2053
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'missing aid' };
|
|
2054
|
+
}
|
|
2055
|
+
if (sessionId !== undefined && typeof sessionId !== 'string') {
|
|
2056
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'sessionId must be a string' };
|
|
2057
|
+
}
|
|
2058
|
+
if (delegationToken !== undefined && typeof delegationToken !== 'string') {
|
|
2059
|
+
return { ok: false, code: 'INVALID_DELEGATION', error: 'delegationToken must be a string' };
|
|
2060
|
+
}
|
|
2061
|
+
if (sessionId && !delegationToken)
|
|
2062
|
+
return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Managed skill refresh requires delegation' };
|
|
2063
|
+
try {
|
|
2064
|
+
if (!Array.isArray(cmd.argv))
|
|
2065
|
+
throw new Error('Skill refresh requires argv');
|
|
2066
|
+
aid = resolveSkillRefreshArgv(cmd.argv);
|
|
2067
|
+
}
|
|
2068
|
+
catch (error) {
|
|
2069
|
+
return { ok: false, code: 'INVALID_REQUEST', error: error instanceof Error ? error.message : String(error) };
|
|
2070
|
+
}
|
|
2071
|
+
return await this.skillRefreshExecutor(aid, sessionId, delegationToken, typeof cmd.delegationCommandHash === 'string' ? cmd.delegationCommandHash : undefined);
|
|
2072
|
+
}
|
|
2073
|
+
case 'trigger.op':
|
|
1867
2074
|
case 'trigger.list':
|
|
1868
2075
|
case 'trigger.show':
|
|
1869
2076
|
case 'trigger.history':
|
|
1870
2077
|
case 'trigger.eventCatalog':
|
|
1871
|
-
case 'trigger.authorizeLocalFiles':
|
|
1872
2078
|
case 'trigger.create':
|
|
1873
2079
|
case 'trigger.update':
|
|
1874
2080
|
case 'trigger.setEnabled':
|
|
@@ -1917,6 +2123,17 @@ export class IpcServer {
|
|
|
1917
2123
|
const aid = cmd.aid;
|
|
1918
2124
|
if (!aid || typeof aid !== 'string')
|
|
1919
2125
|
return { ok: false, error: 'missing aid' };
|
|
2126
|
+
if (cmd.argv !== undefined) {
|
|
2127
|
+
if (!Array.isArray(cmd.argv) || cmd.argv.some((value) => typeof value !== 'string')) {
|
|
2128
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'Invalid command argv' };
|
|
2129
|
+
}
|
|
2130
|
+
const argv = cmd.argv;
|
|
2131
|
+
const validFormat = argv.length === 3
|
|
2132
|
+
|| (argv.length === 5 && argv[3] === '--format' && argv[4] === 'json');
|
|
2133
|
+
if (argv[0] !== 'agent' || argv[1] !== 'ready' || argv[2] !== aid || !validFormat) {
|
|
2134
|
+
return { ok: false, code: 'INVALID_REQUEST', error: 'agent ready endpoint does not match argv' };
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
1920
2137
|
if (!this.bootstrapCompleteExecutor)
|
|
1921
2138
|
return { ok: false, error: 'bootstrap complete executor not configured' };
|
|
1922
2139
|
try {
|
|
@@ -2333,7 +2550,7 @@ export async function ipcQuery(socketPath, cmd, timeoutMs = 3000, options = {})
|
|
|
2333
2550
|
function ipcQueryOnce(socketPath, cmd, timeoutMs = 3000) {
|
|
2334
2551
|
let authenticatedCmd = cmd;
|
|
2335
2552
|
if (!process.env.EVOLCORE_SESSION_ID
|
|
2336
|
-
&& requiresLocalControlToken(cmd)
|
|
2553
|
+
&& (requiresLocalControlToken(cmd) || (MEMORY_COMMAND_ENDPOINTS.has(cmd.type) && cmd.debug === true))
|
|
2337
2554
|
&& typeof cmd.controlToken !== 'string') {
|
|
2338
2555
|
try {
|
|
2339
2556
|
const controlToken = fs.readFileSync(resolvePaths().controlToken, 'utf8').trim();
|
|
@@ -2345,7 +2562,7 @@ function ipcQueryOnce(socketPath, cmd, timeoutMs = 3000) {
|
|
|
2345
2562
|
const requestArgv = Array.isArray(authenticatedCmd.argv)
|
|
2346
2563
|
&& authenticatedCmd.argv.every((value) => typeof value === 'string')
|
|
2347
2564
|
? [
|
|
2348
|
-
|
|
2565
|
+
MAIN_CLI_BIN,
|
|
2349
2566
|
...(authenticatedCmd.type === 'menu-client.request' ? ['menu-client'] : []),
|
|
2350
2567
|
...authenticatedCmd.argv,
|
|
2351
2568
|
]
|
package/dist/paths.js
CHANGED
|
@@ -208,6 +208,26 @@ export function channelStatePath(channelKey, ...parts) {
|
|
|
208
208
|
export function agentTriggersDir(aid) {
|
|
209
209
|
return path.join(agentDir(aid), 'triggers');
|
|
210
210
|
}
|
|
211
|
+
/** 话题数据的统一根目录:索引、摘要、续读锚点、跨会话收件箱都收在这里。 */
|
|
212
|
+
export function agentThreadsDir(aid) {
|
|
213
|
+
return path.join(agentDataDir(aid), 'threads');
|
|
214
|
+
}
|
|
215
|
+
export function agentThreadIndexPath(aid) {
|
|
216
|
+
return path.join(agentThreadsDir(aid), 'index.json');
|
|
217
|
+
}
|
|
218
|
+
export function agentThreadSummariesDir(aid) {
|
|
219
|
+
return path.join(agentThreadsDir(aid), 'summaries');
|
|
220
|
+
}
|
|
221
|
+
export function agentThreadSummaryPath(aid, sessionId) {
|
|
222
|
+
return path.join(agentThreadSummariesDir(aid), `${sessionId}.summary.jsonl`);
|
|
223
|
+
}
|
|
224
|
+
/** Thread Context 收件箱:跨话题发送后在目标会话侧留下的注入提醒。 */
|
|
225
|
+
export function agentThreadInboxDir(aid) {
|
|
226
|
+
return path.join(agentThreadsDir(aid), 'inbox');
|
|
227
|
+
}
|
|
228
|
+
export function agentThreadInboxPath(aid, targetSessionId) {
|
|
229
|
+
return path.join(agentThreadInboxDir(aid), `${targetSessionId}.jsonl`);
|
|
230
|
+
}
|
|
211
231
|
function stripTrailingWindowsSeparators(value) {
|
|
212
232
|
const stripped = value.replace(/[\\/]+$/g, '');
|
|
213
233
|
// Keep a drive-root separator. `C:` is a drive-relative path on Windows.
|
|
@@ -414,6 +434,9 @@ export function kitsSchemasDir() {
|
|
|
414
434
|
export function eckDebugDir() {
|
|
415
435
|
return path.join(resolveRoot(), 'data', 'eck-debug');
|
|
416
436
|
}
|
|
437
|
+
export function debugSessionsDir() {
|
|
438
|
+
return path.join(resolveRoot(), 'data', 'debug-sessions');
|
|
439
|
+
}
|
|
417
440
|
export function getPackageRoot() {
|
|
418
441
|
// import.meta.dirname is available in Node.js 21.2+ and always returns
|
|
419
442
|
// the correct OS-native path, regardless of Git Bash or MSYS2 environment.
|