mirror of
https://github.com/Mintplex-Labs/anything-llm
synced 2026-04-26 01:25:15 +02:00
* Add automatic chat mode with native tool calling support
Introduces a new automatic chat mode (now the default) that automatically invokes tools when the provider supports native tool calling. Conditionally shows/hides the @agent command based on whether native tooling is available.
- Add supportsNativeToolCalling() to AI providers (OpenAI, Anthropic, Azure always support; others opt-in via ENV)
- Update all locale translations with new mode descriptions
- Enhance translator to preserve Trans component tags
- Remove deprecated ability tags UI
* rebase translations
* WIP on image attachments. Supports initial image attachment + subsequent attachments
* persist images
* Image attachments and updates for providers
* desktop pre-change
* always show command on failure
* add back gemini streaming detection
* move provider native tooling flag to Provider func
* whoops - forgot to delete
* strip "@agent" from prompts to prevent weird replies
* translations for automatic-mode (#5145)
* translations for automatic-mode
* rebase
* translations
* lint
* fix dead translations
* change default for now to chat mode just for rollout
* remove pfp for workspace
* passthrough workspace for showAgentCommand detection and rendering
* Agent API automatic mode support
* ephemeral attachments passthrough
* support reading of pinned documents in agent context
117 lines
3.8 KiB
JavaScript
117 lines
3.8 KiB
JavaScript
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 opacity-60 hover:opacity-100 light:opacity-100 light:hover:opacity-60 ${
|
|
showing ? "!opacity-100" : ""
|
|
}`}
|
|
>
|
|
<At
|
|
color="var(--theme-sidebar-footer-icon-fill)"
|
|
className="w-[20px] h-[20px] pointer-events-none text-theme-text-primary"
|
|
/>
|
|
<Tooltip
|
|
id="tooltip-agent-list-btn"
|
|
place="top"
|
|
delayShow={300}
|
|
className="tooltip !text-xs z-99"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function AvailableAgents({
|
|
showing,
|
|
setShowing,
|
|
sendCommand,
|
|
promptRef,
|
|
centered = false,
|
|
}) {
|
|
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={
|
|
centered
|
|
? "w-full flex justify-center md:justify-start absolute top-full mt-2 left-0 z-10 px-4 md:px-0 md:pl-[57px]"
|
|
: "flex justify-center md:justify-start absolute bottom-[130px] md:bottom-[150px] left-0 right-0 z-10 max-w-[750px] mx-auto px-4 md:px-0 md:pl-[57px]"
|
|
}
|
|
>
|
|
<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 overflow-y-auto max-h-[200px] no-scroll"
|
|
>
|
|
<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>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function useAvailableAgents() {
|
|
const [showAgents, setShowAgents] = useState(false);
|
|
return { showAgents, setShowAgents };
|
|
}
|