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
|
@@ -7,10 +7,11 @@ import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
|
7
7
|
import { readTaskRuntimeContextFromEnv } from './task-context.js';
|
|
8
8
|
import { assertEcSingleLine } from './cli-argv.js';
|
|
9
9
|
import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
|
|
10
|
+
import { MAIN_CLI_BIN } from '../product.js';
|
|
10
11
|
import { readTriggerLocalFile, resolveTriggerLocalPath } from '../trigger/local-files.js';
|
|
11
12
|
import { normalizeTriggerDefinition, resolveScriptPath, safeRelativePath, } from '../trigger/validation.js';
|
|
12
13
|
export async function cmdTrigger(args) {
|
|
13
|
-
args = canonicalizeEvolcoreCommandArgv([
|
|
14
|
+
args = canonicalizeEvolcoreCommandArgv([MAIN_CLI_BIN, 'trigger', ...args]).slice(2);
|
|
14
15
|
const sub = args[0];
|
|
15
16
|
if (sub === 'create' || sub === 'set' || sub === 'update') {
|
|
16
17
|
const nameIndex = args.indexOf('--name');
|
|
@@ -41,29 +42,27 @@ export async function cmdTrigger(args) {
|
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
throw new Error('daemon did not provide a valid Trigger file scope');
|
|
64
|
-
}
|
|
65
|
-
fileScope = authorization.fileScope;
|
|
45
|
+
if (process.env.EVOLCORE_SESSION_ID) {
|
|
46
|
+
const response = await request({ type: 'trigger.op', argv: ['trigger', ...args] }, sub === 'run' ? 120_000 : 30_000);
|
|
47
|
+
if (json)
|
|
48
|
+
return printJson(response);
|
|
49
|
+
if (sub === 'list')
|
|
50
|
+
return listTriggers(rest, false, response);
|
|
51
|
+
if (sub === 'show')
|
|
52
|
+
return showTrigger(rest, false, response);
|
|
53
|
+
if (sub === 'history')
|
|
54
|
+
return showHistory(rest, false, response);
|
|
55
|
+
if (sub === 'run') {
|
|
56
|
+
console.log(`${response.result.status}${response.result.reason ? ` (${response.result.reason})` : ''}: ${response.result.runId}`);
|
|
57
|
+
if (response.result.error)
|
|
58
|
+
console.log(response.result.error);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const verb = { create: 'created', set: 'created', update: 'updated', enable: 'enabled',
|
|
62
|
+
disable: 'disabled', cancel: 'disabled', delete: 'deleted', remove: 'deleted', rm: 'deleted' }[sub];
|
|
63
|
+
console.log(`✓ ${verb} ${response.trigger.id}${['create', 'set', 'update'].includes(sub) ? ` (${response.trigger.name})` : ''}`);
|
|
66
64
|
}
|
|
65
|
+
return;
|
|
67
66
|
}
|
|
68
67
|
switch (sub) {
|
|
69
68
|
case 'list':
|
|
@@ -77,10 +76,10 @@ export async function cmdTrigger(args) {
|
|
|
77
76
|
return;
|
|
78
77
|
case 'create':
|
|
79
78
|
case 'set':
|
|
80
|
-
await createTrigger(rest, json
|
|
79
|
+
await createTrigger(rest, json);
|
|
81
80
|
return;
|
|
82
81
|
case 'update':
|
|
83
|
-
await updateTrigger(rest, json
|
|
82
|
+
await updateTrigger(rest, json);
|
|
84
83
|
return;
|
|
85
84
|
case 'enable':
|
|
86
85
|
case 'disable':
|
|
@@ -113,7 +112,7 @@ function printHelp() {
|
|
|
113
112
|
console.log(`用法: ec trigger <subcommand>
|
|
114
113
|
|
|
115
114
|
命令:
|
|
116
|
-
list [--agent <aid>] [--all] [--json]
|
|
115
|
+
list [--agent <aid>] [--all] [--thread-id <threadId>] [--json]
|
|
117
116
|
show [--agent <aid>] <triggerId> [--json]
|
|
118
117
|
history [--agent <aid>] [triggerId] [--limit <n>] [--json]
|
|
119
118
|
create --exec <script|trigger-session|target-session> --file <trigger.json|trigger-dir> [--enable] [--json]
|
|
@@ -175,9 +174,10 @@ Update 参数:
|
|
|
175
174
|
省略 --agent 时使用当前 agent AID;无会话上下文或跨身份操作时需要显式指定。
|
|
176
175
|
任务会话中的跨身份操作仅允许目标 Agent 上具备 owner/admin 权限的调用者执行 list/show/history;创建、修改、启停、删除和运行仍只允许当前 Agent。`);
|
|
177
176
|
}
|
|
178
|
-
async function listTriggers(args, json) {
|
|
177
|
+
async function listTriggers(args, json, response) {
|
|
179
178
|
const agentAid = resolveAgentAid(args);
|
|
180
|
-
const
|
|
179
|
+
const threadId = flagValue(args, '--thread-id');
|
|
180
|
+
const res = response ?? await request({ type: 'trigger.list', agentAid, all: hasFlag(args, '--all'), ...(threadId ? { threadId } : {}) });
|
|
181
181
|
if (json)
|
|
182
182
|
return printJson(res);
|
|
183
183
|
const triggers = res.triggers;
|
|
@@ -189,10 +189,10 @@ async function listTriggers(args, json) {
|
|
|
189
189
|
console.log(`${t.enabled ? 'on ' : 'off'} ${t.id} ${t.name} ${sourceLabel(t)}`);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
async function showTrigger(args, json) {
|
|
192
|
+
async function showTrigger(args, json, response) {
|
|
193
193
|
const agentAid = resolveAgentAid(args);
|
|
194
194
|
const triggerId = positional(args, 0, ['--agent', '--format']);
|
|
195
|
-
const res = await request({ type: 'trigger.show', agentAid, triggerId });
|
|
195
|
+
const res = response ?? await request({ type: 'trigger.show', agentAid, triggerId });
|
|
196
196
|
if (json)
|
|
197
197
|
return printJson(res);
|
|
198
198
|
const t = res.definition;
|
|
@@ -239,7 +239,7 @@ async function showTrigger(args, json) {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
|
-
async function showHistory(args, json) {
|
|
242
|
+
async function showHistory(args, json, response) {
|
|
243
243
|
const agentAid = resolveAgentAid(args);
|
|
244
244
|
const triggerId = optionalPositional(args, 0, ['--agent', '--limit', '--format']);
|
|
245
245
|
const rawLimit = flagValue(args, '--limit');
|
|
@@ -247,7 +247,7 @@ async function showHistory(args, json) {
|
|
|
247
247
|
if (!Number.isInteger(limit) || limit <= 0 || limit > 10_000) {
|
|
248
248
|
throw new Error('--limit 必须是 1 到 10000 的整数');
|
|
249
249
|
}
|
|
250
|
-
const res = await request({ type: 'trigger.history', agentAid, triggerId, limit });
|
|
250
|
+
const res = response ?? await request({ type: 'trigger.history', agentAid, triggerId, limit });
|
|
251
251
|
if (json)
|
|
252
252
|
return printJson(res);
|
|
253
253
|
const events = Array.isArray(res.events) ? res.events : [];
|
|
@@ -266,6 +266,12 @@ async function showHistory(args, json) {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
async function createTrigger(args, json, fileScope) {
|
|
269
|
+
const res = await request(await buildTriggerCreateRequest(args, fileScope), 30_000);
|
|
270
|
+
if (json)
|
|
271
|
+
return printJson(res);
|
|
272
|
+
console.log(`✓ created ${res.trigger.id} (${res.trigger.name})`);
|
|
273
|
+
}
|
|
274
|
+
export async function buildTriggerCreateRequest(args, fileScope, defaultAgentAid) {
|
|
269
275
|
if (!hasOption(args, '--exec')) {
|
|
270
276
|
throw new Error('创建 trigger 必须显式指定 --exec script|trigger-session|target-session');
|
|
271
277
|
}
|
|
@@ -280,16 +286,12 @@ async function createTrigger(args, json, fileScope) {
|
|
|
280
286
|
if (definition.execution.type !== executionType) {
|
|
281
287
|
throw new Error(`--exec ${flagValue(args, '--exec')} 与 trigger.json 的 execution.type=${definition.execution.type} 不一致`);
|
|
282
288
|
}
|
|
283
|
-
|
|
289
|
+
return {
|
|
284
290
|
type: 'trigger.create',
|
|
285
291
|
definition,
|
|
286
292
|
files,
|
|
287
293
|
enable: hasFlag(args, '--enable') ? true : undefined,
|
|
288
|
-
}
|
|
289
|
-
if (json)
|
|
290
|
-
return printJson(res);
|
|
291
|
-
console.log(`✓ created ${res.trigger.id} (${res.trigger.name})`);
|
|
292
|
-
return;
|
|
294
|
+
};
|
|
293
295
|
}
|
|
294
296
|
// Flag mode: use parser
|
|
295
297
|
const usesPromptFile = hasOption(args, '--prompt-file');
|
|
@@ -302,7 +304,7 @@ async function createTrigger(args, json, fileScope) {
|
|
|
302
304
|
throw new Error(parseResult.error);
|
|
303
305
|
}
|
|
304
306
|
const parsed = parseResult.value;
|
|
305
|
-
const agentAid = parsed.agentId ?? resolveAgentAid(args);
|
|
307
|
+
const agentAid = parsed.agentId ?? defaultAgentAid ?? resolveAgentAid(args);
|
|
306
308
|
const eventSession = parsed.feedbackStrategy === 'event_session';
|
|
307
309
|
if (parsed.feedbackStrategy !== 'target' && !eventSession) {
|
|
308
310
|
throw new Error('CLI flag 模式仅支持 --feedback target;origin/silent 请使用 /trigger 或 --file 导入 Trigger V3 第二阶段 JSON');
|
|
@@ -332,6 +334,7 @@ async function createTrigger(args, json, fileScope) {
|
|
|
332
334
|
enabled: hasFlag(args, '--enable'),
|
|
333
335
|
createdAt: now,
|
|
334
336
|
updatedAt: now,
|
|
337
|
+
...(parsed.labels ? { labels: parsed.labels } : {}),
|
|
335
338
|
source: sourceFromParsed(parsed),
|
|
336
339
|
execution: {
|
|
337
340
|
type: parsed.executionType,
|
|
@@ -364,15 +367,12 @@ async function createTrigger(args, json, fileScope) {
|
|
|
364
367
|
relativePath: script.path.replace(/\\/g, '/'),
|
|
365
368
|
contentBase64: readTriggerLocalFile(parsed.scriptPath, fileScope).toString('base64'),
|
|
366
369
|
}] : [];
|
|
367
|
-
|
|
370
|
+
return {
|
|
368
371
|
type: 'trigger.create',
|
|
369
372
|
definition,
|
|
370
373
|
files,
|
|
371
374
|
enable: hasFlag(args, '--enable') ? true : undefined,
|
|
372
|
-
}
|
|
373
|
-
if (json)
|
|
374
|
-
return printJson(res);
|
|
375
|
-
console.log(`✓ created ${res.trigger.id} (${res.trigger.name})`);
|
|
375
|
+
};
|
|
376
376
|
}
|
|
377
377
|
function triggerCreateArgs(args) {
|
|
378
378
|
const out = [];
|
|
@@ -453,7 +453,13 @@ function shellQuoteArg(value) {
|
|
|
453
453
|
return /[\s"'\\]/.test(value) ? `"${value.replace(/(["\\$`])/g, '\\$1')}"` : value;
|
|
454
454
|
}
|
|
455
455
|
async function updateTrigger(args, json, fileScope) {
|
|
456
|
-
const
|
|
456
|
+
const res = await request(await buildTriggerUpdateRequest(args, fileScope), 30_000);
|
|
457
|
+
if (json)
|
|
458
|
+
return printJson(res);
|
|
459
|
+
console.log(`✓ updated ${res.trigger.id} (${res.trigger.name})`);
|
|
460
|
+
}
|
|
461
|
+
export async function buildTriggerUpdateRequest(args, fileScope, defaultAgentAid) {
|
|
462
|
+
const agentAid = flagValue(args, '--agent') ?? defaultAgentAid ?? resolveAgentAid(args);
|
|
457
463
|
const triggerId = positional(args, 0, ['--agent', '--format', '--if-revision', '--prompt-file', '--script-file']);
|
|
458
464
|
const usesPromptFile = hasOption(args, '--prompt-file');
|
|
459
465
|
const usesScriptFile = hasOption(args, '--script-file');
|
|
@@ -469,7 +475,7 @@ async function updateTrigger(args, json, fileScope) {
|
|
|
469
475
|
const scriptFileBase64 = scriptFilePath
|
|
470
476
|
? readTriggerLocalFile(scriptFilePath, fileScope).toString('base64')
|
|
471
477
|
: undefined;
|
|
472
|
-
|
|
478
|
+
return {
|
|
473
479
|
type: 'trigger.update',
|
|
474
480
|
agentAid,
|
|
475
481
|
triggerId,
|
|
@@ -477,10 +483,30 @@ async function updateTrigger(args, json, fileScope) {
|
|
|
477
483
|
...(usesPromptFile ? { promptFile: true } : {}),
|
|
478
484
|
...(scriptFileBase64 !== undefined ? { scriptFileBase64 } : {}),
|
|
479
485
|
...(expectedRevision ? { expectedRevision } : {}),
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
export function resolveTriggerCommandArgv(argv, defaultAgentAid) {
|
|
489
|
+
if (argv[0] !== 'trigger')
|
|
490
|
+
throw new Error('Expected a trigger command');
|
|
491
|
+
const sub = argv[1];
|
|
492
|
+
const args = argv.slice(2);
|
|
493
|
+
const types = {
|
|
494
|
+
list: 'trigger.list', show: 'trigger.show', history: 'trigger.history', create: 'trigger.create',
|
|
495
|
+
set: 'trigger.create', update: 'trigger.update', enable: 'trigger.setEnabled', disable: 'trigger.setEnabled',
|
|
496
|
+
cancel: 'trigger.cancel', delete: 'trigger.delete', remove: 'trigger.delete', rm: 'trigger.delete', run: 'trigger.run',
|
|
497
|
+
};
|
|
498
|
+
if (!types[sub])
|
|
499
|
+
throw new Error(`Unknown trigger command: ${sub}`);
|
|
500
|
+
const agentAid = flagValue(args, '--agent') ?? defaultAgentAid;
|
|
501
|
+
const valueFlags = ['--agent', '--format', '--limit', '--if-revision', '--prompt-file', '--script-file'];
|
|
502
|
+
const triggerId = ['list', 'create', 'set'].includes(sub) ? undefined : optionalPositional(args, 0, valueFlags);
|
|
503
|
+
if (!['list', 'history', 'create', 'set'].includes(sub) && !triggerId)
|
|
504
|
+
throw new Error('missing triggerId');
|
|
505
|
+
const limit = Number(flagValue(args, '--limit') ?? 100);
|
|
506
|
+
if (!Number.isInteger(limit) || limit <= 0 || limit > 10_000)
|
|
507
|
+
throw new Error('Invalid history limit');
|
|
508
|
+
return { type: types[sub], agentAid, triggerId, limit, all: hasFlag(args, '--all'),
|
|
509
|
+
enabled: sub === 'enable', dryRun: hasFlag(args, '--dry-run') };
|
|
484
510
|
}
|
|
485
511
|
function triggerUpdateArgs(args) {
|
|
486
512
|
const out = [];
|
|
@@ -42,6 +42,7 @@ export function getManagementCommandPermissions(role) {
|
|
|
42
42
|
'role.policy.read': { allow: true, scopes: ['agent'] },
|
|
43
43
|
'role.relation.read': { allow: true, scopes: ['agent'] },
|
|
44
44
|
'agent.baseagent.update': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
|
|
45
|
+
'agent.rename': { allow: true, dangerous: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
|
|
45
46
|
'observable.current': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true } },
|
|
46
47
|
'observable.update': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
|
|
47
48
|
'file.root.agent': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
|
|
@@ -64,17 +65,18 @@ export function getManagementCommandPermissions(role) {
|
|
|
64
65
|
'ec.aid.agentmd.put': { allow: true, dangerous: true, scopes: ['agent'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
|
|
65
66
|
'ec.aid.agentmd.set': { allow: true, dangerous: true, scopes: ['agent'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
|
|
66
67
|
'ec.aid.avatar': { allow: true, dangerous: true, scopes: ['agent'], constraints: { targetCurrentAgentOnly: true, requireAgentOwner: true } },
|
|
67
|
-
'ec.fs.mkdir': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
68
|
-
'ec.fs.upload': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
69
|
-
'ec.fs.copy': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
70
|
-
'ec.fs.move': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
71
|
-
'ec.fs.remove': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
72
|
-
'ec.fs.getfacl': { allow: true, scopes: ['relation'
|
|
73
|
-
'ec.fs.setfacl': { allow: true, permissionMode: 'auto', scopes: ['relation'
|
|
68
|
+
'ec.fs.mkdir': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
69
|
+
'ec.fs.upload': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
70
|
+
'ec.fs.copy': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
71
|
+
'ec.fs.move': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
72
|
+
'ec.fs.remove': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
73
|
+
'ec.fs.getfacl': { allow: true, scopes: ['relation', 'agent'] },
|
|
74
|
+
'ec.fs.setfacl': { allow: true, permissionMode: 'auto', scopes: ['relation', 'agent'] },
|
|
74
75
|
'*': { allow: true },
|
|
75
76
|
// Reload is valid from an Agent's own channel and the daemon control plane.
|
|
76
77
|
// The control-channel gate still requires a daemon owner for cross-Agent reloads.
|
|
77
78
|
'agent.reload': { allow: true, dangerous: true, scopes: ['agent', 'control'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
|
|
79
|
+
'skill.refresh': { allow: true, scopes: ['agent', 'control'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
|
|
78
80
|
'dangerous:*': { allow: true, dangerous: true, constraints: { requireDaemonOwner: true } },
|
|
79
81
|
};
|
|
80
82
|
}
|
|
@@ -3,7 +3,6 @@ const BEHAVIOR_TOP_FIELDS = new Set([
|
|
|
3
3
|
'chatmode',
|
|
4
4
|
'mentionMode',
|
|
5
5
|
'autoMentionQuietWindowMs',
|
|
6
|
-
'sessionIdleSec',
|
|
7
6
|
'groupSlashRequireMentions',
|
|
8
7
|
'responseMode',
|
|
9
8
|
'responseModeParams',
|
|
@@ -128,8 +127,6 @@ export function resolveConfigFieldRule(fieldPath, scope) {
|
|
|
128
127
|
return scalar(field, 'mention-mode');
|
|
129
128
|
if (field === 'autoMentionQuietWindowMs')
|
|
130
129
|
return scalar(field, 'nonnegative-number');
|
|
131
|
-
if (field === 'sessionIdleSec')
|
|
132
|
-
return scalar(field, 'finite-number');
|
|
133
130
|
if (field === 'groupSlashRequireMentions')
|
|
134
131
|
return scalar(field, 'boolean');
|
|
135
132
|
if (field === 'show_activities')
|
|
@@ -142,6 +139,8 @@ export function resolveConfigFieldRule(fieldPath, scope) {
|
|
|
142
139
|
return scalar('configSnapshots', 'boolean');
|
|
143
140
|
if (field === 'restartRecovery.enabled')
|
|
144
141
|
return scalar('restartRecovery.enabled', 'boolean');
|
|
142
|
+
if (field === 'skills.watch')
|
|
143
|
+
return scalar('skills.watch', 'boolean');
|
|
145
144
|
if (top === 'chatmode') {
|
|
146
145
|
if (parts.length === 1)
|
|
147
146
|
return readonlyObject('chatmode');
|
|
@@ -1464,6 +1464,9 @@ export function routeField(topField, scope) {
|
|
|
1464
1464
|
*/
|
|
1465
1465
|
export function routeFieldPath(fieldPath, scope) {
|
|
1466
1466
|
const topField = fieldPath.split('.')[0];
|
|
1467
|
+
if (topField === 'sessionLoop') {
|
|
1468
|
+
throw new ConfigError('SESSION_LOOP_MANAGED', 'sessionLoop is managed through the dedicated /loop or session Menu entry');
|
|
1469
|
+
}
|
|
1467
1470
|
if (scope === 'process')
|
|
1468
1471
|
return routeIn(DAEMON_SCHEMA_NAME, ConfigTarget.Process, topField);
|
|
1469
1472
|
if (scope === 'defaults') {
|
|
@@ -1541,8 +1544,10 @@ export function listFields(scope) {
|
|
|
1541
1544
|
const out = [];
|
|
1542
1545
|
const add = (name, target) => {
|
|
1543
1546
|
const s = loadSchema(name);
|
|
1544
|
-
for (const f of s.fields.keys())
|
|
1545
|
-
|
|
1547
|
+
for (const f of s.fields.keys()) {
|
|
1548
|
+
if (f !== 'sessionLoop')
|
|
1549
|
+
out.push(mkRoute(s, target, f));
|
|
1550
|
+
}
|
|
1546
1551
|
};
|
|
1547
1552
|
if (scope === 'process') {
|
|
1548
1553
|
add(DAEMON_SCHEMA_NAME, ConfigTarget.Process);
|
|
@@ -90,6 +90,9 @@ function resolveFieldCommand(argv, subcommand, options = {}) {
|
|
|
90
90
|
const field = business.values[0].trim();
|
|
91
91
|
if (!field)
|
|
92
92
|
return { ok: false, code: 'MISSING_ARG', reason: `config ${subcommand} requires a field` };
|
|
93
|
+
if (field === 'sessionLoop' || field.startsWith('sessionLoop.')) {
|
|
94
|
+
return { ok: false, code: 'SESSION_LOOP_MANAGED', reason: 'sessionLoop is managed through the dedicated /loop or session Menu entry' };
|
|
95
|
+
}
|
|
93
96
|
if (field === 'permissionMode') {
|
|
94
97
|
return {
|
|
95
98
|
ok: false,
|
package/dist/config-store.js
CHANGED
|
@@ -60,6 +60,9 @@ export function loadDaemonConfig() {
|
|
|
60
60
|
export function isRestartRecoveryEnabled(config = loadDaemonConfig()) {
|
|
61
61
|
return config.restartRecovery?.enabled === true;
|
|
62
62
|
}
|
|
63
|
+
export function isSkillWatchEnabled(config = loadDaemonConfig()) {
|
|
64
|
+
return config.skills?.watch === true;
|
|
65
|
+
}
|
|
63
66
|
let eckSnapshotsConfigCache;
|
|
64
67
|
/** Parse the process-level snapshot gate once for the current daemon lifecycle. */
|
|
65
68
|
export function initializeEckSnapshotsConfig(config = loadDaemonConfig()) {
|
|
@@ -103,6 +106,18 @@ function validateDaemonConfig(value, validateAidDomain) {
|
|
|
103
106
|
throw new Error('daemon.json.restartRecovery.enabled must be a boolean');
|
|
104
107
|
}
|
|
105
108
|
}
|
|
109
|
+
if (value.skills !== undefined) {
|
|
110
|
+
if (!value.skills || typeof value.skills !== 'object' || Array.isArray(value.skills)) {
|
|
111
|
+
throw new Error('daemon.json.skills must be an object');
|
|
112
|
+
}
|
|
113
|
+
const unknownSkillsFields = Object.keys(value.skills).filter(key => key !== 'watch');
|
|
114
|
+
if (unknownSkillsFields.length > 0) {
|
|
115
|
+
throw new Error('daemon.json.skills contains unsupported fields: ' + unknownSkillsFields.join(', '));
|
|
116
|
+
}
|
|
117
|
+
if (value.skills.watch !== undefined && typeof value.skills.watch !== 'boolean') {
|
|
118
|
+
throw new Error('daemon.json.skills.watch must be a boolean');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
106
121
|
const minEvolVersion = value.aun?.minEvolVersion;
|
|
107
122
|
if (minEvolVersion !== undefined && !parseStableSemver(minEvolVersion)) {
|
|
108
123
|
throw new Error('daemon.json.aun.minEvolVersion must use stable X.Y.Z format');
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { loadDaemonConfig } from '../config-store.js';
|
|
4
|
-
import { parseAgentWelcomeArgs, parseInitializationArgs, resolveInitializationPlan, } from '../cli/agent-create.js';
|
|
4
|
+
import { parseAgentWelcomeArgs, parseInitializationArgs, resolveInitializationPlan, readInitializationPersona, } from '../cli/agent-create.js';
|
|
5
5
|
import { trustedExecutionIdentityInput } from './auth/agent-delegation.js';
|
|
6
6
|
import { authorizeOperation, buildAuthSubject } from './auth/auth-gateway.js';
|
|
7
7
|
import { authorizationDenialData } from './auth/authorization-denial.js';
|
|
8
8
|
import { parsePeerKey } from './relation/peer-identity.js';
|
|
9
9
|
import { isHClassPath, isLClassPath, isSameOrDescendant } from './permission/protected-paths.js';
|
|
10
|
-
|
|
10
|
+
import { isValidAid } from '../aun/aid/validation.js';
|
|
11
|
+
export function registerAgentOperationExecutor({ ipcServer, sessionManager, agentDelegationRegistry, eventBus, responseEngine, handoffRuntime, agentApplicationService, agentInitializationService, executeConfigOperation, }) {
|
|
11
12
|
ipcServer.setAgentOperationExecutor(async (argv, sessionId, delegationToken, delegationCommandHash) => {
|
|
12
13
|
const fail = (code, error, reasonCode) => ({
|
|
13
14
|
ok: false,
|
|
@@ -17,9 +18,16 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
17
18
|
});
|
|
18
19
|
if (!Array.isArray(argv) || argv[0] !== 'agent')
|
|
19
20
|
return fail('INVALID_REQUEST', 'agent.op requires an agent command');
|
|
20
|
-
const
|
|
21
|
+
const shorthand = !!argv[1] && isValidAid(argv[1]);
|
|
22
|
+
const sub = shorthand ? 'show' : argv[1];
|
|
21
23
|
if (!sub)
|
|
22
24
|
return fail('INVALID_ARGS', 'missing agent subcommand');
|
|
25
|
+
if (sub === 'get' || sub === 'set') {
|
|
26
|
+
const result = await executeConfigOperation(argv, sessionId, delegationToken, delegationCommandHash);
|
|
27
|
+
return result.ok
|
|
28
|
+
? { ok: true, result: result.result }
|
|
29
|
+
: { ok: false, code: result.code ?? 'CONFIG_OPERATION_FAILED', error: result.error ?? 'config operation failed' };
|
|
30
|
+
}
|
|
23
31
|
const value = (flag) => {
|
|
24
32
|
const index = argv.indexOf(flag);
|
|
25
33
|
return index >= 0 && index + 1 < argv.length && !argv[index + 1].startsWith('--') ? argv[index + 1] : undefined;
|
|
@@ -31,6 +39,8 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
31
39
|
if (!taskSession || taskSession.selfAID !== delegation.grant.selfAid) {
|
|
32
40
|
return fail('INVALID_DELEGATION', 'delegation does not match the current session');
|
|
33
41
|
}
|
|
42
|
+
if (shorthand)
|
|
43
|
+
argv = ['agent', 'show', ...argv.slice(1)];
|
|
34
44
|
const taskAid = delegation.grant.selfAid;
|
|
35
45
|
let welcomeArgs;
|
|
36
46
|
if (sub === 'welcome') {
|
|
@@ -58,12 +68,13 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
58
68
|
: sub === 'show' ? 'agent.show'
|
|
59
69
|
: sub === 'persona' ? 'agent.persona'
|
|
60
70
|
: sub === 'welcome' ? 'agent.welcome'
|
|
61
|
-
: sub === '
|
|
62
|
-
: sub === 'new' ? 'agent.
|
|
63
|
-
: sub === '
|
|
64
|
-
: sub === '
|
|
65
|
-
: sub === '
|
|
66
|
-
: sub === '
|
|
71
|
+
: sub === 'rename' ? 'agent.rename'
|
|
72
|
+
: sub === 'initialize' || (sub === 'new' && argv.includes('--initialize')) ? 'agent.initialize'
|
|
73
|
+
: sub === 'new' ? 'agent.create'
|
|
74
|
+
: sub === 'enable' ? 'agent.enable'
|
|
75
|
+
: sub === 'disable' ? 'agent.disable'
|
|
76
|
+
: sub === 'reload' ? 'agent.reload'
|
|
77
|
+
: sub === 'delete' ? 'agent.delete' : undefined;
|
|
67
78
|
if (!operation)
|
|
68
79
|
return fail('INVALID_ARGS', `unsupported managed agent command: ${sub}`);
|
|
69
80
|
if (sub === 'new' && !argv.includes('--non-interactive') && !argv.includes('--initialize')) {
|
|
@@ -95,7 +106,7 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
95
106
|
subject,
|
|
96
107
|
intent: {
|
|
97
108
|
operation,
|
|
98
|
-
scope: operation === 'agent.show' || operation === 'agent.persona' || operation === 'agent.welcome'
|
|
109
|
+
scope: operation === 'agent.show' || operation === 'agent.persona' || operation === 'agent.welcome' || operation === 'agent.rename'
|
|
99
110
|
? 'agent'
|
|
100
111
|
: operation === 'agent.reload' && targetAid
|
|
101
112
|
? 'agent'
|
|
@@ -170,15 +181,23 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
170
181
|
if (!hasFormatSuffix && rawPersonaArgs.includes('--format')) {
|
|
171
182
|
return fail('INVALID_ARGS', 'persona 仅支持末尾的 --format json');
|
|
172
183
|
}
|
|
173
|
-
if (personaArgs.length === 2 && personaArgs[0] === '--file') {
|
|
174
|
-
return fail('INVALID_ARGS', '托管 persona --file 必须由 CLI 读取后作为文本提交');
|
|
175
|
-
}
|
|
176
184
|
const wantsShow = personaArgs.length === 1 && personaArgs[0] === 'show';
|
|
177
|
-
|
|
185
|
+
let text = personaArgs.length === 2 && personaArgs[0] === '--text'
|
|
178
186
|
? personaArgs[1]
|
|
179
187
|
: undefined;
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
const file = personaArgs.length === 2 && personaArgs[0] === '--file' ? personaArgs[1] : undefined;
|
|
189
|
+
if (file !== undefined) {
|
|
190
|
+
try {
|
|
191
|
+
text = readInitializationPersona(file, true, {
|
|
192
|
+
projectCwd: taskSession.projectPath, tempDir: delegation.grant.sessionRuntimeDir,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
return fail('INVALID_ARGS', error.message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!wantsShow && !(personaArgs.length === 2 && (personaArgs[0] === '--text' || personaArgs[0] === '--file'))) {
|
|
200
|
+
return fail('INVALID_ARGS', '用法: ec agent persona show | --text <text> | --file <path>');
|
|
182
201
|
}
|
|
183
202
|
if (text === undefined && !wantsShow)
|
|
184
203
|
return fail('INVALID_ARGS', 'persona --text 缺少参数');
|
|
@@ -211,12 +230,32 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
211
230
|
...(result.sha256 ? { sha256: result.sha256 } : {}),
|
|
212
231
|
} };
|
|
213
232
|
}
|
|
233
|
+
if (operation === 'agent.rename') {
|
|
234
|
+
const rawRenameArgs = argv.slice(2);
|
|
235
|
+
const hasFormatSuffix = rawRenameArgs.length >= 2
|
|
236
|
+
&& rawRenameArgs.at(-2) === '--format'
|
|
237
|
+
&& rawRenameArgs.at(-1) === 'json';
|
|
238
|
+
const renameArgs = hasFormatSuffix ? rawRenameArgs.slice(0, -2) : rawRenameArgs;
|
|
239
|
+
if (!hasFormatSuffix && rawRenameArgs.includes('--format')) {
|
|
240
|
+
return fail('INVALID_ARGS', 'rename 仅支持末尾的 --format json');
|
|
241
|
+
}
|
|
242
|
+
if (renameArgs.length !== 2 || !renameArgs[0] || !renameArgs[1]) {
|
|
243
|
+
return fail('INVALID_ARGS', '用法: ec agent rename <aid> <name>');
|
|
244
|
+
}
|
|
245
|
+
if (/[\x00-\x1f\x7f]/u.test(renameArgs[1])) {
|
|
246
|
+
return fail('INVALID_ARGS', 'name 不允许换行或控制字符');
|
|
247
|
+
}
|
|
248
|
+
const result = await execAgentAction('update', { aid: targetAid ?? taskAid, patch: { name: renameArgs[1] } }, delegation.grant.actorId, eventBus, agentApplicationService, subject);
|
|
249
|
+
return 'error' in result ? fail(result.code, result.error) : { ok: true, result: { ok: true, ...(result.data ?? {}) } };
|
|
250
|
+
}
|
|
214
251
|
if (operation === 'agent.initialize') {
|
|
215
252
|
try {
|
|
216
253
|
const parsed = parseInitializationArgs(argv.slice(1));
|
|
217
254
|
const actor = delegation.grant.actorId;
|
|
218
|
-
if (parsed.resume)
|
|
219
|
-
|
|
255
|
+
if (parsed.resume) {
|
|
256
|
+
agentInitializationService.resume(parsed.aid, actor);
|
|
257
|
+
return { ok: true, result: await agentInitializationService.wait(parsed.aid, parsed.wait) };
|
|
258
|
+
}
|
|
220
259
|
const createPermission = authorizeOperation({
|
|
221
260
|
source: 'agent-tool', subject,
|
|
222
261
|
intent: { operation: 'agent.create', scope: 'control', source: 'agent-tool', args: { aid: parsed.aid } },
|
|
@@ -226,14 +265,16 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
226
265
|
return fail(createPermission.code, createPermission.reason);
|
|
227
266
|
if (!argv.includes('--owner') && !argv.includes('--owners'))
|
|
228
267
|
return fail('INITIALIZE_OWNER_MISMATCH', 'Explicit Owner required');
|
|
229
|
-
const plan = resolveInitializationPlan(argv.slice(1)
|
|
268
|
+
const plan = resolveInitializationPlan(argv.slice(1), {
|
|
269
|
+
projectCwd: taskSession.projectPath, tempDir: delegation.grant.sessionRuntimeDir,
|
|
270
|
+
});
|
|
230
271
|
if (plan.avatarFile?.startsWith('attachment:')) {
|
|
231
272
|
const { readRelationAttachment } = await import('../utils/media-cache.js');
|
|
232
273
|
plan.avatarFile = readRelationAttachment(taskAid, delegation.grant.peerKey, plan.avatarFile.slice('attachment:'.length)).attachment.filePath;
|
|
233
274
|
}
|
|
234
275
|
else if (plan.avatarFile) {
|
|
235
276
|
const session = await sessionManager.getSessionById(sessionId);
|
|
236
|
-
const candidate = path.resolve(plan.avatarFile);
|
|
277
|
+
const candidate = path.resolve(taskSession.projectPath, plan.avatarFile);
|
|
237
278
|
const roots = [session?.projectPath, delegation.grant.sessionRuntimeDir]
|
|
238
279
|
.filter((root) => !!root && path.isAbsolute(root))
|
|
239
280
|
.map(root => fs.realpathSync(root));
|
|
@@ -245,7 +286,8 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
245
286
|
}
|
|
246
287
|
if (!plan.owners.includes(actor))
|
|
247
288
|
return fail('INITIALIZE_OWNER_MISMATCH', 'The authenticated requesting Owner must be retained');
|
|
248
|
-
|
|
289
|
+
const result = agentInitializationService.start(plan, actor, parsed.dryRun);
|
|
290
|
+
return { ok: true, result: parsed.dryRun ? result : await agentInitializationService.wait(parsed.aid, parsed.wait) };
|
|
249
291
|
}
|
|
250
292
|
catch (error) {
|
|
251
293
|
return fail(error.code ?? 'INVALID_ARGS', error.message);
|
|
@@ -283,7 +325,7 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
283
325
|
avatarFile: value('--avatar-file'),
|
|
284
326
|
avatarUrl: value('--avatar-url'),
|
|
285
327
|
force: argv.includes('--force'),
|
|
286
|
-
});
|
|
328
|
+
}, taskSession.projectPath);
|
|
287
329
|
const validationError = validateAgentCreatePlan(plan);
|
|
288
330
|
if (validationError)
|
|
289
331
|
return fail('INVALID_ARGS', validationError);
|
|
@@ -319,6 +361,7 @@ export function registerAgentOperationExecutor({ ipcServer, sessionManager, agen
|
|
|
319
361
|
channelType: delegation.grant.channelType,
|
|
320
362
|
chatType: delegation.grant.chatType,
|
|
321
363
|
peerKey: delegation.grant.peerKey,
|
|
364
|
+
approvalInteractionPolicy: delegation.grant.approvalInteractionPolicy,
|
|
322
365
|
},
|
|
323
366
|
causation: responseEngine.getTaskRuntimeContext(sessionId)?.causation,
|
|
324
367
|
});
|