fix: refine claw markdown composer display
This commit is contained in:
parent
ed63eb77b7
commit
71fd765ebc
@ -2,7 +2,7 @@
|
||||
|
||||
import { useChat } from "@ai-sdk/react";
|
||||
import { DefaultChatTransport } from "ai";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo, type ClipboardEvent as ReactClipboardEvent } from "react";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo, type ClipboardEvent as ReactClipboardEvent, type MouseEvent as ReactMouseEvent } from "react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { createPortal } from "react-dom";
|
||||
@ -1222,6 +1222,86 @@ function extractOpenClawActionsFromMarkdown(content: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function splitOpenClawMarkdownTableCells(line: string) {
|
||||
return String(line || "")
|
||||
.trim()
|
||||
.replace(/^\|/, "")
|
||||
.replace(/\|$/, "")
|
||||
.split(/(?<!\\)\|/)
|
||||
.map((cell) =>
|
||||
cell
|
||||
.replace(/\\\|/g, "|")
|
||||
.replace(/\*\*(.*?)\*\*/g, "$1")
|
||||
.replace(/`([^`]+)`/g, "$1")
|
||||
.replace(/\s+/g, "")
|
||||
.trim()
|
||||
);
|
||||
}
|
||||
|
||||
function isOpenClawRoutingDiagnosticTable(tableLines: string[]) {
|
||||
if (tableLines.length < 3) return false;
|
||||
|
||||
const headerCells = splitOpenClawMarkdownTableCells(tableLines[0] || "");
|
||||
const hasDiagnosticHeader =
|
||||
headerCells.some((cell) => cell.includes("已尝试")) &&
|
||||
headerCells.some((cell) => cell.includes("结果"));
|
||||
if (!hasDiagnosticHeader) return false;
|
||||
|
||||
const bodyText = tableLines
|
||||
.slice(2)
|
||||
.map((line) => splitOpenClawMarkdownTableCells(line).join(" "))
|
||||
.join(" ");
|
||||
|
||||
return (
|
||||
bodyText.includes("标准品类识别") ||
|
||||
bodyText.includes("市场分析准备") ||
|
||||
bodyText.includes("建议示例")
|
||||
);
|
||||
}
|
||||
|
||||
function stripOpenClawLowValueDiagnosticTables(content: string) {
|
||||
const normalized = String(content || "").replace(/\r\n/g, "\n");
|
||||
if (!normalized.includes("|")) return normalized.trim();
|
||||
|
||||
const lines = normalized.split("\n");
|
||||
const keptLines: string[] = [];
|
||||
let inCodeFence = false;
|
||||
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const line = lines[index] || "";
|
||||
if (/^\s*```/.test(line)) {
|
||||
inCodeFence = !inCodeFence;
|
||||
keptLines.push(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
!inCodeFence &&
|
||||
index < lines.length - 1 &&
|
||||
isLikelyMarkdownTableRow(line) &&
|
||||
isMarkdownTableSeparatorRow(lines[index + 1] || "")
|
||||
) {
|
||||
let endIndex = index + 2;
|
||||
while (
|
||||
endIndex < lines.length &&
|
||||
isLikelyMarkdownTableRow(lines[endIndex] || "")
|
||||
) {
|
||||
endIndex += 1;
|
||||
}
|
||||
|
||||
const tableLines = lines.slice(index, endIndex);
|
||||
if (isOpenClawRoutingDiagnosticTable(tableLines)) {
|
||||
index = endIndex - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
keptLines.push(line);
|
||||
}
|
||||
|
||||
return keptLines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
||||
}
|
||||
|
||||
type MarkdownTableBlockRange = {
|
||||
start: number;
|
||||
end: number;
|
||||
@ -11568,6 +11648,35 @@ export function CanvasChatPanel({
|
||||
(selectedSkillTag
|
||||
? `请输入「${selectedSkillTag.name}」相关需求`
|
||||
: "请输入你的设计需求");
|
||||
const clawdEditablePresetPlaceholder =
|
||||
isClawdMode && activeClawdSkillTag
|
||||
? activeClawdSkillTag.placeholder?.trim() || ""
|
||||
: "";
|
||||
const handleClawdPresetPlaceholderDoubleClick = useCallback(
|
||||
(event: ReactMouseEvent<HTMLDivElement>) => {
|
||||
if (isSubmitting || !isClawdMode || !clawdEditablePresetPlaceholder) return;
|
||||
|
||||
const editor = event.currentTarget;
|
||||
if (input.trim() || getComposerPlainTextFromElement(editor)) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
composerUserEditedAtRef.current = Date.now();
|
||||
setInput(clawdEditablePresetPlaceholder);
|
||||
editor.textContent = clawdEditablePresetPlaceholder;
|
||||
editor.focus();
|
||||
|
||||
const selection = window.getSelection();
|
||||
if (!selection) return;
|
||||
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(editor);
|
||||
range.collapse(false);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
},
|
||||
[clawdEditablePresetPlaceholder, input, isClawdMode, isSubmitting]
|
||||
);
|
||||
const detailProductCount = DETAIL_PRODUCT_SLOT_INDEXES.filter((index) => Boolean(detailSlots[index]?.url)).length;
|
||||
const detailModelReady = DETAIL_MODEL_SLOT_INDEX >= 0 ? Boolean(detailSlots[DETAIL_MODEL_SLOT_INDEX]?.url) : false;
|
||||
const detailBundleCount = DETAIL_BUNDLE_SLOT_INDEXES.filter((index) => Boolean(detailSlots[index]?.url)).length;
|
||||
@ -12805,7 +12914,11 @@ export function CanvasChatPanel({
|
||||
const openClawActionsResult = isClawAssistantMessage
|
||||
? extractOpenClawActionsFromMarkdown(textWithoutImages)
|
||||
: { markdown: textWithoutImages, blocks: [] };
|
||||
const textWithoutActions = openClawActionsResult.markdown;
|
||||
const textWithoutActions = isClawAssistantMessage
|
||||
? stripOpenClawLowValueDiagnosticTables(
|
||||
openClawActionsResult.markdown
|
||||
)
|
||||
: openClawActionsResult.markdown;
|
||||
const openClawActionBlocks = openClawActionsResult.blocks;
|
||||
const analysisSection = extractCanvasImageAnalysisSection(textWithoutActions);
|
||||
const plainText = normalizeCanvasAgentText(textWithoutActions);
|
||||
@ -14457,6 +14570,7 @@ export function CanvasChatPanel({
|
||||
: "text-[#1f2328] empty:before:text-[#a8abb2] dark:text-zinc-100 dark:empty:before:text-zinc-500"
|
||||
)}
|
||||
data-placeholder={composerPlaceholder}
|
||||
onDoubleClick={handleClawdPresetPlaceholderDoubleClick}
|
||||
onInput={(e) => {
|
||||
// 从 contenteditable 中提取纯文本(排除附件标签文本)
|
||||
const target = e.target as HTMLDivElement;
|
||||
|
||||
@ -571,10 +571,10 @@ function DownloadableMarkdownTable({
|
||||
<table
|
||||
ref={tableRef}
|
||||
className={cn(
|
||||
"w-max min-w-full table-auto border-collapse text-sm",
|
||||
"[&_td]:min-w-[12rem] [&_td]:align-top [&_td]:whitespace-nowrap",
|
||||
"[&_td:first-child]:min-w-[22rem] [&_th:first-child]:min-w-[22rem]",
|
||||
"[&_th]:min-w-[12rem] [&_th]:whitespace-nowrap",
|
||||
"min-w-full table-auto border-collapse text-sm",
|
||||
"[&_td]:min-w-[10rem] [&_td]:max-w-[24rem] [&_td]:align-top [&_td]:whitespace-normal [&_td]:break-words [&_td]:[overflow-wrap:anywhere] [&_td]:[word-break:break-word]",
|
||||
"[&_td:first-child]:min-w-[12rem] [&_td:first-child]:max-w-[18rem] [&_th:first-child]:min-w-[12rem] [&_th:first-child]:max-w-[18rem]",
|
||||
"[&_th]:min-w-[10rem] [&_th]:max-w-[22rem] [&_th]:whitespace-normal [&_th]:break-words [&_th]:[overflow-wrap:anywhere] [&_th]:[word-break:break-word]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@ -593,7 +593,10 @@ function MarkdownTableCell({
|
||||
}: MarkdownTableCellProps) {
|
||||
return (
|
||||
<td
|
||||
className={cn("min-w-[12rem] align-top !whitespace-nowrap", className)}
|
||||
className={cn(
|
||||
"min-w-[10rem] max-w-[24rem] align-top !whitespace-normal break-words [overflow-wrap:anywhere] [word-break:break-word]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@ -606,7 +609,10 @@ function MarkdownTableHeaderCell({
|
||||
}: MarkdownTableHeaderCellProps) {
|
||||
return (
|
||||
<th
|
||||
className={cn("min-w-[12rem] !whitespace-nowrap", className)}
|
||||
className={cn(
|
||||
"min-w-[10rem] max-w-[22rem] !whitespace-normal break-words [overflow-wrap:anywhere] [word-break:break-word]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user