agent 模式补充文件功能已经实现
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* SSE 连接管理
|
||||
*
|
||||
* 封装 EventSource 的创建、事件注册和 done 事件处理,避免重复代码。
|
||||
*/
|
||||
import { App } from './state.js';
|
||||
import {
|
||||
removeTypingIndicator,
|
||||
setFileProcessing,
|
||||
setFileDone,
|
||||
setFileCached,
|
||||
setFileError,
|
||||
handleLLMStream,
|
||||
addChatMessage,
|
||||
showStatus,
|
||||
} from './chat.js';
|
||||
import { handleAgentEvent } from './agent.js';
|
||||
|
||||
/**
|
||||
* 创建 SSE 连接并返回 EventSource 实例
|
||||
*
|
||||
* @param {string} sessionId - 会话 ID
|
||||
* @param {Object} options - 选项配置
|
||||
* @param {Function} options.onDone - done 事件处理器
|
||||
* @param {boolean} options.handleFileProgress - 是否处理文件进度事件 (默认 true)
|
||||
* @param {boolean} options.handleLLMStream - 是否处理 LLM 流式事件 (默认 true)
|
||||
* @param {boolean} options.handleAgentEvents - 是否处理 Agent 事件 (默认 true)
|
||||
* @returns {EventSource}
|
||||
*/
|
||||
export function createSSEConnection(sessionId, options = {}) {
|
||||
const {
|
||||
onDone,
|
||||
handleFileProgress = true,
|
||||
handleLLMStream: handleStream = true,
|
||||
handleAgentEvents = true,
|
||||
} = options;
|
||||
|
||||
const es = new EventSource(`/api/logs/${sessionId}`);
|
||||
|
||||
es.addEventListener('message', e => {
|
||||
try {
|
||||
const msg = JSON.parse(e.data);
|
||||
|
||||
// 文件进度事件
|
||||
if (handleFileProgress && msg.type === 'file_progress') {
|
||||
const filename = msg.file;
|
||||
switch (msg.status) {
|
||||
case 'processing':
|
||||
setFileProcessing(filename);
|
||||
break;
|
||||
case 'done':
|
||||
setFileDone(filename, msg.summary || {});
|
||||
break;
|
||||
case 'cached':
|
||||
setFileCached(filename);
|
||||
break;
|
||||
case 'error':
|
||||
setFileError(filename, msg.error);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// LLM 流式事件
|
||||
if (handleStream && msg.type === 'llm_stream') {
|
||||
handleLLMStream(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Agent 事件
|
||||
if (handleAgentEvents && msg.type && msg.type.startsWith('agent_')) {
|
||||
handleAgentEvent(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// 完成事件
|
||||
if (msg.type === 'done') {
|
||||
es.close();
|
||||
if (onDone) {
|
||||
onDone(msg.result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
// 普通日志行,忽略
|
||||
}
|
||||
});
|
||||
|
||||
es.onerror = () => {
|
||||
es.close();
|
||||
removeTypingIndicator();
|
||||
App.isProcessing = false;
|
||||
App.processState = 'done';
|
||||
addChatMessage('连接中断,请刷新页面重试', 'error');
|
||||
};
|
||||
|
||||
return es;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 done 事件的通用逻辑 (根据 result 内容更新 UI 状态)
|
||||
*
|
||||
* @param {Object} result - done 事件的结果对象
|
||||
*/
|
||||
export function handleDoneResult(result) {
|
||||
App.isProcessing = false;
|
||||
|
||||
if (App.forceSubmitting) {
|
||||
App.forceSubmitting = false;
|
||||
App.lastProcessedFileCount = App.allFiles.length;
|
||||
if (result.ok) {
|
||||
addChatMessage('提交完成!', 'done');
|
||||
} else {
|
||||
addChatMessage(`提交失败:${result.error || '未知错误'}`, 'error');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.waiting_for_supplement) {
|
||||
App.processState = 'awaiting_supplement';
|
||||
showStatus('信息不完整,请补充上传相关材料');
|
||||
addChatMessage(
|
||||
'您可通过上传区补充文件,或直接输入文字说明补充信息,或输入"直接提交"跳过校验',
|
||||
'system'
|
||||
);
|
||||
} else {
|
||||
App.processState = 'done';
|
||||
App.lastProcessedFileCount = App.allFiles.length;
|
||||
|
||||
if (result.ok) {
|
||||
if (result.agent_ready) {
|
||||
if (result.submit_ok !== false) {
|
||||
addChatMessage('信息完整,已自动提交到财务系统', 'done');
|
||||
} else {
|
||||
addChatMessage(`校验通过但提交失败:${result.submit_error || '未知错误'}`, 'error');
|
||||
}
|
||||
} else if (result.invoice_count) {
|
||||
addChatMessage(`处理完成!共提取 ${result.invoice_count} 张发票数据`, 'done');
|
||||
}
|
||||
} else {
|
||||
addChatMessage(`处理失败:${result.error || '未知错误'}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user