Add files via upload

This commit is contained in:
公明
2026-05-28 14:34:14 +08:00
committed by GitHub
parent 8a089a826c
commit df531910cf
6 changed files with 105 additions and 1 deletions
+5
View File
@@ -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)",
+5
View File
@@ -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",
+14
View File
@@ -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') {
+35
View File
@@ -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
View File
@@ -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,
}),
});