Merge branch 'ji' into master

This commit is contained in:
吉鑫升 committed 2026-06-18 19:24:03 +08:00
commit 179a3f2b2f
1 file changed
+20 -12
+20 -12
View File
@@ -85,8 +85,11 @@ export default function AgentChatPage({
taskBind && !taskGate && taskContext && taskContext.agentId === agent_id
? (taskContext.openingText?.trim() ?? "")
: "";
// 纯绑定每次进入新建对话都自动发一次开场信息;ref 防止同一新建会话内重复发出。
const taskAutoSentRef = useRef(false);
// 纯绑定每次进入「新建对话」自动发一次开场信息。用「武装」标志去重,而不是绑定到 threadId——
// 新建态首帧 useThreadChat 会把 threadId 从 useState 初值换成新 uuid(抖动),若用 threadId 做
// 去重,会被误判成「又一个新会话」而重复发送(表现为「发了两次、开始回答后又变回一个」)。
// 「武装」只在会话真正创建完成(isNewThread 落回 false)后才重置,故对 threadId 抖动免疫。
const autoSentArmedRef = useRef(true);
// If ChatPage stashed an opening message for this agent, skip the landing
// screen on first render so the user doesn't see a flash of the welcome UI
@@ -123,12 +126,16 @@ export default function AgentChatPage({
useEffect(() => {
if (isNewThread) {
setHasStartedConversation(hasPendingForThisAgent() || !!taskAutoSendText);
// 进入新建对话:允许纯绑定再次自动发出开场信息。
taskAutoSentRef.current = false;
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isNewThread, threadId, agent_id]);
// 会话真正创建完成(isNewThread 落回 false)后重新「武装」,让下一次「新建对话」能再自动发一次。
// 不依赖 threadId,故新建态首帧的 threadId 抖动不会误触发重复发送。
useEffect(() => {
if (!isNewThread) autoSentArmedRef.current = true;
}, [isNewThread]);
const { showNotification } = useNotification();
const [thread, sendMessage, , streamThreadId] = useThreadStream({
threadId: isNewThread ? undefined : threadId,
@@ -227,19 +234,20 @@ export default function AgentChatPage({
handleSubmit({ text: pending.text, files: [] });
}, [agent_id, threadId, isNewThread, handleSubmit]);
// 纯绑定任务深链(3qfx/xdfx,无闸门):进入新建对话即自动发出任务开场信息。
// 每次新建对话都带(与 rwfx 闸门「开始问答」发出等价);ref 防止同一会话内重复发出。
// 纯绑定任务深链(3qfx/xdfx,无闸门):进入新建对话即自动发出任务开场信息(每个新建会话恰好一次)。
//
// 必须等 `streamThreadId == null`(底层 stream 已切到全新线程)才发:从已有会话点「新建对话」时,
// `isNewThread` 先翻 true,但 useThreadStream 的 onStreamThreadId 要慢一帧才重置为 null。
// 若在那一帧就 submit,hook 仍绑定上一个会话,submit 的 threadId 选项被忽略 → 开场信息发进
// 上一个对话(表现为「一直在同一个聊天框里发消息」)。等它归零再发即落到新建线程。
// 两道守卫缺一不可:
// 1) `streamThreadId == null`:等底层 stream 真正切到全新线程再发。从已有会话点「新建对话」时
// isNewThread 先翻 true,但 onStreamThreadId 慢一帧才归零;若那一帧就 submit,hook 仍绑定上一个
// 会话(submit 的 threadId 选项仅在 hook 线程为空时生效)→ 开场信息发进旧对话。
// 2) `autoSentArmedRef`:本轮新建会话是否还「待发」。只在会话创建完成(isNewThread→false)后重置,
// 不受 threadId 抖动影响,避免同一个新建会话里重复发出。
useEffect(() => {
if (!taskAutoSendText) return;
if (!isNewThread) return;
if (streamThreadId != null) return;
if (taskAutoSentRef.current) return;
taskAutoSentRef.current = true;
if (!autoSentArmedRef.current) return;
autoSentArmedRef.current = false;
handleSubmit({ text: taskAutoSendText, files: [] });
}, [taskAutoSendText, isNewThread, streamThreadId, handleSubmit]);