tfrere's picture
tfrere HF Staff
feat(agent): integrate Lovable-style patterns
37938b3
Raw
History Blame Contribute Delete
3.59 kB
import { useEffect, useRef, useState } from "react";
const STORAGE_KEY = "reachy-vibe-knowledge";
const MAX_LEN = 20_000;
interface KnowledgeDialogProps {
open: boolean;
onClose: () => void;
}
export function loadKnowledge(): string {
try {
return localStorage.getItem(STORAGE_KEY) ?? "";
} catch {
return "";
}
}
export function KnowledgeDialog({ open, onClose }: KnowledgeDialogProps) {
const [text, setText] = useState("");
const [saved, setSaved] = useState(false);
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
useEffect(() => {
if (!open) return;
setText(loadKnowledge());
setSaved(false);
const t = window.setTimeout(() => textareaRef.current?.focus(), 40);
return () => window.clearTimeout(t);
}, [open]);
const handleSave = () => {
try {
const trimmed = text.slice(0, MAX_LEN);
localStorage.setItem(STORAGE_KEY, trimmed);
setText(trimmed);
setSaved(true);
window.setTimeout(() => setSaved(false), 1500);
} catch (err) {
console.error("[knowledge] save failed", err);
}
};
const handleClear = () => {
try {
localStorage.removeItem(STORAGE_KEY);
} catch {}
setText("");
setSaved(true);
window.setTimeout(() => setSaved(false), 1500);
};
if (!open) return null;
const charCount = text.length;
const approxKb = (charCount / 1024).toFixed(1);
return (
<div className="modal-overlay" onClick={onClose}>
<div className="modal knowledge-modal" onClick={(e) => e.stopPropagation()}>
<header className="modal-header">
<div>
<h2>App Knowledge</h2>
<p className="modal-sub">
Long-lived context the agent sees on every message. Use it for
the project goal, constraints, tone, preferred libraries,
API keys already in place, etc.
</p>
</div>
<button
type="button"
className="btn btn-ghost"
onClick={onClose}
aria-label="Close"
>
</button>
</header>
<div className="modal-body">
<textarea
ref={textareaRef}
className="knowledge-textarea"
value={text}
onChange={(e) => setText(e.target.value.slice(0, MAX_LEN))}
placeholder={[
"Example:",
"- I'm building an accessibility demo for Reachy Mini.",
"- Keep the UI high-contrast and screen-reader friendly.",
"- All robot commands must be undoable from the UI.",
"- Prefer plain DOM over frameworks.",
].join("\n")}
rows={14}
/>
<div className="knowledge-meta">
<span>
{charCount.toLocaleString()} chars · ~{approxKb} KB
</span>
<span className="text-faint">
Stored locally in your browser, sent on every prompt.
</span>
</div>
</div>
<footer className="modal-footer">
<button type="button" className="btn btn-ghost" onClick={handleClear}>
Clear
</button>
<div className="spacer" />
{saved && <span className="saved-pill">Saved</span>}
<button type="button" className="btn btn-ghost" onClick={onClose}>
Close
</button>
<button type="button" className="btn btn-primary" onClick={handleSave}>
Save
</button>
</footer>
</div>
</div>
);
}