Spaces:
Build error
Build error
| import React, { useState } from "react"; | |
| import { useTranslation } from "react-i18next"; | |
| import { ChevronDown, ChevronRight } from "lucide-react"; | |
| import ReactJsonView from "@microlink/react-json-view"; | |
| import { BaseModalTitle } from "#/components/shared/modals/confirmation-modals/base-modal"; | |
| import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop"; | |
| import { ModalBody } from "#/components/shared/modals/modal-body"; | |
| import { cn } from "#/utils/utils"; | |
| import { JSON_VIEW_THEME } from "#/utils/constants"; | |
| interface SystemMessageModalProps { | |
| isOpen: boolean; | |
| onClose: () => void; | |
| systemMessage: { | |
| content: string; | |
| tools: Array<Record<string, unknown>> | null; | |
| openhands_version: string | null; | |
| agent_class: string | null; | |
| } | null; | |
| } | |
| interface FunctionData { | |
| name?: string; | |
| description?: string; | |
| parameters?: Record<string, unknown>; | |
| } | |
| interface ToolData { | |
| type?: string; | |
| function?: FunctionData; | |
| name?: string; | |
| description?: string; | |
| parameters?: Record<string, unknown>; | |
| } | |
| export function SystemMessageModal({ | |
| isOpen, | |
| onClose, | |
| systemMessage, | |
| }: SystemMessageModalProps) { | |
| const { t } = useTranslation(); | |
| const [activeTab, setActiveTab] = useState<"system" | "tools">("system"); | |
| const [expandedTools, setExpandedTools] = useState<Record<number, boolean>>( | |
| {}, | |
| ); | |
| if (!systemMessage) { | |
| return null; | |
| } | |
| const toggleTool = (index: number) => { | |
| setExpandedTools((prev) => ({ | |
| ...prev, | |
| [index]: !prev[index], | |
| })); | |
| }; | |
| return ( | |
| isOpen && ( | |
| <ModalBackdrop onClose={onClose}> | |
| <ModalBody | |
| width="medium" | |
| className="max-h-[80vh] flex flex-col items-start" | |
| > | |
| <div className="flex flex-col gap-6 w-full"> | |
| <BaseModalTitle title={t("SYSTEM_MESSAGE_MODAL$TITLE")} /> | |
| <div className="flex flex-col gap-2"> | |
| {systemMessage.agent_class && ( | |
| <div className="text-sm"> | |
| <span className="font-semibold text-gray-300"> | |
| {t("SYSTEM_MESSAGE_MODAL$AGENT_CLASS")} | |
| </span>{" "} | |
| <span className="font-medium text-gray-100"> | |
| {systemMessage.agent_class} | |
| </span> | |
| </div> | |
| )} | |
| {systemMessage.openhands_version && ( | |
| <div className="text-sm"> | |
| <span className="font-semibold text-gray-300"> | |
| {t("SYSTEM_MESSAGE_MODAL$OPENHANDS_VERSION")} | |
| </span>{" "} | |
| <span className="text-gray-100"> | |
| {systemMessage.openhands_version} | |
| </span> | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| <div className="w-full"> | |
| <div className="flex border-b mb-2"> | |
| <button | |
| type="button" | |
| className={cn( | |
| "px-4 py-2 font-medium border-b-2 transition-colors", | |
| activeTab === "system" | |
| ? "border-primary text-gray-100" | |
| : "border-transparent hover:text-gray-700 dark:hover:text-gray-300", | |
| )} | |
| onClick={() => setActiveTab("system")} | |
| > | |
| {t("SYSTEM_MESSAGE_MODAL$SYSTEM_MESSAGE_TAB")} | |
| </button> | |
| {systemMessage.tools && systemMessage.tools.length > 0 && ( | |
| <button | |
| type="button" | |
| className={cn( | |
| "px-4 py-2 font-medium border-b-2 transition-colors", | |
| activeTab === "tools" | |
| ? "border-primary text-gray-100" | |
| : "border-transparent hover:text-gray-700 dark:hover:text-gray-300", | |
| )} | |
| onClick={() => setActiveTab("tools")} | |
| > | |
| {t("SYSTEM_MESSAGE_MODAL$TOOLS_TAB")} | |
| </button> | |
| )} | |
| </div> | |
| <div className="h-[60vh] overflow-auto rounded-md"> | |
| {activeTab === "system" && ( | |
| <div className="p-4 whitespace-pre-wrap font-mono text-sm leading-relaxed text-gray-300 shadow-inner"> | |
| {systemMessage.content} | |
| </div> | |
| )} | |
| {activeTab === "tools" && | |
| systemMessage.tools && | |
| systemMessage.tools.length > 0 && ( | |
| <div className="p-2 space-y-3"> | |
| {systemMessage.tools.map((tool, index) => { | |
| // Extract function data from the nested structure | |
| const toolData = tool as ToolData; | |
| const functionData = toolData.function || toolData; | |
| const name = | |
| functionData.name || | |
| (toolData.type === "function" && | |
| toolData.function?.name) || | |
| ""; | |
| const description = | |
| functionData.description || | |
| (toolData.type === "function" && | |
| toolData.function?.description) || | |
| ""; | |
| const parameters = | |
| functionData.parameters || | |
| (toolData.type === "function" && | |
| toolData.function?.parameters) || | |
| null; | |
| const isExpanded = expandedTools[index] || false; | |
| return ( | |
| <div key={index} className="rounded-md overflow-hidden"> | |
| <button | |
| type="button" | |
| onClick={() => toggleTool(index)} | |
| className="w-full py-3 px-2 text-left flex items-center justify-between hover:bg-gray-700 transition-colors" | |
| > | |
| <div className="flex items-center"> | |
| <h3 className="font-bold text-gray-100"> | |
| {String(name)} | |
| </h3> | |
| </div> | |
| <span className="text-gray-300"> | |
| {isExpanded ? ( | |
| <ChevronDown size={18} /> | |
| ) : ( | |
| <ChevronRight size={18} /> | |
| )} | |
| </span> | |
| </button> | |
| {isExpanded && ( | |
| <div className="px-2 pb-3 pt-1"> | |
| <div className="mt-2 mb-3"> | |
| <p className="text-sm whitespace-pre-wrap text-gray-300 leading-relaxed"> | |
| {String(description)} | |
| </p> | |
| </div> | |
| {/* Parameters section */} | |
| {parameters && ( | |
| <div className="mt-2"> | |
| <h4 className="text-sm font-semibold text-gray-300"> | |
| {t("SYSTEM_MESSAGE_MODAL$PARAMETERS")} | |
| </h4> | |
| <div className="text-sm mt-2 p-3 bg-gray-900 rounded-md overflow-auto text-gray-300 max-h-[400px] shadow-inner"> | |
| <ReactJsonView | |
| name={false} | |
| src={parameters} | |
| theme={JSON_VIEW_THEME} | |
| /> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| )} | |
| {activeTab === "tools" && | |
| (!systemMessage.tools || systemMessage.tools.length === 0) && ( | |
| <div className="flex items-center justify-center h-full p-4"> | |
| <p className="text-gray-400"> | |
| {t("SYSTEM_MESSAGE_MODAL$NO_TOOLS")} | |
| </p> | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| </ModalBody> | |
| </ModalBackdrop> | |
| ) | |
| ); | |
| } | |