evolcore 0.0.28 → 0.0.29
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 +12 -0
- package/bin/ec-safe-output.js +270 -54
- package/dist/agents/baseagent-availability.js +37 -1
- package/dist/agents/baseagent.js +19 -9
- package/dist/agents/claude-runner.js +171 -13
- package/dist/agents/codex/app-server-client.js +6 -2
- package/dist/agents/codex/diagnostics.js +4 -3
- package/dist/agents/codex-runner.js +396 -95
- package/dist/agents/gemini-runner.js +35 -17
- package/dist/aun/group/history.js +130 -90
- package/dist/aun/group/operations.js +1 -3
- package/dist/aun/menu/transport.js +5 -3
- package/dist/aun/msg/managed-operation.js +70 -0
- package/dist/aun/msg/p2p.js +1 -3
- package/dist/aun/msg/upload.js +2 -2
- package/dist/aun/outbox.js +1 -37
- package/dist/channels/aun.js +249 -89
- package/dist/channels/daemon.js +18 -1
- package/dist/channels/feishu.js +1 -2
- package/dist/cli/agent-command.js +23 -3
- package/dist/cli/agent-create.js +68 -2
- package/dist/cli/agent.js +12 -2
- package/dist/cli/aun-commands.js +87 -13
- package/dist/cli/cli-argv.js +26 -0
- package/dist/cli/daemon-commands.js +40 -10
- package/dist/cli/data-command.js +4 -4
- package/dist/cli/handoff-command.js +2 -0
- package/dist/cli/index.js +18 -1
- package/dist/cli/managed-command-guard.js +10 -0
- package/dist/cli/memory-command.js +441 -0
- package/dist/cli/restart-monitor.js +62 -6
- package/dist/cli/skill-command.js +41 -0
- package/dist/cli/task-context.js +2 -23
- package/dist/cli/trigger-command.js +9 -1
- package/dist/cli/watch-msg-diag.js +209 -0
- package/dist/config/config-field-policy.js +52 -3
- package/dist/config/config-manager.js +17 -4
- package/dist/config/contact-book-store.js +2 -2
- package/dist/config/mention-mode.js +7 -2
- package/dist/config/merge.js +28 -9
- package/dist/config/resolved-config-op.js +1 -1
- package/dist/config/runtime-env.js +137 -0
- package/dist/config/schema-registry.js +11 -1
- package/dist/config-store.js +10 -10
- package/dist/core/audit/event-key.js +3 -1
- package/dist/core/audit/log-integrity.js +4 -0
- package/dist/core/auth/agent-delegation.js +2 -1
- package/dist/core/auth/auth-gateway.js +13 -6
- package/dist/core/auth/authorization-audit.js +54 -19
- package/dist/core/auth/operation-authorizer.js +17 -0
- package/dist/core/auth/operation-catalog.js +9 -0
- package/dist/core/causation/context.js +5 -1
- package/dist/core/command/agent-control.js +1 -2
- package/dist/core/command/command-handler.js +51 -23
- package/dist/core/command/memory-slash.js +270 -0
- package/dist/core/command/menu-catalog.js +1 -0
- package/dist/core/command/menu-handler.js +315 -60
- package/dist/core/command/menu-protocol.js +42 -4
- package/dist/core/command/slash-gate.js +10 -10
- package/dist/core/command/slash-handler.js +206 -64
- package/dist/core/data-migration.js +282 -505
- package/dist/core/event-catalog.js +26 -0
- package/dist/core/evolagent-registry.js +6 -0
- package/dist/core/evolagent.js +0 -10
- package/dist/core/handoff/store.js +1 -20
- package/dist/core/inference/text-inference.js +57 -1
- package/dist/core/memory/consolidation-context.js +505 -0
- package/dist/core/memory/consolidation-ops-records.js +124 -0
- package/dist/core/memory/consolidation-trigger.js +394 -0
- package/dist/core/memory/index-manager.js +308 -0
- package/dist/core/memory/launch-consolidation.js +395 -0
- package/dist/core/memory/memory-admin.js +234 -0
- package/dist/core/memory/memory-document.js +100 -0
- package/dist/core/memory/memory-session-policy.js +41 -0
- package/dist/core/memory/memory-signature.js +257 -0
- package/dist/core/memory/memory-writer.js +432 -0
- package/dist/core/memory/staleness.js +117 -0
- package/dist/core/message/auto-mention-gate.js +454 -0
- package/dist/core/message/im-renderer.js +69 -16
- package/dist/core/message/message-bridge.js +287 -21
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +114 -27
- package/dist/core/message/pending-hints.js +329 -161
- package/dist/core/message/response-engine.js +567 -80
- package/dist/core/permission/ec-command-parser.js +1029 -80
- package/dist/core/permission/protected-paths.js +376 -126
- package/dist/core/permission/sandbox-runtime.js +40 -12
- package/dist/core/permission/tool-error-code.js +96 -13
- package/dist/core/permission/tool-policy.js +276 -23
- package/dist/core/role/runtime-policy.js +3 -7
- package/dist/core/session/{runner-task-history.js → runner-event-summary.js} +1 -1
- package/dist/core/session/session-fs-store.js +0 -76
- package/dist/core/session/session-idle-monitor.js +355 -0
- package/dist/core/session/session-manager.js +478 -17
- package/dist/core/session/session-mapper.js +33 -16
- package/dist/core/session/session-renew.js +217 -155
- package/dist/core/session/{session-turns.js → session-transcript.js} +35 -6
- package/dist/core/skill/global-watcher.js +282 -0
- package/dist/core/skill/index-generator.js +84 -0
- package/dist/core/skill/startup.js +73 -0
- package/dist/core/skill/switch-resolver.js +115 -0
- package/dist/core/task/task-activity-store.js +219 -0
- package/dist/eck/kit-renderer.js +30 -3
- package/dist/eck/manifest-engine.js +26 -4
- package/dist/index.js +708 -18
- package/dist/ipc.js +564 -2
- package/dist/paths.js +30 -9
- package/dist/response-system/engines/v1/proactive-flow.js +116 -15
- package/dist/response-system/modes/single-session/index.js +3 -0
- package/dist/trigger/feedback.js +1 -0
- package/dist/trigger/manager.js +0 -10
- package/dist/trigger/scheduler.js +11 -0
- package/dist/trigger/validation.js +22 -0
- package/dist/utils/avatar-upload.js +59 -18
- package/dist/utils/error-dict.json +6 -3
- package/dist/utils/error-utils.js +27 -0
- package/dist/utils/logger.js +32 -10
- package/dist/utils/media-cache.js +84 -0
- package/dist/utils/msg-diag.js +97 -0
- package/dist/utils/welcome.js +37 -8
- package/kits/docs/AUTHORING.md +314 -0
- package/kits/docs/GUIDE.md +2 -0
- package/kits/docs/INDEX.md +2 -0
- package/kits/docs/aun/CHEATSHEET.md +4 -0
- package/kits/docs/aun/SDK.md +60 -0
- package/kits/docs/context-assembly.md +10 -6
- package/kits/docs/evolcore/INDEX.md +17 -3
- package/kits/docs/evolcore/agent-create.md +24 -0
- package/kits/docs/evolcore/agent.md +5 -2
- package/kits/docs/evolcore/config.md +1 -1
- package/kits/docs/evolcore/ec-capabilities.md +364 -0
- package/kits/docs/evolcore/group.md +34 -18
- package/kits/docs/evolcore/memory-architecture.md +78 -0
- package/kits/docs/evolcore/memory-consolidation-batches.md +133 -0
- package/kits/docs/evolcore/memory-consolidation.md +263 -0
- package/kits/docs/evolcore/memory-tags.md +63 -0
- package/kits/docs/evolcore/memory.md +110 -0
- package/kits/docs/evolcore/menu-client.md +27 -11
- package/kits/{schemas → docs/evolcore}/menu-exec-schema-commands.md +12 -6
- package/kits/docs/evolcore/menu-protocol.md +213 -0
- package/kits/docs/evolcore/msg.md +2 -0
- package/kits/docs/evolcore/trigger.md +7 -5
- package/kits/docs/path-registry.md +6 -8
- package/kits/docs/prompt-loading-architecture.md +5 -3
- package/kits/docs/venues/group.md +5 -4
- package/kits/eck_manifest.json +294 -88
- package/kits/eck_manifest.memory.json +257 -0
- package/kits/rules/03-identity.md +8 -8
- package/kits/rules/05-venue.md +4 -2
- package/kits/rules/06-channel.md +1 -1
- package/kits/schemas/_meta.json +276 -47
- package/kits/schemas/agent-config.schema.12.json +38 -2
- package/kits/schemas/agent-config.schema.13.json +591 -0
- package/kits/schemas/daemon.schema.6.json +9 -9
- package/kits/schemas/defaults.schema.5.json +29 -0
- package/kits/schemas/relation-config.schema.8.json +14 -1
- package/kits/schemas/relation-config.schema.9.json +129 -0
- package/kits/schemas/role-config.schema.1.json +3 -3
- package/kits/skills/.switches.json +3 -0
- package/kits/skills/ec-skill/SKILL.md +217 -0
- package/kits/skills/ec-skill/scripts/cli.mjs +128 -0
- package/kits/skills/ec-skill/scripts/deps.mjs +107 -0
- package/kits/skills/ec-skill/scripts/frontmatter.mjs +104 -0
- package/kits/skills/ec-skill/scripts/skill.mjs +629 -0
- package/kits/skills/ec-skill/scripts/template/SKILL.md.tmpl +30 -0
- package/kits/templates/decision/auto-mention.md +25 -0
- package/kits/templates/decision/session-renew.md +22 -0
- package/kits/templates/memory-consolidation/forget.md +104 -0
- package/kits/templates/memory-consolidation/generalize.md +76 -0
- package/kits/templates/memory-consolidation/notes.md +133 -0
- package/kits/templates/memory-consolidation/profile.md +58 -0
- package/kits/templates/memory-consolidation/promote.md +72 -0
- package/kits/templates/memory-consolidation/workflow.md +75 -0
- package/kits/templates/system-fragments/bootstrap.md +14 -5
- package/kits/templates/system-fragments/commands.md +1 -0
- package/kits/templates/system-fragments/group-history.md +6 -0
- package/kits/templates/system-fragments/identity.md +0 -3
- package/kits/templates/system-fragments/memory.md +79 -0
- package/kits/templates/system-fragments/reply.md +1 -0
- package/kits/templates/system-fragments/venue.md +1 -1
- package/package.json +4 -6
- package/dist/trigger/legacy-session-history.js +0 -19
- package/kits/templates/system-fragments/group-unread-history.md +0 -7
|
@@ -113,10 +113,11 @@ export const MENU_NAME_COMMANDS = Object.freeze({
|
|
|
113
113
|
model: '/model',
|
|
114
114
|
effort: '/effort',
|
|
115
115
|
chatmode: '/chatmode',
|
|
116
|
-
mentionmode: '/
|
|
116
|
+
mentionmode: '/mention',
|
|
117
117
|
group: '/group',
|
|
118
118
|
permission: '/perm',
|
|
119
119
|
activity: '/activity',
|
|
120
|
+
task: '/task',
|
|
120
121
|
dispatch: '/dispatch',
|
|
121
122
|
observable: '/observable',
|
|
122
123
|
system: '/system',
|
|
@@ -215,7 +216,7 @@ export function isEvolMenuVersionGateEnabled() {
|
|
|
215
216
|
export function isAunMenuTokenRequired() {
|
|
216
217
|
return loadDaemonConfig().aun?.menuTokenRequired === true;
|
|
217
218
|
}
|
|
218
|
-
export function evolMenuResponseTransportMetadata(sdkVersion) {
|
|
219
|
+
export function evolMenuResponseTransportMetadata(sdkVersion, volatileCapability) {
|
|
219
220
|
return {
|
|
220
221
|
// Clear inherited request state so AUNChannel applies daemon aun.defaultEncrypt.
|
|
221
222
|
encrypted: undefined,
|
|
@@ -226,6 +227,7 @@ export function evolMenuResponseTransportMetadata(sdkVersion) {
|
|
|
226
227
|
...(typeof sdkVersion === 'string' && sdkVersion.trim()
|
|
227
228
|
? { menuClientSdkVersion: sdkVersion.trim() }
|
|
228
229
|
: {}),
|
|
230
|
+
...(volatileCapability === '1' ? { menuClientVolatileV1: true } : {}),
|
|
229
231
|
};
|
|
230
232
|
}
|
|
231
233
|
const EXPLICIT_SCOPE_UPDATE_NAMES = new Set([
|
|
@@ -243,7 +245,7 @@ const EXPLICIT_SCOPE_UPDATE_COMMANDS = new Set([
|
|
|
243
245
|
'/effort',
|
|
244
246
|
'/chatmode',
|
|
245
247
|
'/dispatch',
|
|
246
|
-
'/
|
|
248
|
+
'/mention',
|
|
247
249
|
'/group',
|
|
248
250
|
'/perm',
|
|
249
251
|
'/activity',
|
|
@@ -315,6 +317,13 @@ export function validateMenuRequest(request) {
|
|
|
315
317
|
if (request.args !== undefined && (!request.args || typeof request.args !== 'object' || Array.isArray(request.args))) {
|
|
316
318
|
return { code: 'INVALID_ARGUMENT', message: 'Menu request args must be an object' };
|
|
317
319
|
}
|
|
320
|
+
if (request.name === 'task' || request.cmd === '/task') {
|
|
321
|
+
if (type !== 'menu.query')
|
|
322
|
+
return { code: 'NOT_SUPPORTED', message: 'task only supports menu.query' };
|
|
323
|
+
const taskError = validateTaskActivityQueryArgs(request.args);
|
|
324
|
+
if (taskError)
|
|
325
|
+
return taskError;
|
|
326
|
+
}
|
|
318
327
|
if (type === 'menu.list' && Object.hasOwn(request, 'context')) {
|
|
319
328
|
return { code: 'INVALID_ARGUMENT', message: 'menu.list context must be inside args.context (for a daemon catalog, use args.context.kind=process)' };
|
|
320
329
|
}
|
|
@@ -353,6 +362,32 @@ export function validateMenuRequest(request) {
|
|
|
353
362
|
}
|
|
354
363
|
return null;
|
|
355
364
|
}
|
|
365
|
+
export function validateTaskActivityQueryArgs(value) {
|
|
366
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
367
|
+
return { code: 'INVALID_ARGUMENT', message: 'task query requires args' };
|
|
368
|
+
}
|
|
369
|
+
const args = value;
|
|
370
|
+
if (args.view !== 'activities' && args.view !== 'activity') {
|
|
371
|
+
return { code: 'INVALID_ARGUMENT', message: 'task query requires args.view=activities or activity' };
|
|
372
|
+
}
|
|
373
|
+
const allowed = args.view === 'activities' ? ['view', 'taskId', 'offset', 'limit'] : ['view', 'taskId', 'activityId'];
|
|
374
|
+
if (Object.keys(args).some(key => !allowed.includes(key))) {
|
|
375
|
+
return { code: 'INVALID_ARGUMENT', message: 'unsupported task query argument' };
|
|
376
|
+
}
|
|
377
|
+
if (typeof args.taskId !== 'string' || !/^task-[A-Za-z0-9._:-]+$/.test(args.taskId)) {
|
|
378
|
+
return { code: 'INVALID_ARGUMENT', message: 'invalid taskId' };
|
|
379
|
+
}
|
|
380
|
+
if (args.view === 'activity') {
|
|
381
|
+
if (typeof args.activityId !== 'string' || !/^activity-[A-Za-z0-9._:-]+$/.test(args.activityId)) {
|
|
382
|
+
return { code: 'INVALID_ARGUMENT', message: 'invalid activityId' };
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
else if ((args.offset !== undefined && (!Number.isSafeInteger(args.offset) || args.offset < 0))
|
|
386
|
+
|| (args.limit !== undefined && (!Number.isSafeInteger(args.limit) || args.limit < 1 || args.limit > 100))) {
|
|
387
|
+
return { code: 'INVALID_ARGUMENT', message: 'offset must be a non-negative integer and limit must be between 1 and 100' };
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
356
391
|
export function menuSuccess(header, data) {
|
|
357
392
|
return {
|
|
358
393
|
type: 'menu.response',
|
|
@@ -373,7 +408,9 @@ export function menuFailure(header, error) {
|
|
|
373
408
|
},
|
|
374
409
|
};
|
|
375
410
|
}
|
|
376
|
-
export
|
|
411
|
+
export const MENU_RESPONSE_MAX_BYTES = 384 * 1024;
|
|
412
|
+
export const MENU_RESPONSE_SAFETY_MARGIN_BYTES = 1024;
|
|
413
|
+
export function enforceMenuResponseSize(response, maxBytes = MENU_RESPONSE_MAX_BYTES) {
|
|
377
414
|
let bytes;
|
|
378
415
|
try {
|
|
379
416
|
bytes = Buffer.byteLength(JSON.stringify(response), 'utf8');
|
|
@@ -408,6 +445,7 @@ const STABLE_CODES = new Set([
|
|
|
408
445
|
'RATE_LIMITED', 'CATALOG_STALE', 'DATA_MIGRATION_REQUIRED',
|
|
409
446
|
'INVALID_CLIENT', 'REMOTE_ACCESS_TOKEN_INVALID', 'ECWEB_TOKEN_INVALID', 'CLIENT_BUSY', 'INVALID_RESPONSE', 'TIMEOUT',
|
|
410
447
|
'RESPONSE_TOO_LARGE',
|
|
448
|
+
'ACTIVITY_NOT_FOUND', 'ACTIVITY_EXPIRED',
|
|
411
449
|
'TOPIC_SESSION_NOT_FOUND', 'TOPIC_SESSION_LOOKUP_FAILED',
|
|
412
450
|
'ROOT_NOT_FOUND', 'ROOT_FORBIDDEN', 'ROOT_EXPIRED', 'ROOT_SCOPE_MISMATCH', 'ROOT_PEER_MISMATCH',
|
|
413
451
|
'INVALID_ROOT_ID', 'MISSING_ROOT_ID', 'INVALID_ROOT_PATH', 'NOT_A_DIRECTORY', 'FILE_TOO_LARGE',
|
|
@@ -43,7 +43,7 @@ export function probeSessionActivity(evidence, probes) {
|
|
|
43
43
|
return evaluateSessionActivity(collected);
|
|
44
44
|
}
|
|
45
45
|
// 支持的命令列表
|
|
46
|
-
const commands = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/stop', '/pause', '/compact', '/renew', '/repair', '/fork', '/del', '/perm', '/file', '/check', '/rewind', '/activity', '/observable', '/chatmode', '/
|
|
46
|
+
const commands = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/stop', '/pause', '/compact', '/renew', '/repair', '/fork', '/del', '/perm', '/file', '/check', '/rewind', '/activity', '/observable', '/chatmode', '/mention', '/ask', '/resume', '/aid', '/rpc', '/storage', '/agent', '/trigger', '/upgrade', '/pair', '/memory'];
|
|
47
47
|
const deprecatedCommands = ['/clear'];
|
|
48
48
|
commands.push('/diag');
|
|
49
49
|
const exactBoundaryCommands = new Set(['/pause', '/resume', '/stop', '/pair', '/diag']);
|
|
@@ -64,10 +64,11 @@ const aliases = {
|
|
|
64
64
|
'/name': '/rename',
|
|
65
65
|
'/rw': '/rewind',
|
|
66
66
|
'/base': '/baseagent',
|
|
67
|
+
'/mentionmode': '/mention',
|
|
67
68
|
};
|
|
68
|
-
const GROUP_READ_ONLY_COMMANDS = new Set(['/
|
|
69
|
+
const GROUP_READ_ONLY_COMMANDS = new Set(['/model', '/effort', '/perm', '/baseagent']);
|
|
69
70
|
const GROUP_TASK_COMMANDS = new Set([
|
|
70
|
-
'/help', '/evolhelp', '/status', '/check', '/ask', '/pause', '/resume', '/stop', '/compact', '/renew',
|
|
71
|
+
'/help', '/evolhelp', '/status', '/check', '/ask', '/pause', '/resume', '/stop', '/compact', '/renew', '/mention', '/memory',
|
|
71
72
|
]);
|
|
72
73
|
/** Group slash policy applies to every role, including old command-card clicks. */
|
|
73
74
|
export function guardGroupSlashCommand(content, chatType) {
|
|
@@ -94,7 +95,7 @@ export function guardGroupSlashCommand(content, chatType) {
|
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
97
|
// 命令快速路径前缀(所有命令都不进入消息队列)
|
|
97
|
-
const quickCommandPrefixes = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/repair', '/fork', '/stop', '/pause', '/clear', '/compact', '/renew', '/del', '/perm', '/file', '/check', '/s ', '/name', '/rewind', '/rw', '/rw ', '/activity', '/observable', '/chatmode', '/
|
|
98
|
+
const quickCommandPrefixes = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/repair', '/fork', '/stop', '/pause', '/clear', '/compact', '/renew', '/del', '/perm', '/file', '/check', '/s ', '/name', '/rewind', '/rw', '/rw ', '/activity', '/observable', '/chatmode', '/mention', '/ask', '/resume', '/base ', '/aid', '/rpc', '/storage', '/agent', '/trigger', '/upgrade', '/pair', '/memory'];
|
|
98
99
|
quickCommandPrefixes.push('/diag');
|
|
99
100
|
/**
|
|
100
101
|
* 计算两个字符串的 Levenshtein 距离(编辑距离)
|
|
@@ -149,8 +150,7 @@ export function guardThreadCommand(content, threadId) {
|
|
|
149
150
|
const threadBlocked = ['/new', '/slist', '/s', '/session', '/fork', '/del', '/repair'];
|
|
150
151
|
const hasCommandArgument = (command) => new RegExp(`^${command.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?:\\s|$)`).test(content);
|
|
151
152
|
const isBlocked = threadBlocked.some(hasCommandArgument);
|
|
152
|
-
|
|
153
|
-
if (!isBlocked && !isRewindMutation)
|
|
153
|
+
if (!isBlocked)
|
|
154
154
|
return undefined;
|
|
155
155
|
return { kind: 'command.error', text: '⚠️ 话题中不支持此命令' };
|
|
156
156
|
}
|
|
@@ -159,9 +159,9 @@ export function guardRoleCommand(content, activeChatType, isAdmin) {
|
|
|
159
159
|
return undefined;
|
|
160
160
|
// visitor/member 在群聊和私聊中均可访问的只读命令:纯查询形态(带参写操作由各 handler 内部守卫拦截)
|
|
161
161
|
const userGroupCommands = [
|
|
162
|
-
'/status', '/help', '/evolhelp', '/check', '/chatmode', '/
|
|
162
|
+
'/status', '/help', '/evolhelp', '/check', '/chatmode', '/mention',
|
|
163
163
|
'/model', '/effort', '/baseagent', '/perm', '/activity', '/stop', '/pause',
|
|
164
|
-
'/resume', '/trigger', '/file', '/ask',
|
|
164
|
+
'/resume', '/trigger', '/file', '/ask', '/memory',
|
|
165
165
|
];
|
|
166
166
|
const userCommands = activeChatType === 'group' && !isAdmin
|
|
167
167
|
? userGroupCommands
|
|
@@ -186,14 +186,14 @@ export async function guardIdleCommand(opts) {
|
|
|
186
186
|
// - 始终需要 idle(无参即写):/compact /repair /fork /new
|
|
187
187
|
// - 仅带参时需要 idle(无参是列表/用法):/session /baseagent /rewind
|
|
188
188
|
// - /chatmode:在 handler 内部自行做写操作的 idle 检查
|
|
189
|
-
// - /
|
|
189
|
+
// - /mention:在 handler 内部自行做写操作的 idle 检查
|
|
190
190
|
// /renew owns a stronger gate + authoritative probe and deliberately skips
|
|
191
191
|
// this realtime precheck so delayed retries can return their committed
|
|
192
192
|
// idempotent result even while later work is busy.
|
|
193
193
|
const idleAlways = ['/compact', '/repair', '/fork', '/new'];
|
|
194
194
|
const idleWhenArg = ['/session', '/baseagent', '/rewind'];
|
|
195
195
|
const usesTopicBackendBoundary = !!opts.threadId
|
|
196
|
-
&& opts.content === '/compact'
|
|
196
|
+
&& (opts.content === '/compact' || opts.content.startsWith('/rewind '))
|
|
197
197
|
&& typeof opts.messageQueue?.withSessionBarrier === 'function';
|
|
198
198
|
const needsIdle = !usesTopicBackendBoundary && (idleAlways.some(cmd => opts.content === cmd || opts.content.startsWith(cmd + ' ')) ||
|
|
199
199
|
idleWhenArg.some(cmd => opts.content.startsWith(cmd + ' ')));
|