import { useContext } from "react"; import Paper from "@moduletrace/twui/elements/Paper"; import Stack from "@moduletrace/twui/layout/Stack"; import Divider from "@moduletrace/twui/layout/Divider"; import { FolderOpen, History, Settings } from "lucide-react"; import type { BUN_SQLITE_COBBLE_WORKSPACES } from "@/db/types/db"; import type { BotWithLastMessage, HarnessOverview } from "@/src/types"; import BotSessionsModal from "@/src/components/general/bot-sessions-modal"; import { AppContext } from "@/src/pages/__root"; import canManageCrew from "@/src/utils/rbac/can-manage-crew"; import isPassThroughUser from "@/src/utils/rbac/is-pass-through-user"; import BotComputersModal from "./bot-computers-modal"; import BotFilesModal from "./bot-files-modal"; import BotTasksModal from "./bot-tasks-modal"; import BotRoutinesModal from "./bot-routines-modal"; import BotModelsModal from "./bot-models-modal"; import HeaderMenuItem from "./header-menu-item"; import NewSessionButton from "./new-session-button"; import StopBotButton from "./stop-bot-button"; type Props = { bot: BotWithLastMessage; /** * The workspace the conversation is in: its name shows under the * bot's, and the models modal edits its models. */ workspace?: BUN_SQLITE_COBBLE_WORKSPACES | null; /** * A bot message arrived in another session of this conversation. */ has_other_unread?: boolean; /** * The computer the bot is on, shown on its row. */ computer_name?: string | null; /** * The text model the bot runs on, shown on its row. */ model_name?: string | null; /** * After the models modal saved, so the header shows the new model. */ on_model_saved: (harnesses: HarnessOverview[]) => void; /** * A row is opening something: the menu closes, leaving only that. */ on_open: () => void; }; /** * The conversation header's menu: the sessions, a new session, the bot's * computer, its models, its settings and, while it works, stopping it. A * row that opens a modal closes the menu first, so the modal never sits * behind an open menu. */ export default function ConversationHeaderMenu({ bot, workspace, has_other_unread, computer_name, model_name, on_model_saved, on_open, }: Props) { const { pageProps } = useContext(AppContext); const can_open_settings = bot.kind == "coordinator" ? isPassThroughUser({ user_types: pageProps?.user_types }) : canManageCrew({ user_types: pageProps?.user_types }); return ( } target_wrapper_props={{ className: "w-full" }} on_open={on_open} /> {can_open_settings ? ( <> ) : null} ); }