mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-06-23 22:40:05 +02:00
Add files via upload
This commit is contained in:
@@ -2580,6 +2580,8 @@
|
||||
"agentModeSingle": "Single-agent (Eino ADK)",
|
||||
"agentModeMulti": "Multi-agent (Eino)",
|
||||
"agentModeHint": "Same as chat: Eino single-agent (ADK), or Deep / Plan-Execute / Supervisor (last three require multi_agent.enabled).",
|
||||
"concurrency": "Concurrency",
|
||||
"concurrencyHint": "Number of subtasks to run in parallel (1-8). Default 1 is serial; use 1-2 for scan-heavy tasks.",
|
||||
"scheduleMode": "Schedule mode",
|
||||
"scheduleModeManual": "Manual",
|
||||
"scheduleModeCron": "Cron expression",
|
||||
@@ -2594,8 +2596,8 @@
|
||||
"tasksList": "Task list (one task per line)",
|
||||
"tasksListPlaceholder": "Enter task list, one per line",
|
||||
"tasksListPlaceholderExample": "Enter task list, one per line, for example:\nScan open ports of 192.168.1.1\nCheck if https://example.com has SQL injection\nEnumerate subdomains of example.com",
|
||||
"tasksListHint": "Enter one task command per line; the system will execute them in order. Empty lines are ignored.",
|
||||
"tasksListHintFull": "Hint: Enter one task command per line; the system will execute these tasks in order. Empty lines are ignored.",
|
||||
"tasksListHint": "Enter one task command per line; the system runs them via a concurrency pool. Empty lines are ignored.",
|
||||
"tasksListHintFull": "Hint: Enter one task command per line; the system runs them via a concurrency pool. Empty lines are ignored.",
|
||||
"createQueue": "Create queue"
|
||||
},
|
||||
"batchQueueDetailModal": {
|
||||
@@ -2629,6 +2631,8 @@
|
||||
"scheduleToggleFailed": "Failed to update schedule toggle",
|
||||
"completedAt": "Completed at",
|
||||
"taskTotal": "Total tasks",
|
||||
"concurrency": "Concurrency",
|
||||
"concurrencyEditHint": "Click to edit. Cannot change while the queue is running.",
|
||||
"taskList": "Task list",
|
||||
"startLabel": "Start",
|
||||
"completeLabel": "Complete",
|
||||
|
||||
@@ -2568,6 +2568,8 @@
|
||||
"agentModeSingle": "单代理(Eino ADK)",
|
||||
"agentModeMulti": "多代理(Eino)",
|
||||
"agentModeHint": "与对话页一致:Eino 单代理(ADK),或 Deep / Plan-Execute / Supervisor(后三种需已启用多代理)。",
|
||||
"concurrency": "并发数",
|
||||
"concurrencyHint": "同时执行的子任务数量(1-8)。默认 1 为串行;含扫描类工具时建议 1-2。",
|
||||
"scheduleMode": "调度方式",
|
||||
"scheduleModeManual": "手工执行",
|
||||
"scheduleModeCron": "调度表达式(Cron)",
|
||||
@@ -2582,8 +2584,8 @@
|
||||
"tasksList": "任务列表(每行一个任务)",
|
||||
"tasksListPlaceholder": "请输入任务列表,每行一个任务",
|
||||
"tasksListPlaceholderExample": "请输入任务列表,每行一个任务,例如:\n扫描 192.168.1.1 的开放端口\n检查 https://example.com 是否存在SQL注入\n枚举 example.com 的子域名",
|
||||
"tasksListHint": "每行输入一个任务指令,系统将依次执行这些任务。空行会被自动忽略。",
|
||||
"tasksListHintFull": "提示:每行输入一个任务指令,系统将依次执行这些任务。空行会被自动忽略。",
|
||||
"tasksListHint": "每行输入一个任务指令,系统将按并发池执行这些任务。空行会被自动忽略。",
|
||||
"tasksListHintFull": "提示:每行输入一个任务指令,系统将按并发池执行这些任务。空行会被自动忽略。",
|
||||
"createQueue": "创建队列"
|
||||
},
|
||||
"batchQueueDetailModal": {
|
||||
@@ -2617,6 +2619,8 @@
|
||||
"scheduleToggleFailed": "更新调度开关失败",
|
||||
"completedAt": "完成时间",
|
||||
"taskTotal": "任务总数",
|
||||
"concurrency": "并发数",
|
||||
"concurrencyEditHint": "点击可修改;队列运行中不可改。",
|
||||
"taskList": "任务列表",
|
||||
"startLabel": "开始",
|
||||
"completeLabel": "完成",
|
||||
|
||||
@@ -990,6 +990,7 @@ async function createBatchQueue() {
|
||||
const roleSelect = document.getElementById('batch-queue-role');
|
||||
const projectSelect = document.getElementById('batch-queue-project-id');
|
||||
const agentModeSelect = document.getElementById('batch-queue-agent-mode');
|
||||
const concurrencyInput = document.getElementById('batch-queue-concurrency');
|
||||
const scheduleModeSelect = document.getElementById('batch-queue-schedule-mode');
|
||||
const cronExprInput = document.getElementById('batch-queue-cron-expr');
|
||||
const executeNowCheckbox = document.getElementById('batch-queue-execute-now');
|
||||
@@ -1019,6 +1020,9 @@ async function createBatchQueue() {
|
||||
const scheduleMode = scheduleModeSelect ? (scheduleModeSelect.value === 'cron' ? 'cron' : 'manual') : 'manual';
|
||||
const cronExpr = cronExprInput ? cronExprInput.value.trim() : '';
|
||||
const executeNow = executeNowCheckbox ? !!executeNowCheckbox.checked : false;
|
||||
let concurrency = concurrencyInput ? parseInt(concurrencyInput.value, 10) : 1;
|
||||
if (!Number.isFinite(concurrency) || concurrency < 1) concurrency = 1;
|
||||
if (concurrency > 8) concurrency = 8;
|
||||
if (scheduleMode === 'cron' && !cronExpr) {
|
||||
alert(_t('batchImportModal.cronExprRequired'));
|
||||
return;
|
||||
@@ -1043,6 +1047,7 @@ async function createBatchQueue() {
|
||||
cronExpr,
|
||||
executeNow,
|
||||
projectId,
|
||||
concurrency,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1489,6 +1494,7 @@ async function showBatchQueueDetail(queueId) {
|
||||
<div class="bq-kv"><span class="bq-kv__k">${escapeHtml(_t('batchQueueDetailModal.role'))}</span><span class="bq-kv__v" id="bq-role-val">${allowSubtaskMutation ? `<span class="bq-inline-editable" onclick="startInlineEditRole()" title="${escapeHtml(_t('common.edit'))}">${roleLineVal}</span>` : roleLineVal}</span></div>
|
||||
<div class="bq-kv"><span class="bq-kv__k">${escapeHtml(_t('batchImportModal.agentMode'))}</span><span class="bq-kv__v" id="bq-agentmode-val">${allowSubtaskMutation ? `<span class="bq-inline-editable" onclick="startInlineEditAgentMode()" title="${escapeHtml(_t('common.edit'))}">${escapeHtml(agentModeText)}</span>` : escapeHtml(agentModeText)}</span></div>
|
||||
<div class="bq-kv"><span class="bq-kv__k">${escapeHtml(_t('batchImportModal.scheduleMode'))}</span><span class="bq-kv__v" id="bq-schedule-val">${allowSubtaskMutation ? `<span class="bq-inline-editable" onclick="startInlineEditSchedule()" title="${escapeHtml(_t('common.edit'))}">${scheduleDetail}</span>` : scheduleDetail}</span></div>
|
||||
<div class="bq-kv"><span class="bq-kv__k">${escapeHtml(_t('batchQueueDetailModal.concurrency'))}</span><span class="bq-kv__v" id="bq-concurrency-val">${allowSubtaskMutation ? `<span class="bq-inline-editable" onclick="startInlineEditConcurrency()" title="${escapeHtml(_t('common.edit'))}">${escapeHtml(String(queue.concurrency && queue.concurrency > 0 ? queue.concurrency : 1))}</span>` : escapeHtml(String(queue.concurrency && queue.concurrency > 0 ? queue.concurrency : 1))}</span></div>
|
||||
<div class="bq-kv"><span class="bq-kv__k">${escapeHtml(_t('batchQueueDetailModal.taskTotal'))}</span><span class="bq-kv__v">${queue.tasks.length}</span></div>
|
||||
${queue.scheduleMode === 'cron' ? `<div class="bq-kv bq-kv--block"><span class="bq-kv__k">${escapeHtml(_t('batchQueueDetailModal.scheduleCronAuto'))}</span><span class="bq-kv__v bq-kv__v--control"><label class="bq-cron-toggle"><input type="checkbox" ${queue.scheduleEnabled !== false ? 'checked' : ''} onchange="updateBatchQueueScheduleEnabled(this.checked)" /><span class="bq-cron-toggle__hint">${escapeHtml(_t('batchQueueDetailModal.scheduleCronAutoHint'))}</span></label></span></div>` : ''}
|
||||
</section>
|
||||
@@ -2287,6 +2293,75 @@ async function saveInlineAgentMode() {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeBatchQueueConcurrencyInput(raw) {
|
||||
let n = parseInt(raw, 10);
|
||||
if (!Number.isFinite(n) || n < 1) n = 1;
|
||||
if (n > 8) n = 8;
|
||||
return n;
|
||||
}
|
||||
|
||||
// --- 内联编辑:并发数 ---
|
||||
function startInlineEditConcurrency() {
|
||||
const container = document.getElementById('bq-concurrency-val');
|
||||
if (!container) return;
|
||||
const queueId = batchQueuesState.currentQueueId;
|
||||
if (!queueId) return;
|
||||
apiFetch(`/api/batch-tasks/${queueId}`).then(r => r.json()).then(detail => {
|
||||
const queue = detail.queue || {};
|
||||
const current = normalizeBatchQueueConcurrencyInput(queue.concurrency || 1);
|
||||
container.innerHTML = `<span class="bq-inline-edit-controls">
|
||||
<input type="number" id="bq-edit-concurrency" min="1" max="8" value="${current}" style="width:72px;" />
|
||||
</span>`;
|
||||
const inp = document.getElementById('bq-edit-concurrency');
|
||||
if (!inp) return;
|
||||
inp.focus();
|
||||
inp.select();
|
||||
let cancelled = false;
|
||||
inp.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') { e.preventDefault(); inp.blur(); }
|
||||
if (e.key === 'Escape') { cancelled = true; cancelAllInlineEdits(); }
|
||||
});
|
||||
inp.addEventListener('blur', () => {
|
||||
if (!cancelled) saveInlineConcurrency();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function saveInlineConcurrency() {
|
||||
if (_bqInlineSaving) return;
|
||||
_bqInlineSaving = true;
|
||||
const queueId = batchQueuesState.currentQueueId;
|
||||
if (!queueId) { _bqInlineSaving = false; return; }
|
||||
const inp = document.getElementById('bq-edit-concurrency');
|
||||
const concurrency = normalizeBatchQueueConcurrencyInput(inp ? inp.value : 1);
|
||||
try {
|
||||
const detailResp = await apiFetch(`/api/batch-tasks/${queueId}`);
|
||||
const detail = await detailResp.json();
|
||||
const q = detail.queue || {};
|
||||
const response = await apiFetch(`/api/batch-tasks/${queueId}/metadata`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
title: q.title || '',
|
||||
role: q.role || '',
|
||||
agentMode: q.agentMode || 'eino_single',
|
||||
concurrency,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const result = await response.json().catch(() => ({}));
|
||||
throw new Error(result.error || _t('tasks.updateTaskFailed'));
|
||||
}
|
||||
_bqInlineSaving = false;
|
||||
showBatchQueueDetail(queueId);
|
||||
refreshBatchQueues();
|
||||
} catch (e) {
|
||||
_bqInlineSaving = false;
|
||||
console.error(e);
|
||||
alert(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 单条执行 ---
|
||||
async function runSingleBatchTask(queueId, taskId) {
|
||||
if (!queueId || !taskId) return;
|
||||
@@ -2441,6 +2516,8 @@ window.startInlineEditRole = startInlineEditRole;
|
||||
window.saveInlineRole = saveInlineRole;
|
||||
window.startInlineEditAgentMode = startInlineEditAgentMode;
|
||||
window.saveInlineAgentMode = saveInlineAgentMode;
|
||||
window.startInlineEditConcurrency = startInlineEditConcurrency;
|
||||
window.saveInlineConcurrency = saveInlineConcurrency;
|
||||
window.runSingleBatchTask = runSingleBatchTask;
|
||||
window.startInlineEditSchedule = startInlineEditSchedule;
|
||||
window.toggleInlineScheduleCron = toggleInlineScheduleCron;
|
||||
|
||||
@@ -4010,6 +4010,11 @@
|
||||
</select>
|
||||
<div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.agentModeHint">与对话页一致:Eino 单代理(ADK),或 Deep / Plan-Execute / Supervisor(后三种需已启用多代理)。</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="batch-queue-concurrency" data-i18n="batchImportModal.concurrency">并发数</label>
|
||||
<input type="number" id="batch-queue-concurrency" min="1" max="8" value="1" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;" />
|
||||
<div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.concurrencyHint">同时执行的子任务数量(1-8)。默认 1 为串行;含扫描类工具时建议 1-2。</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="batch-queue-schedule-mode" data-i18n="batchImportModal.scheduleMode">调度方式</label>
|
||||
<select id="batch-queue-schedule-mode" onchange="handleBatchScheduleModeChange()" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
|
||||
|
||||
Reference in New Issue
Block a user