mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-06-01 12:01:46 +02:00
Add files via upload
This commit is contained in:
@@ -470,6 +470,8 @@
|
||||
"einoAgentReplyTitle": "Sub-agent reply",
|
||||
"einoStreamErrorTitle": "⚠️ Eino stream interrupted ({{agent}})",
|
||||
"einoStreamErrorMessage": "Streaming read failed; the system will retry or terminate according to policy.",
|
||||
"einoRunRetryTitle": "🔁 Transient error retry",
|
||||
"einoRunRetryErrorDetail": "Error detail",
|
||||
"iterationLimitReachedTitle": "⛔ Iteration limit reached",
|
||||
"iterationLimitReachedMessage": "Maximum iteration count reached; automatic iteration has stopped.",
|
||||
"einoPendingOrphanedTitle": "🧹 Tool call reconciliation",
|
||||
@@ -2271,6 +2273,9 @@
|
||||
"role": "Role",
|
||||
"defaultRole": "Default",
|
||||
"roleHint": "Select a role; all tasks will be executed using that role's configuration (prompt and tools).",
|
||||
"project": "Project",
|
||||
"projectNone": "(Unbound)",
|
||||
"projectHint": "Optionally bind this queue to a project; leave empty to keep it unbound.",
|
||||
"agentMode": "Agent mode",
|
||||
"agentModeSingle": "Single-agent (ReAct)",
|
||||
"agentModeMulti": "Multi-agent (Eino)",
|
||||
|
||||
@@ -459,6 +459,8 @@
|
||||
"einoAgentReplyTitle": "子代理回复",
|
||||
"einoStreamErrorTitle": "⚠️ Eino 流式中断({{agent}})",
|
||||
"einoStreamErrorMessage": "流式读取异常,系统将按策略重试或结束。",
|
||||
"einoRunRetryTitle": "🔁 临时错误重试",
|
||||
"einoRunRetryErrorDetail": "具体报错",
|
||||
"iterationLimitReachedTitle": "⛔ 达到迭代上限",
|
||||
"iterationLimitReachedMessage": "已达到最大迭代次数,任务已停止继续自动迭代。",
|
||||
"einoPendingOrphanedTitle": "🧹 工具调用收尾补偿",
|
||||
@@ -2260,6 +2262,9 @@
|
||||
"role": "角色",
|
||||
"defaultRole": "默认",
|
||||
"roleHint": "选择一个角色,所有任务将使用该角色的配置(提示词和工具)执行。",
|
||||
"project": "所属项目",
|
||||
"projectNone": "(未绑定)",
|
||||
"projectHint": "可为队列绑定项目;留空则不绑定项目上下文。",
|
||||
"agentMode": "代理模式",
|
||||
"agentModeSingle": "单代理(ReAct)",
|
||||
"agentModeMulti": "多代理(Eino)",
|
||||
|
||||
@@ -2479,6 +2479,20 @@ function renderProcessDetails(messageId, processDetails) {
|
||||
itemTitle = agPx + execLine;
|
||||
} else if (eventType === 'eino_agent_reply') {
|
||||
itemTitle = agPx + '💬 ' + (typeof window.t === 'function' ? window.t('chat.einoAgentReplyTitle') : '子代理回复');
|
||||
} else if (eventType === 'eino_run_retry') {
|
||||
itemTitle = typeof window.t === 'function'
|
||||
? window.t('chat.einoRunRetryTitle')
|
||||
: '🔁 临时错误重试';
|
||||
const errRaw = data && data.error != null ? String(data.error).trim() : '';
|
||||
if (errRaw) {
|
||||
const detailLabel = typeof window.t === 'function'
|
||||
? window.t('chat.einoRunRetryErrorDetail')
|
||||
: '错误详情';
|
||||
if (!title || String(title).indexOf(errRaw) === -1) {
|
||||
const merged = title ? (String(title) + '\n' + detailLabel + ':' + errRaw) : (detailLabel + ':' + errRaw);
|
||||
detail.message = merged;
|
||||
}
|
||||
}
|
||||
} else if (eventType === 'knowledge_retrieval') {
|
||||
itemTitle = '📚 ' + (typeof window.t === 'function' ? window.t('chat.knowledgeRetrieval') : '知识检索');
|
||||
} else if (eventType === 'error') {
|
||||
|
||||
@@ -1271,6 +1271,22 @@ function mergeMcpExecutionIDLists(prev, next) {
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatEinoRunRetryMessage(message, data) {
|
||||
const d = data && typeof data === 'object' ? data : {};
|
||||
const base = String(message || '').trim();
|
||||
const errRaw = d.error != null ? String(d.error).trim() : '';
|
||||
if (!errRaw) {
|
||||
return base;
|
||||
}
|
||||
const detailLabel = typeof window.t === 'function'
|
||||
? window.t('chat.einoRunRetryErrorDetail')
|
||||
: '错误详情';
|
||||
if (base && base.indexOf(errRaw) !== -1) {
|
||||
return base;
|
||||
}
|
||||
return base ? (base + '\n' + detailLabel + ':' + errRaw) : (detailLabel + ':' + errRaw);
|
||||
}
|
||||
|
||||
// 处理流式事件
|
||||
function handleStreamEvent(event, progressElement, progressId,
|
||||
getAssistantId, setAssistantId, getMcpIds, setMcpIds) {
|
||||
@@ -1582,6 +1598,20 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
break;
|
||||
}
|
||||
|
||||
case 'eino_run_retry': {
|
||||
const d = event.data || {};
|
||||
const title = typeof window.t === 'function'
|
||||
? window.t('chat.einoRunRetryTitle')
|
||||
: '🔁 临时错误重试';
|
||||
const msg = formatEinoRunRetryMessage(event.message, d);
|
||||
addTimelineItem(timeline, 'warning', {
|
||||
title: title,
|
||||
message: msg,
|
||||
data: d
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'iteration_limit_reached': {
|
||||
addTimelineItem(timeline, 'warning', {
|
||||
title: typeof window.t === 'function' ? window.t('chat.iterationLimitReachedTitle') : '⛔ 达到迭代上限',
|
||||
@@ -2966,6 +2996,11 @@ function addTimelineItem(timeline, type, options) {
|
||||
${escapeHtml(options.message || taskCancelledLabel)}
|
||||
</div>
|
||||
`;
|
||||
} else if (type === 'warning' && options.message) {
|
||||
const streamBody = typeof formatTimelineStreamBody === 'function'
|
||||
? formatTimelineStreamBody(options.message, options.data)
|
||||
: options.message;
|
||||
content += `<div class="timeline-item-content">${formatMarkdown(streamBody)}</div>`;
|
||||
} else if (type === 'progress' && options.message) {
|
||||
content += `<div class="timeline-item-content timeline-eino-trace"><pre class="tool-result">${escapeHtml(options.message)}</pre></div>`;
|
||||
} else if (type === 'user_interrupt_continue' && options.message) {
|
||||
|
||||
+39
-1
@@ -812,12 +812,44 @@ const batchQueuesState = {
|
||||
totalPages: 1
|
||||
};
|
||||
|
||||
async function refreshBatchProjectSelectOptions() {
|
||||
const projectSelect = document.getElementById('batch-queue-project-id');
|
||||
if (!projectSelect) return;
|
||||
|
||||
const noneLabel = _t('batchImportModal.projectNone');
|
||||
projectSelect.innerHTML = `<option value="">${escapeHtml(noneLabel)}</option>`;
|
||||
|
||||
try {
|
||||
const response = await apiFetch('/api/projects?status=active&limit=200');
|
||||
if (!response.ok) {
|
||||
throw new Error(_t('projects.loadProjectsFailed'));
|
||||
}
|
||||
const projects = await response.json();
|
||||
const list = Array.isArray(projects) ? projects : [];
|
||||
const activeProjectId = typeof getActiveProjectId === 'function' ? getActiveProjectId() || '' : '';
|
||||
|
||||
list.forEach((project) => {
|
||||
if (!project || !project.id) return;
|
||||
const option = document.createElement('option');
|
||||
option.value = project.id;
|
||||
option.textContent = project.name || project.id;
|
||||
if (activeProjectId && project.id === activeProjectId) {
|
||||
option.selected = true;
|
||||
}
|
||||
projectSelect.appendChild(option);
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('加载项目列表失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示新建任务模态框
|
||||
async function showBatchImportModal() {
|
||||
const modal = document.getElementById('batch-import-modal');
|
||||
const input = document.getElementById('batch-tasks-input');
|
||||
const titleInput = document.getElementById('batch-queue-title');
|
||||
const roleSelect = document.getElementById('batch-queue-role');
|
||||
const projectSelect = document.getElementById('batch-queue-project-id');
|
||||
const agentModeSelect = document.getElementById('batch-queue-agent-mode');
|
||||
const scheduleModeSelect = document.getElementById('batch-queue-schedule-mode');
|
||||
const cronExprInput = document.getElementById('batch-queue-cron-expr');
|
||||
@@ -831,6 +863,9 @@ async function showBatchImportModal() {
|
||||
if (roleSelect) {
|
||||
roleSelect.value = '';
|
||||
}
|
||||
if (projectSelect) {
|
||||
projectSelect.value = '';
|
||||
}
|
||||
if (agentModeSelect) {
|
||||
agentModeSelect.value = 'single';
|
||||
}
|
||||
@@ -872,6 +907,7 @@ async function showBatchImportModal() {
|
||||
console.error('加载角色列表失败:', error);
|
||||
}
|
||||
}
|
||||
await refreshBatchProjectSelectOptions();
|
||||
|
||||
modal.style.display = 'block';
|
||||
input.focus();
|
||||
@@ -935,6 +971,7 @@ async function createBatchQueue() {
|
||||
const input = document.getElementById('batch-tasks-input');
|
||||
const titleInput = document.getElementById('batch-queue-title');
|
||||
const roleSelect = document.getElementById('batch-queue-role');
|
||||
const projectSelect = document.getElementById('batch-queue-project-id');
|
||||
const agentModeSelect = document.getElementById('batch-queue-agent-mode');
|
||||
const scheduleModeSelect = document.getElementById('batch-queue-schedule-mode');
|
||||
const cronExprInput = document.getElementById('batch-queue-cron-expr');
|
||||
@@ -959,6 +996,7 @@ async function createBatchQueue() {
|
||||
|
||||
// 获取角色(可选,空字符串表示默认角色)
|
||||
const role = roleSelect ? roleSelect.value || '' : '';
|
||||
const projectId = projectSelect ? (projectSelect.value || '').trim() : '';
|
||||
const rawMode = agentModeSelect ? agentModeSelect.value : 'single';
|
||||
const agentMode = isBatchQueueAgentMode(rawMode) ? rawMode : 'single';
|
||||
const scheduleMode = scheduleModeSelect ? (scheduleModeSelect.value === 'cron' ? 'cron' : 'manual') : 'manual';
|
||||
@@ -987,7 +1025,7 @@ async function createBatchQueue() {
|
||||
scheduleMode,
|
||||
cronExpr,
|
||||
executeNow,
|
||||
projectId: typeof getActiveProjectId === 'function' ? getActiveProjectId() || '' : '',
|
||||
projectId,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -3678,6 +3678,13 @@
|
||||
</select>
|
||||
<div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.roleHint">选择一个角色,所有任务将使用该角色的配置(提示词和工具)执行。</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="batch-queue-project-id" data-i18n="batchImportModal.project">所属项目</label>
|
||||
<select id="batch-queue-project-id" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
|
||||
<option value="" data-i18n="batchImportModal.projectNone">(未绑定)</option>
|
||||
</select>
|
||||
<div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.projectHint">可为队列绑定项目;留空则不绑定项目上下文。</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="batch-queue-agent-mode" data-i18n="batchImportModal.agentMode">代理模式</label>
|
||||
<select id="batch-queue-agent-mode" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
|
||||
|
||||
Reference in New Issue
Block a user