新增: 无人值守P0任务边界全链

- 任务级授权边界判定与审批旁路单点插桩
- boundary_json 随会话落库(V45 可逆迁移)
- 六路非正常终局统一安全停靠与托盘通知
- 每五轮进度事件与会话头部进度条
- 前端边界配置卡侧栏徽标及 UX 校验补齐
This commit is contained in:
lxy
2026-10-04 16:27:30 +08:00
parent 8396849d04
commit b2d44f85e9
29 changed files with 2773 additions and 142 deletions
+79
View File
@@ -49,6 +49,8 @@ export default {
// conversation load/switch failure feedback (network jitter/IPC down → empty list/blank, was silent)
loadConvFail: 'Failed to load conversations. Please check your network or backend connection.',
switchConvFail: 'Failed to switch conversation. Please retry.',
// UX走查 P3-7/P1-1: linked-conversation jump hit a deleted conversation (was silently creating a blank one / dead click in detached window)
convDeleted: 'Conversation deleted',
// M30: rename/archive/pin IPC failure feedback (was no try/catch, exceptions leaked to unhandledrejection)
renameConvFail: 'Failed to rename. Please retry.',
archiveConvFail: 'Failed to {action}. Please retry.',
@@ -87,11 +89,23 @@ export default {
title: 'Sub-agent',
completed: 'completed',
truncated: 'truncated',
cancelled: 'cancelled',
failed: 'failed',
// stop_kind structured stop reasons (replaces summary heuristics; truncation sub-kinds surfaced)
truncMaxRounds: 'max rounds reached',
truncWallClock: 'timed out',
truncTokenBudget: 'token budget reached',
noReport: 'no report produced',
// Rejected-tools chip ({tools} = "tool×count" items, first 2 shown then +N)
rejected: 'rejected {tools}',
// Startup-failed sub-agents have no persisted trace; card is click-disabled
noTrace: 'No trace (failed to start)',
meta: '{rounds} rounds · {tokens} tokens',
// S3: finished card is clickable to open the read-only trace (hover hint)
viewHint: 'Click to view execution trace',
},
// P3-6 background-conversation sub-agent finished light toast ({status} reuses agentFinished status words above, {summary} truncated to 40 chars)
agentFinishedToast: 'Sub-agent {status}: {summary}',
// S3 sub-agent trace overlay (opened from the finished card, read-only simple render,
// discarded on close)
agentTrace: {
@@ -102,6 +116,71 @@ export default {
roleAssistant: 'Assistant',
roleTool: 'Tool result',
roleSystem: 'System',
deniedTool: 'Denied: {tool}',
riskLow: 'low risk',
riskMedium: 'medium risk',
riskHigh: 'high risk',
},
// Unattended task parked card (AiTaskParked, terminal of the pending family):
// Continue re-authorizes the loop, Stop archives without resuming
taskParked: {
title: 'Task parked',
// stop_kind structured stop reason (vocabulary pinned by backend contract; unknown values fall back to unknownKind)
stopKind: {
approval_timeout: 'Approval timed out',
cancelled: 'Cancelled',
circuit_breaker: 'Circuit breaker',
stall_breaker: 'Stall breaker',
max_rounds: 'Max rounds reached',
fatal: 'Repeated failures (retry budget exhausted)',
midstream: 'Stream interrupted',
},
unknownKind: 'Parked',
stopArchive: 'Stop & Archive',
stoppedToast: 'Task stopped, will not resume',
archiveFailed: 'Stop failed: {msg}',
},
// Unattended task progress (AiTaskProgress, design §4.3): TopBar lightweight progress,
// visible as "still working" during silent periods
taskProgress: {
running: 'Running · round {round}/{max} · {tokens} tokens',
unlimited: 'Running · round {round} · {tokens} tokens',
barHint: 'Round {round}/{max}',
},
// Unattended boundary config card (authorized once at kickoff, effective for the task
// lifetime, dies with the conversation)
taskBoundary: {
toggle: 'Unattended',
badge: 'Unattended boundary authorized',
riskCeiling: 'Risk ceiling',
riskLow: 'Low',
riskMedium: 'Medium',
dirs: 'Directory allowlist',
dirPlaceholder: 'Enter absolute directory path',
dirAdd: 'Add',
dirEmpty: 'No directories added',
forbidDestructive: 'Destructive commands always blocked',
budgetToggle: 'Budget (advanced)',
budgetRounds: 'Max rounds',
budgetTokens: 'Max tokens',
budgetWallSecs: 'Wall-clock seconds',
budgetHint: 'Leave empty for unlimited',
budgetInvalid: 'Budget values must be positive integers',
confirmSet: 'Authorize once, no interruptions for the whole task',
clearBoundary: 'Clear boundary',
setOk: 'Unattended boundary authorized',
clearOk: 'Boundary cleared, back to per-action approval',
setFail: 'Failed to set boundary: {msg}',
lockedGenerating: 'Task is running: only clearing (revoke) is allowed, fields are locked',
loadFailed: 'Failed to load boundary; the form below is not trustworthy',
retryLoad: 'Retry',
dirErrIllegal: 'Path contains illegal characters < > : " | ? *',
dirErrRelative: 'Enter an absolute path (e.g. D:\\projects or /home/user)',
clearConfirm: 'Clearing the boundary revokes unattended authorization immediately; tool calls in the running task will fall back to per-action approval. Clear?',
echoRisk: 'risk ceiling {risk}',
echoDirs: '{n} dirs',
echoBudget: 'budget {rounds} rounds / {tokens} tokens / {secs}s',
echoNoBudget: 'no budget limit',
},
},
}
+3
View File
@@ -110,6 +110,7 @@ export default {
// ── Skill ──
clearSkill: 'Clear skill',
skillBadgeTip: 'Injected full skill playbook: {name}',
placeholderWithSkill: 'Skill selected. Type arguments and press Enter',
placeholderDefault: "Type a message... (/ for skills, {'@'} to mention)",
skillNoMatch: 'No matching skill',
@@ -141,6 +142,8 @@ export default {
imageTooLarge: 'Image too large (max 10MB), skipped',
imageLimit: 'Up to {n} images, extras ignored',
imageReadFailed: 'Failed to read image',
imageIgnoredWarn: 'Current model does not support images; they will be ignored on send',
imageOnlyBlocked: 'Current model does not support images; switch to a vision model or add some text',
// ── Confirm dialog ──
confirmDeleteConversation: 'Delete chat "{title}"? This cannot be undone.',