fix: 停止迁移复活默认模型供应商/模型;AI聊天媒体生成改为异步(修复视频请求失败)

- migrations/002_init_data.sql: 移除 model_providers/models 的 INSERT IGNORE 种子,重启容器不再复活 deepseek/openai/通义千问等默认供应商与模型,改由用户在后台大模型库自行维护
- chat.py: 图像/视频生成分支改为立即返回占位(generating=true),后台 asyncio 任务轮询 AGNES 并回写消息内容,避免最长 5 分钟同步轮询阻塞 HTTP 请求导致前端「发送失败:请求失败」
- ChatPage.tsx: 发送后若 assistant_message.generating,每 3s 轮询 getMessages 直至内容更新;页面刷新时若仍有「⏳」占位继续轮询;卸载清理定时器
This commit is contained in:
QihuAI Design committed 2026-07-14 21:48:39 +08:00
1 parent b7f76c3e92
commit 5d1370156e
3 files changed
+121 -21

No files matched your search

+64
View File
@@ -565,8 +565,67 @@ const ChatPage: React.FC = () => {
}
};
loadMessages();
// 页面刷新时若仍有「⏳」占位的媒体消息,继续轮询后端回写结果
mapped.forEach((m) => {
if (m.role === 'assistant' && typeof m.content === 'string' && m.content.startsWith('⏳')) {
startMediaPolling(id, m.id);
}
});
}, [id]);
// 媒体(图像/视频)异步生成轮询:后端先返回「⏳」占位,前端定时拉取该消息最新内容并回写
const pollMediaRef = useRef<Record<string, ReturnType<typeof setInterval> | null>>({});
const stopMediaPolling = (msgId: string) => {
const t = pollMediaRef.current[msgId];
if (t) {
clearInterval(t);
pollMediaRef.current[msgId] = null;
}
};
const startMediaPolling = (convId: string, msgId: string) => {
if (pollMediaRef.current[msgId]) return; // 已在轮询
let ticks = 0;
const timer = setInterval(async () => {
ticks += 1;
try {
const res = await chatAPI.getMessages(convId);
const msgs: any[] = unwrapList(res);
const updated = msgs.find((m: any) => m.id === msgId);
if (!updated) {
stopMediaPolling(msgId);
return;
}
const content: string = updated.content || '';
if (content.startsWith('⏳')) {
if (ticks > 120) stopMediaPolling(msgId); // ~6 分钟兜底
return;
}
// 生成完成:回写消息内容
setMessages(prev => prev.map(m => m.id === msgId ? {
...m,
content,
tokenUsed: updated.tokenUsed ?? updated.token_used ?? m.tokenUsed,
createdAt: updated.createdAt || updated.created_at || m.createdAt,
used_skills: updated.usedSkills ?? updated.used_skills ?? m.used_skills,
} : m));
stopMediaPolling(msgId);
} catch (e) {
if (ticks > 120) stopMediaPolling(msgId); // 网络异常兜底
}
}, 3000);
pollMediaRef.current[msgId] = timer;
};
// 卸载时清理所有轮询定时器
useEffect(() => {
return () => {
Object.values(pollMediaRef.current).forEach(t => t && clearInterval(t));
};
}, []);
// Load knowledge bases, agents, skills for attachment dropdowns
useEffect(() => {
knowledgeAPI.getBases().then((res: any) => {
@@ -821,6 +880,11 @@ const ChatPage: React.FC = () => {
return [...filtered, ...newMsgs];
});
// 媒体异步生成:启动轮询,待后端回写后自动刷新
if (data.assistant_message?.generating) {
startMediaPolling(selectedConversation!.id, data.assistant_message.id);
}
// Refresh conversations to update lastMessage
loadConversations();