bug修改
This commit is contained in:
1 parent
910cee9e67
commit
704438b3d2
6 files changed
+278
-36
No files matched your search
@@ -76,6 +76,7 @@ import {
|
||||
useArtifactContent,
|
||||
useUpdateArtifactContent,
|
||||
} from "@/core/artifacts/hooks";
|
||||
import { isWriteFileInFlight } from "@/core/artifacts/write-file-in-flight";
|
||||
import { resolveArtifactURL, urlOfArtifact } from "@/core/artifacts/utils";
|
||||
import {
|
||||
isSandboxStreamPerfEnabled,
|
||||
@@ -308,19 +309,33 @@ export function ArtifactFileDetail({
|
||||
const isSpreadsheetFile = useMemo(() => {
|
||||
return /\.xlsx$/i.test(filepath);
|
||||
}, [filepath]);
|
||||
// 圆桌沙箱:write_file 虚拟预览的 md 在流式结束(thread 非 loading)后,切回真实
|
||||
// artifacts API 加载并允许编辑/保存。流式进行中仍走内存 stub 只读预览;仅
|
||||
// allowVirtualMarkdownEdit 开启的调用方(Step2/Step3 沙箱)生效,主聊天页不受影响。
|
||||
// 仅当「当前这个文件」的 write_file 还没返回 tool result 时才算在写。
|
||||
// 不能用 thread.isLoading:用户协助后的下一轮问答也会 loading,否则会把已写完的
|
||||
// md 从 CodeMirror 拽回巨大 textarea,主线程卡住、聊天变成「发送中然后一口气出来」。
|
||||
const writeFileInFlight = useMemo(() => {
|
||||
if (!isWriteFileVirtual || isImageFile(filepath)) {
|
||||
return false;
|
||||
}
|
||||
return isWriteFileInFlight(thread, filepathFromProps);
|
||||
}, [filepath, filepathFromProps, isWriteFileVirtual, thread.messages]);
|
||||
// 圆桌/主聊天沙箱:write_file 虚拟预览的 md 在该文件写完后切回真实 artifacts API
|
||||
// (可加载 + PATCH 保存)。后续问答轮次的 loading 不再把预览拽回去。
|
||||
const editVirtualMarkdown = useMemo(() => {
|
||||
return (
|
||||
allowVirtualMarkdownEdit &&
|
||||
isWriteFileVirtual &&
|
||||
!isImageFile(filepath) &&
|
||||
!isMock &&
|
||||
!thread.isLoading &&
|
||||
!writeFileInFlight &&
|
||||
checkCodeFile(filepath).language === "markdown"
|
||||
);
|
||||
}, [allowVirtualMarkdownEdit, isWriteFileVirtual, filepath, isMock, thread.isLoading]);
|
||||
}, [
|
||||
allowVirtualMarkdownEdit,
|
||||
isWriteFileVirtual,
|
||||
filepath,
|
||||
isMock,
|
||||
writeFileInFlight,
|
||||
]);
|
||||
/** write_file 流式预览走 tool args 文本;图片等二进制产物始终走 artifacts API;
|
||||
* 圆桌结束后可编辑的 md(editVirtualMarkdown)亦回到真实 API(可加载 + PATCH 保存)。 */
|
||||
const useWriteFileStreaming = useMemo(() => {
|
||||
@@ -377,7 +392,7 @@ export function ArtifactFileDetail({
|
||||
language === "markdown" &&
|
||||
!isSkillFile &&
|
||||
!isMock &&
|
||||
!thread.isLoading &&
|
||||
!writeFileInFlight &&
|
||||
(canEditArtifact || useWriteFileStreaming);
|
||||
const [draftContent, setDraftContent] = useState("");
|
||||
const [hasLocalEdits, setHasLocalEdits] = useState(false);
|
||||
@@ -406,7 +421,7 @@ export function ArtifactFileDetail({
|
||||
? draftContent
|
||||
: (content ?? ""));
|
||||
const streamPerfEnabled = isSandboxStreamPerfEnabled();
|
||||
const isLiveStreaming = thread.isLoading || documentRewriteActive;
|
||||
const isLiveStreaming = writeFileInFlight || documentRewriteActive;
|
||||
const sandboxDisplayText = useMemo(() => {
|
||||
const raw = displayContent ?? "";
|
||||
if (disableDesensitize) return raw;
|
||||
@@ -426,7 +441,7 @@ export function ArtifactFileDetail({
|
||||
const isAutoPreviewLanguage =
|
||||
language === "html" || language === "markdown" || language === "mermaid";
|
||||
const isPreviewStreaming =
|
||||
isAutoPreviewLanguage && (thread.isLoading || documentRewriteActive);
|
||||
isAutoPreviewLanguage && (writeFileInFlight || documentRewriteActive);
|
||||
const hasMultipleArtifacts = (artifacts?.length ?? 0) > 1;
|
||||
const fileTypeLabel = useMemo(() => {
|
||||
if (isImageFile(filepath)) return "IMG";
|
||||
@@ -889,7 +904,7 @@ export function ArtifactFileDetail({
|
||||
}
|
||||
|
||||
if (language === "html") {
|
||||
setViewMode(thread.isLoading ? "code" : "preview");
|
||||
setViewMode(writeFileInFlight || documentRewriteActive ? "code" : "preview");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -899,14 +914,20 @@ export function ArtifactFileDetail({
|
||||
}
|
||||
|
||||
setViewMode("code");
|
||||
}, [isPreviewStreaming, isSupportPreview, language, thread.isLoading]);
|
||||
}, [
|
||||
documentRewriteActive,
|
||||
isPreviewStreaming,
|
||||
isSupportPreview,
|
||||
language,
|
||||
writeFileInFlight,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!allowAutoViewSwitch || !isAutoPreviewLanguage) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (thread.isLoading) {
|
||||
if (writeFileInFlight || documentRewriteActive) {
|
||||
setViewMode("code");
|
||||
return;
|
||||
}
|
||||
@@ -918,7 +939,13 @@ export function ArtifactFileDetail({
|
||||
}, 1400);
|
||||
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
}, [allowAutoViewSwitch, isAutoPreviewLanguage, isSupportPreview, thread.isLoading]);
|
||||
}, [
|
||||
allowAutoViewSwitch,
|
||||
documentRewriteActive,
|
||||
isAutoPreviewLanguage,
|
||||
isSupportPreview,
|
||||
writeFileInFlight,
|
||||
]);
|
||||
|
||||
const scrollArtifactToBottom = useCallback(
|
||||
(behavior: ScrollBehavior = "auto") => {
|
||||
@@ -1015,13 +1042,13 @@ export function ArtifactFileDetail({
|
||||
}, [filepath, threadId, isMock, isCodeFile, isSpreadsheetFile, isWriteFileVirtual, publicShareCode]);
|
||||
|
||||
const handlePauseAutoScroll = useCallback(() => {
|
||||
if (!thread.isLoading || !autoScrollEnabled) {
|
||||
if (!isLiveStreaming || !autoScrollEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
setAutoScrollEnabled(false);
|
||||
setShowResumeAutoScroll(true);
|
||||
}, [autoScrollEnabled, thread.isLoading]);
|
||||
}, [autoScrollEnabled, isLiveStreaming]);
|
||||
|
||||
const handleResumeAutoScroll = useCallback(() => {
|
||||
setAutoScrollEnabled(true);
|
||||
@@ -1774,7 +1801,7 @@ export function ArtifactFileDetail({
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
isStreaming={thread.isLoading}
|
||||
isStreaming={writeFileInFlight || documentRewriteActive}
|
||||
streamingReadonlyFallback={!canEditArtifact}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user