mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:40:43 +00:00
fix: address markdown preview follow-ups
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
export {
|
export {
|
||||||
DEFAULT_AI_SNAPSHOT_MAX_CHARS,
|
DEFAULT_AI_SNAPSHOT_MAX_CHARS,
|
||||||
|
DEFAULT_BROWSER_ACTION_TIMEOUT_MS,
|
||||||
DEFAULT_BROWSER_DEFAULT_PROFILE_NAME,
|
DEFAULT_BROWSER_DEFAULT_PROFILE_NAME,
|
||||||
DEFAULT_BROWSER_EVALUATE_ENABLED,
|
DEFAULT_BROWSER_EVALUATE_ENABLED,
|
||||||
DEFAULT_OPENCLAW_BROWSER_COLOR,
|
DEFAULT_OPENCLAW_BROWSER_COLOR,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import { DEFAULT_UPLOAD_DIR } from "./paths.js";
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
DEFAULT_AI_SNAPSHOT_MAX_CHARS,
|
DEFAULT_AI_SNAPSHOT_MAX_CHARS,
|
||||||
|
DEFAULT_BROWSER_ACTION_TIMEOUT_MS,
|
||||||
DEFAULT_BROWSER_DEFAULT_PROFILE_NAME,
|
DEFAULT_BROWSER_DEFAULT_PROFILE_NAME,
|
||||||
DEFAULT_BROWSER_EVALUATE_ENABLED,
|
DEFAULT_BROWSER_EVALUATE_ENABLED,
|
||||||
DEFAULT_OPENCLAW_BROWSER_COLOR,
|
DEFAULT_OPENCLAW_BROWSER_COLOR,
|
||||||
|
|||||||
@@ -263,7 +263,9 @@ describe("gateway update.run", () => {
|
|||||||
);
|
);
|
||||||
const res = await onceMessage(ws, (o) => o.type === "res" && o.id === id);
|
const res = await onceMessage(ws, (o) => o.type === "res" && o.id === id);
|
||||||
expect(res.ok).toBe(true);
|
expect(res.ok).toBe(true);
|
||||||
expect(updateMock).toHaveBeenCalledOnce();
|
await vi.waitFor(() => {
|
||||||
|
expect(updateMock).toHaveBeenCalledOnce();
|
||||||
|
}, FAST_WAIT_OPTS);
|
||||||
} finally {
|
} finally {
|
||||||
process.off("SIGUSR1", sigusr1);
|
process.off("SIGUSR1", sigusr1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ const BROWSER_HELPER_EXPORT_PARITY_CONTRACTS: readonly BrowserHelperExportParity
|
|||||||
extensionPath: "extensions/browser/browser-profiles.ts",
|
extensionPath: "extensions/browser/browser-profiles.ts",
|
||||||
expectedExports: [
|
expectedExports: [
|
||||||
"DEFAULT_AI_SNAPSHOT_MAX_CHARS",
|
"DEFAULT_AI_SNAPSHOT_MAX_CHARS",
|
||||||
|
"DEFAULT_BROWSER_ACTION_TIMEOUT_MS",
|
||||||
"DEFAULT_BROWSER_DEFAULT_PROFILE_NAME",
|
"DEFAULT_BROWSER_DEFAULT_PROFILE_NAME",
|
||||||
"DEFAULT_BROWSER_EVALUATE_ENABLED",
|
"DEFAULT_BROWSER_EVALUATE_ENABLED",
|
||||||
"DEFAULT_OPENCLAW_BROWSER_COLOR",
|
"DEFAULT_OPENCLAW_BROWSER_COLOR",
|
||||||
|
|||||||
@@ -303,10 +303,14 @@ export function renderToolPreview(
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildSidebarContent(value: string): SidebarContent {
|
export function buildSidebarContent(
|
||||||
|
value: string,
|
||||||
|
options?: { rawText?: string | null },
|
||||||
|
): SidebarContent {
|
||||||
return {
|
return {
|
||||||
kind: "markdown",
|
kind: "markdown",
|
||||||
content: value,
|
content: value,
|
||||||
|
...(options?.rawText ? { rawText: options.rawText } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export type MarkdownSidebarContent = {
|
export type MarkdownSidebarContent = {
|
||||||
kind: "markdown";
|
kind: "markdown";
|
||||||
content: string;
|
content: string;
|
||||||
|
rawText?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CanvasSidebarContent = {
|
export type CanvasSidebarContent = {
|
||||||
|
|||||||
@@ -47,6 +47,28 @@ function getExtensionLabel(fileName: string) {
|
|||||||
return ext ? `${ext.toUpperCase()} Preview` : "Preview";
|
return ext ? `${ext.toUpperCase()} Preview` : "Preview";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatWorkspaceRelativePath(filePath: string, workspace: string | null | undefined) {
|
||||||
|
const normalizedPath = filePath.trim();
|
||||||
|
const normalizedWorkspace = workspace?.trim();
|
||||||
|
if (!normalizedPath) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (normalizedWorkspace && normalizedPath === normalizedWorkspace) {
|
||||||
|
return ".";
|
||||||
|
}
|
||||||
|
if (normalizedWorkspace && normalizedPath.startsWith(`${normalizedWorkspace}/`)) {
|
||||||
|
return normalizedPath.slice(normalizedWorkspace.length + 1) || ".";
|
||||||
|
}
|
||||||
|
const pathParts = normalizedPath.split(/[\\/]+/);
|
||||||
|
for (let index = pathParts.length - 1; index >= 0; index -= 1) {
|
||||||
|
const pathPart = pathParts[index];
|
||||||
|
if (pathPart) {
|
||||||
|
return pathPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return normalizedPath;
|
||||||
|
}
|
||||||
|
|
||||||
function toDomId(value: string) {
|
function toDomId(value: string) {
|
||||||
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
||||||
return normalized.replace(/^-+|-+$/g, "") || "preview";
|
return normalized.replace(/^-+|-+$/g, "") || "preview";
|
||||||
@@ -413,6 +435,9 @@ export function renderAgentFiles(params: {
|
|||||||
const draftByteSize = formatBytes(new TextEncoder().encode(draft).length);
|
const draftByteSize = formatBytes(new TextEncoder().encode(draft).length);
|
||||||
const draftWordCount = countWords(draft);
|
const draftWordCount = countWords(draft);
|
||||||
const draftLineCount = countLines(draft);
|
const draftLineCount = countLines(draft);
|
||||||
|
const activePathLabel = activeEntry
|
||||||
|
? formatWorkspaceRelativePath(activeEntry.path, list?.workspace)
|
||||||
|
: "";
|
||||||
const previewTitleId = activeEntry ? `agent-file-preview-title-${toDomId(activeEntry.name)}` : "";
|
const previewTitleId = activeEntry ? `agent-file-preview-title-${toDomId(activeEntry.name)}` : "";
|
||||||
const previewStatusLabel = activeEntry?.missing
|
const previewStatusLabel = activeEntry?.missing
|
||||||
? "Will Create on Save"
|
? "Will Create on Save"
|
||||||
@@ -574,7 +599,7 @@ export function renderAgentFiles(params: {
|
|||||||
${activeEntry.name}
|
${activeEntry.name}
|
||||||
</div>
|
</div>
|
||||||
<div class="md-preview-dialog__path mono" translate="no">
|
<div class="md-preview-dialog__path mono" translate="no">
|
||||||
${activeEntry.path}
|
${activePathLabel}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ describe("renderAgentFiles", () => {
|
|||||||
|
|
||||||
expect(container.querySelector(".md-preview-dialog__reader.sidebar-markdown")).not.toBeNull();
|
expect(container.querySelector(".md-preview-dialog__reader.sidebar-markdown")).not.toBeNull();
|
||||||
expect(container.querySelector(".md-preview-dialog__path")?.textContent?.trim()).toBe(
|
expect(container.querySelector(".md-preview-dialog__path")?.textContent?.trim()).toBe(
|
||||||
"/tmp/workspace/USER.md",
|
"USER.md",
|
||||||
);
|
);
|
||||||
expect(container.querySelector(".md-preview-dialog__chip strong")?.textContent).toBe(
|
expect(container.querySelector(".md-preview-dialog__chip strong")?.textContent).toBe(
|
||||||
"Saved Preview",
|
"Saved Preview",
|
||||||
|
|||||||
@@ -111,6 +111,42 @@ describe("renderChat", () => {
|
|||||||
cleanupChatModuleState();
|
cleanupChatModuleState();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps markdown raw text toggles idempotent", () => {
|
||||||
|
const container = document.createElement("div");
|
||||||
|
const onOpenSidebar = vi.fn();
|
||||||
|
const rawMarkdown = "```ts\nconst value = 1;\n```";
|
||||||
|
|
||||||
|
render(
|
||||||
|
renderChat(
|
||||||
|
createProps({
|
||||||
|
sidebarOpen: true,
|
||||||
|
sidebarContent: {
|
||||||
|
kind: "markdown",
|
||||||
|
content: `\`\`\`\n${rawMarkdown}\n\`\`\``,
|
||||||
|
rawText: rawMarkdown,
|
||||||
|
},
|
||||||
|
stream: null,
|
||||||
|
streamStartedAt: null,
|
||||||
|
onCloseSidebar: () => undefined,
|
||||||
|
onOpenSidebar,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
container,
|
||||||
|
);
|
||||||
|
|
||||||
|
const rawButton = Array.from(container.querySelectorAll<HTMLButtonElement>("button")).find(
|
||||||
|
(button) => button.textContent?.includes("View Raw Text"),
|
||||||
|
);
|
||||||
|
rawButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||||
|
|
||||||
|
expect(rawButton).not.toBeNull();
|
||||||
|
expect(onOpenSidebar).toHaveBeenCalledWith({
|
||||||
|
kind: "markdown",
|
||||||
|
content: `\`\`\`\n${rawMarkdown}\n\`\`\``,
|
||||||
|
rawText: rawMarkdown,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("renders configured assistant text avatars in transcript groups", () => {
|
it("renders configured assistant text avatars in transcript groups", () => {
|
||||||
const container = document.createElement("div");
|
const container = document.createElement("div");
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ function getPinnedMessages(sessionKey: string): PinnedMessages {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toPlainTextCodeFence(value: string, language = ""): string {
|
||||||
|
const fenceHeader = language ? `\`\`\`${language}` : "```";
|
||||||
|
return `${fenceHeader}\n${value}\n\`\`\``;
|
||||||
|
}
|
||||||
|
|
||||||
function getDeletedMessages(sessionKey: string): DeletedMessages {
|
function getDeletedMessages(sessionKey: string): DeletedMessages {
|
||||||
return getOrCreateSessionCacheValue(
|
return getOrCreateSessionCacheValue(
|
||||||
deletedMessagesMap,
|
deletedMessagesMap,
|
||||||
@@ -1129,14 +1134,17 @@ export function renderChat(props: ChatProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (props.sidebarContent.kind === "markdown") {
|
if (props.sidebarContent.kind === "markdown") {
|
||||||
|
const rawText = props.sidebarContent.rawText ?? props.sidebarContent.content;
|
||||||
props.onOpenSidebar(
|
props.onOpenSidebar(
|
||||||
buildSidebarContent(`\`\`\`\n${props.sidebarContent.content}\n\`\`\``),
|
buildSidebarContent(toPlainTextCodeFence(rawText), { rawText }),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (props.sidebarContent.rawText?.trim()) {
|
if (props.sidebarContent.rawText?.trim()) {
|
||||||
props.onOpenSidebar(
|
props.onOpenSidebar(
|
||||||
buildSidebarContent(`\`\`\`json\n${props.sidebarContent.rawText}\n\`\`\``),
|
buildSidebarContent(
|
||||||
|
toPlainTextCodeFence(props.sidebarContent.rawText, "json"),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user