New Lab 2

This commit is contained in:
2026-04-07 16:02:48 -06:00
parent 6bcebd55ee
commit 9f3af49845
65 changed files with 6650 additions and 1553 deletions
+102 -35
View File
@@ -1,16 +1,21 @@
"use client";
import { useEffect, useRef, useState } from "react";
import { Fragment, useEffect, useRef, useState } from "react";
import { Objective5Chat } from "~/components/labs/Objective5Chat";
import { QuantizationGridExplorer } from "~/components/labs/QuantizationGridExplorer";
import { QuantizationExplorer } from "~/components/labs/QuantizationExplorer";
type LabContentProps = {
className: string;
html: string;
};
const cliLanguagePattern = /\b(language-(bash|sh|shell|zsh|console|terminal)|bash|shell|zsh)\b/i;
const cliLanguagePattern =
/\b(language-(bash|sh|shell|zsh|console|terminal)|bash|shell|zsh)\b/i;
const cliCommandPattern =
/(^|\n)\s*(\$|sudo\s|git\s|python3?\s|pip\s|npm\s|pnpm\s|yarn\s|llama-|ollama\s|curl\s|wget\s|apt\s|cd\s|ls\s|cat\s|cp\s|mv\s|chmod\s|make\s)/i;
const promptLanguagePattern = /\b(language-(text|plaintext|md|markdown)|text|plaintext|markdown)\b/i;
const promptLanguagePattern =
/\b(language-(text|plaintext|md|markdown)|text|plaintext|markdown)\b/i;
const promptSignalPattern =
/\b(you are|guidelines|follow these|example|when provided|system prompt|tasked with)\b/i;
@@ -24,9 +29,16 @@ type ZoomedImageState = {
alt: string;
};
const quantizationExplorerToken = "<div data-quantization-explorer></div>";
const quantizationGridExplorerToken =
"<div data-quantization-grid-explorer></div>";
const objective5ChatToken = "<div data-objective5-chat></div>";
function looksLikeCliCommand(commandText: string, className: string) {
if (cliLanguagePattern.test(className)) return true;
return cliCommandPattern.test(commandText) || /--[a-z0-9-]+/i.test(commandText);
return (
cliCommandPattern.test(commandText) || /--[a-z0-9-]+/i.test(commandText)
);
}
function looksLikePromptTextBlock(text: string, className: string) {
@@ -36,7 +48,8 @@ function looksLikePromptTextBlock(text: string, className: string) {
if (!normalizedText) return false;
const lineCount = normalizedText.split("\n").length;
if (promptLanguagePattern.test(className) && normalizedText.length > 80) return true;
if (promptLanguagePattern.test(className) && normalizedText.length > 80)
return true;
if (lineCount >= 4 && promptSignalPattern.test(normalizedText)) return true;
if (lineCount >= 6 && /(^|\n)\s*[*-]\s+/.test(normalizedText)) return true;
return false;
@@ -63,7 +76,9 @@ function parseSettingListItem(item: HTMLLIElement): ParsedSetting | null {
if (!key || key.length > 40) return null;
const text = (item.textContent ?? "").replace(/\s+/g, " ").trim();
const match = new RegExp(`^${escapeRegex(key)}\\s*(?:-||—|:|=)\\s*(.+)$`).exec(text);
const match = new RegExp(
`^${escapeRegex(key)}\\s*(?:-||—|:|=)\\s*(.+)$`,
).exec(text);
if (!match) return null;
const value = (match[1] ?? "").replace(/\s+/g, " ").trim();
@@ -79,17 +94,22 @@ function enhanceSettingsLists(root: HTMLElement) {
for (const list of lists) {
if (list.dataset.settingsEnhanced === "true") continue;
const items = Array.from(list.children).filter((node): node is HTMLLIElement => {
return node.tagName === "LI";
});
const items = Array.from(list.children).filter(
(node): node is HTMLLIElement => {
return node.tagName === "LI";
},
);
if (items.length < 2) continue;
const parsedItems = items.map((item) => parseSettingListItem(item));
if (parsedItems.some((parsedItem) => parsedItem === null)) continue;
const settings = parsedItems as ParsedSetting[];
const compactValueCount = settings.filter((setting) => setting.value.length <= 20).length;
if (compactValueCount < Math.max(2, Math.ceil(settings.length * 0.66))) continue;
const compactValueCount = settings.filter(
(setting) => setting.value.length <= 20,
).length;
if (compactValueCount < Math.max(2, Math.ceil(settings.length * 0.66)))
continue;
list.dataset.settingsEnhanced = "true";
list.classList.add("lab-settings-list");
@@ -126,11 +146,16 @@ async function copyTextToClipboard(text: string) {
return;
}
const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;
const activeElement =
document.activeElement instanceof HTMLElement
? document.activeElement
: null;
const selection = document.getSelection();
const previousRanges =
selection && selection.rangeCount > 0
? Array.from({ length: selection.rangeCount }, (_, index) => selection.getRangeAt(index).cloneRange())
? Array.from({ length: selection.rangeCount }, (_, index) =>
selection.getRangeAt(index).cloneRange(),
)
: [];
const textarea = document.createElement("textarea");
@@ -169,6 +194,38 @@ export function LabContent({ className, html }: LabContentProps) {
const containerRef = useRef<HTMLElement>(null);
const [zoomedImage, setZoomedImage] = useState<ZoomedImageState | null>(null);
const renderedContent = html
.split(
new RegExp(
`(${escapeRegex(quantizationExplorerToken)}|${escapeRegex(quantizationGridExplorerToken)}|${escapeRegex(objective5ChatToken)})`,
"g",
),
)
.filter(Boolean)
.map((part, index) => {
if (part === quantizationExplorerToken) {
return <QuantizationExplorer key={`quantization-explorer-${index}`} />;
}
if (part === quantizationGridExplorerToken) {
return (
<QuantizationGridExplorer
key={`quantization-grid-explorer-${index}`}
/>
);
}
if (part === objective5ChatToken) {
return <Objective5Chat key={`objective5-chat-${index}`} />;
}
return (
<Fragment key={`html-segment-${index}`}>
<div dangerouslySetInnerHTML={{ __html: part }} />
</Fragment>
);
});
useEffect(() => {
const root = containerRef.current;
if (!root) return;
@@ -195,7 +252,9 @@ export function LabContent({ className, html }: LabContentProps) {
const handleRootClick = (event: Event) => {
const target = event.target as HTMLElement;
const button = target.closest<HTMLButtonElement>("button.lab-copy-button");
const button = target.closest<HTMLButtonElement>(
"button.lab-copy-button",
);
if (button) {
const pre = button.closest("pre");
const code = pre?.querySelector("code");
@@ -203,19 +262,21 @@ export function LabContent({ className, html }: LabContentProps) {
if (!commandText) return;
const defaultLabel = button.dataset.defaultLabel ?? "Copy";
void copyTextToClipboard(commandText).then(() => {
button.textContent = "Copied";
button.classList.add("is-copied");
window.setTimeout(() => {
button.textContent = defaultLabel;
button.classList.remove("is-copied");
}, 1200);
}).catch(() => {
button.textContent = "Failed";
window.setTimeout(() => {
button.textContent = defaultLabel;
}, 1200);
});
void copyTextToClipboard(commandText)
.then(() => {
button.textContent = "Copied";
button.classList.add("is-copied");
window.setTimeout(() => {
button.textContent = defaultLabel;
button.classList.remove("is-copied");
}, 1200);
})
.catch(() => {
button.textContent = "Failed";
window.setTimeout(() => {
button.textContent = defaultLabel;
}, 1200);
});
return;
}
@@ -246,7 +307,8 @@ export function LabContent({ className, html }: LabContentProps) {
document.body.style.overflow = "hidden";
const activeElement = document.activeElement;
const previousFocusedElement = activeElement instanceof HTMLElement ? activeElement : null;
const previousFocusedElement =
activeElement instanceof HTMLElement ? activeElement : null;
const handleEscape = (event: KeyboardEvent) => {
if (event.key === "Escape") {
@@ -264,20 +326,25 @@ export function LabContent({ className, html }: LabContentProps) {
return (
<>
<article
ref={containerRef}
className={className}
dangerouslySetInnerHTML={{ __html: html }}
/>
<article ref={containerRef} className={className}>
{renderedContent}
</article>
{zoomedImage ? (
<div
className="lab-image-modal"
role="presentation"
onClick={() => setZoomedImage(null)}
>
<div className="lab-image-modal__surface" onClick={(event) => event.stopPropagation()}>
<div
className="lab-image-modal__surface"
onClick={(event) => event.stopPropagation()}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img className="lab-image-modal__image" src={zoomedImage.src} alt={zoomedImage.alt} />
<img
className="lab-image-modal__image"
src={zoomedImage.src}
alt={zoomedImage.alt}
/>
</div>
</div>
) : null}