File size: 4,663 Bytes
f8b5d42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import { useEffect, useRef, useState } from "react";
import { Tooltip } from "react-tooltip";
import { At } from "@phosphor-icons/react";
import { useIsAgentSessionActive } from "@/utils/chat/agent";
import { useTranslation } from "react-i18next";
import { useSearchParams } from "react-router-dom";
export default function AvailableAgentsButton({ showing, setShowAgents }) {
const { t } = useTranslation();
const agentSessionActive = useIsAgentSessionActive();
if (agentSessionActive) return null;
return (
<div
id="agent-list-btn"
data-tooltip-id="tooltip-agent-list-btn"
data-tooltip-content={t("chat_window.agents")}
aria-label={t("chat_window.agents")}
onClick={() => setShowAgents(!showing)}
className={`flex justify-center items-center cursor-pointer ${
showing ? "!opacity-100" : ""
}`}
>
<At
color="var(--theme-sidebar-footer-icon-fill)"
className={`w-[22px] h-[22px] pointer-events-none text-theme-text-primary opacity-60 hover:opacity-100 light:opacity-100 light:hover:opacity-60`}
/>
<Tooltip
id="tooltip-agent-list-btn"
place="top"
delayShow={300}
className="tooltip !text-xs z-99"
/>
</div>
);
}
function AbilityTag({ text }) {
return (
<div className="px-2 bg-theme-action-menu-item-hover text-theme-text-secondary text-xs w-fit rounded-sm">
<p>{text}</p>
</div>
);
}
export function AvailableAgents({
showing,
setShowing,
sendCommand,
promptRef,
}) {
const formRef = useRef(null);
const agentSessionActive = useIsAgentSessionActive();
const [searchParams] = useSearchParams();
const { t } = useTranslation();
/*
* @checklist-item
* If the URL has the agent param, open the agent menu for the user
* automatically when the component mounts.
*/
useEffect(() => {
if (searchParams.get("action") === "set-agent-chat" && !showing)
handleAgentClick();
}, [promptRef.current]);
useEffect(() => {
function listenForOutsideClick() {
if (!showing || !formRef.current) return false;
document.addEventListener("click", closeIfOutside);
}
listenForOutsideClick();
}, [showing, formRef.current]);
const closeIfOutside = ({ target }) => {
if (target.id === "agent-list-btn") return;
const isOutside = !formRef?.current?.contains(target);
if (!isOutside) return;
setShowing(false);
};
const handleAgentClick = () => {
setShowing(false);
sendCommand({ text: "@agent " });
promptRef?.current?.focus();
};
if (agentSessionActive) return null;
return (
<>
<div hidden={!showing}>
<div className="w-full flex justify-center absolute bottom-[130px] md:bottom-[150px] left-0 z-10 px-4">
<div
ref={formRef}
className="w-[600px] p-2 bg-theme-action-menu-bg rounded-2xl shadow flex-col justify-center items-start gap-2.5 inline-flex"
>
<button
onClick={handleAgentClick}
className="border-none w-full hover:cursor-pointer hover:bg-theme-action-menu-item-hover px-2 py-2 rounded-xl flex flex-col justify-start group"
>
<div className="w-full flex-col text-left flex pointer-events-none">
<div className="text-theme-text-primary text-sm">
<b>{t("chat_window.at_agent")}</b>
{t("chat_window.default_agent_description")}
</div>
<div className="flex flex-wrap gap-2 mt-2">
<AbilityTag text="rag-search" />
<AbilityTag text="web-scraping" />
<AbilityTag text="web-browsing" />
<AbilityTag text="save-file-to-browser" />
<AbilityTag text="list-documents" />
<AbilityTag text="summarize-document" />
<AbilityTag text="chart-generation" />
</div>
</div>
</button>
<button
type="button"
disabled={true}
className="w-full rounded-xl flex flex-col justify-start group"
>
<div className="w-full flex-col text-center flex pointer-events-none">
<div className="text-theme-text-secondary text-xs italic">
{t("chat_window.custom_agents_coming_soon")}
</div>
</div>
</button>
</div>
</div>
</div>
</>
);
}
export function useAvailableAgents() {
const [showAgents, setShowAgents] = useState(false);
return { showAgents, setShowAgents };
}
|