Ryker_Feng 6d961e00e3
feat(skills): show loaded skill snapshots in answer details (#5758)
* feat(skills): show loaded skill snapshots in answer details

* docs: bring agent guidance under size budgets

* fix: align skill usage snapshots with visible tool output

* fix: validate skill usage producers and clarification run boundaries
2026-09-24 17:49:52 +08:00

54 lines
1.5 KiB
TypeScript

import { CheckIcon, CopyIcon } from "lucide-react";
import { useCallback, useState, type ComponentProps } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { writeTextToClipboard } from "@/core/clipboard";
import { useI18n } from "@/core/i18n/hooks";
import { Tooltip } from "./tooltip";
export function CopyButton({
clipboardData,
...props
}: ComponentProps<typeof Button> & {
clipboardData: string;
}) {
const { t } = useI18n();
const [copied, setCopied] = useState(false);
const handleCopy = useCallback(() => {
void (async () => {
const didCopy = await writeTextToClipboard(clipboardData);
if (!didCopy) {
toast.error(t.clipboard.failedToCopyToClipboard);
return;
}
setCopied(true);
setTimeout(() => setCopied(false), 2000);
})().catch(() => {
toast.error(t.clipboard.failedToCopyToClipboard);
});
}, [clipboardData, t.clipboard.failedToCopyToClipboard]);
return (
<Tooltip content={t.clipboard.copyToClipboard}>
<Button
aria-label={
copied ? t.clipboard.copiedToClipboard : t.clipboard.copyToClipboard
}
size="icon-sm"
type="button"
variant="ghost"
onClick={handleCopy}
{...props}
>
{copied ? (
<CheckIcon className="size-4 text-green-500" />
) : (
<CopyIcon className="size-4" />
)}
</Button>
</Tooltip>
);
}