diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx index 266eef271..fb6e11cbd 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx @@ -67,6 +67,7 @@ export function ConversationModelSelect({ ref, errorPresentation = 'inline', onUnavailable, + onNotice, strengthSection, }: { className?: string; @@ -85,6 +86,13 @@ export function ConversationModelSelect({ errorPresentation?: 'inline' | 'toast'; /** `errorPresentation: 'toast'` 时,对**新出现**的失败消息回调一次(同一条不重复)。 */ onUnavailable?: (message: string) => void; + /** + * 状态文案(「模型列表已刷新」「正在刷新模型列表」「默认模型已停用」等)的浮层通道。 + * + * 只在 `errorPresentation: 'toast'` 时回调,且与失败**分开**:语气不同(状态不是失败)、 + * 去重名额也各算各的。`toast` 模式下没有常驻 `role="status"`,输入区不再被一行状态文字顶高。 + */ + onNotice?: (message: string) => void; /** * 菜单顶部的附加区(Direct 输入盒用来放「思维强度」滑块)。 * @@ -146,6 +154,31 @@ export function ConversationModelSelect({ onUnavailableRef.current?.(error); }, [error, errorPresentation]); + /** + * 状态文案(「模型列表已刷新」「默认模型已停用」等)在 toast 形态下走**另一条**通道: + * 它和失败的语气不同(失败是 error,状态是 neutral),报告也不该占用失败的"同一条只报一次" + * 名额。输入区子树因此不再有常驻 `role="status"`。 + */ + const onNoticeRef = useRef(onNotice); + useEffect(() => { + onNoticeRef.current = onNotice; + }, [onNotice]); + const reportedNoticeRef = useRef(''); + useEffect(() => { + if (errorPresentation !== 'toast') { + return; + } + if (notice === '') { + reportedNoticeRef.current = ''; + return; + } + if (reportedNoticeRef.current === notice) { + return; + } + reportedNoticeRef.current = notice; + onNoticeRef.current?.(notice); + }, [errorPresentation, notice]); + useEffect(() => { mountedRef.current = true; return () => { @@ -493,7 +526,10 @@ export function ConversationModelSelect({ {error && errorPresentation === 'inline' ? ( {error} ) : null} - {notice ? {notice} : null} + {/* 状态文案同理:Direct 输入区不留常驻 `role="status"`,一并交给浮层通道。 */} + {notice && errorPresentation === 'inline' ? ( + {notice} + ) : null}