fix: writing mode uses chat search then pipeline write only

Keep deep_research_report as a write-only deliverable from conversation materials, block post-success rewrite loops with a summary nudge, fill thin/empty pools from model knowledge, and open the sandbox only on real report.md content.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
董宏凯andCursor committed 2026-08-30 12:41:04 +08:00
1 parent 9afb9750e5
commit 49c01cb72b
20 files changed
+1449 -381

No files matched your search

+8 -10
View File
@@ -45,6 +45,7 @@ import { stopActiveThreadBeforeClarificationReply, stopThreadRun, useThreadStrea
import { useResearchWritingFeed } from "@/core/threads/use-research-writing-feed";
import { clearResearchReportStream } from "@/core/threads/use-research-report-stream";
import { textOfMessage } from "@/core/threads/utils";
import { resolveWritingModeReportPath } from "@/core/threads/writing-mode";
import { OptType, writeYLog } from "@/core/log/y-log";
import {
Select,
@@ -612,16 +613,13 @@ export default function AgentChatPage({
} as typeof displayThread;
}, [displayThread, showReportImportCard, taskId, threadId]);
// 写作模式续写轮:已有 md 产物(report.md 已生成)时回传 writing_artifact_path,
// 后端据此走「直接编辑画布」分支而不是再次挂载深度研究写报告管线(与
// ChatPage 的回传逻辑对齐)。
const writingArtifactPath = useMemo(() => {
const isMarkdown = (path: string | null | undefined) =>
!!path && /\.(md|markdown)(?:$|[?#])/i.test(path);
return [...(thread.values.artifacts ?? [])]
.reverse()
.find((path) => isMarkdown(path));
}, [thread.values.artifacts]);
// 写作模式续写轮:仅当已有写作模式产物 report.md 时回传 writing_artifact_path,
// 后端据此走「直接编辑画布」分支而不是再次挂载深度研究写报告管线。其它 leftover
// .md 不得跳过管线(与 ChatPage 对齐)。
const writingArtifactPath = useMemo(
() => resolveWritingModeReportPath(thread.values.artifacts),
[thread.values.artifacts],
);
// ── 「模板数据转换器」对话页专属调试入口(仅此 agent)──────────────────────────
// 选一个页面模板,问答跑完后点「渲染预览」:取最近一条 AI 回复里的 JSON 填进模板,
+6 -10
View File
@@ -63,6 +63,7 @@ import {
import { useThreadStream, stopActiveThreadBeforeClarificationReply } from "@/core/threads/hooks";
import { useResearchWritingFeed } from "@/core/threads/use-research-writing-feed";
import { clearResearchReportStream } from "@/core/threads/use-research-report-stream";
import { resolveWritingModeReportPath } from "@/core/threads/writing-mode";
import { queueLlmWikiConversationDeposit } from "@/core/llmwiki/conversation-deposit";
import { useSingleRoundRagMessages } from "@/core/threads/use-single-round-rag";
import { useMultiRoundRagMessages } from "@/core/threads/use-multi-round-rag";
@@ -354,16 +355,11 @@ export default function ChatPage() {
researchDisplayThread,
]);
const writingArtifactPath = useMemo(() => {
const isMarkdown = (path: string | null | undefined) =>
!!path && /\.(md|markdown)(?:$|[?#])/i.test(path);
if (isMarkdown(selectedArtifact)) {
return selectedArtifact ?? undefined;
}
return [...(thread.values.artifacts ?? [])]
.reverse()
.find((path) => isMarkdown(path));
}, [selectedArtifact, thread.values.artifacts]);
const writingArtifactPath = useMemo(
() =>
resolveWritingModeReportPath(thread.values.artifacts, selectedArtifact),
[selectedArtifact, thread.values.artifacts],
);
const handleSubmit = useCallback(
(message: PromptInputMessage) => {
+6 -10
View File
@@ -42,6 +42,7 @@ import {
import { usePluginManagementSettings } from "@/core/system-settings/hooks";
import { stopActiveThreadBeforeClarificationReply, useThreadStream } from "@/core/threads/hooks";
import { textOfMessage } from "@/core/threads/utils";
import { resolveWritingModeReportPath } from "@/core/threads/writing-mode";
import { env } from "@/env";
import { cn } from "@/lib/utils";
import {
@@ -285,16 +286,11 @@ export default function IframeChatPage() {
threadMetadataAgentId,
]);
const writingArtifactPath = useMemo(() => {
const isMarkdown = (path: string | null | undefined) =>
!!path && /\.(md|markdown)(?:$|[?#])/i.test(path);
if (isMarkdown(selectedArtifact)) {
return selectedArtifact ?? undefined;
}
return [...(thread.values.artifacts ?? [])]
.reverse()
.find((path) => isMarkdown(path));
}, [selectedArtifact, thread.values.artifacts]);
const writingArtifactPath = useMemo(
() =>
resolveWritingModeReportPath(thread.values.artifacts, selectedArtifact),
[selectedArtifact, thread.values.artifacts],
);
const handleSubmit = useCallback(
(