From 43de1dd98c1bb000c70d49d6bd0f177083d691ed Mon Sep 17 00:00:00 2001 From: Ian Arawjo Date: Sat, 30 Mar 2024 21:54:20 -0400 Subject: [PATCH] Move Alert Provider to top level of index.js --- chainforge/react-server/src/App.tsx | 10 +++++-- chainforge/react-server/src/InspectorNode.tsx | 12 ++++++-- .../react-server/src/LLMResponseInspector.tsx | 30 ++++++++++++++----- .../src/LLMResponseInspectorModal.tsx | 19 ++++++++++-- chainforge/react-server/src/index.js | 9 ++++-- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/chainforge/react-server/src/App.tsx b/chainforge/react-server/src/App.tsx index f7f446e..d798431 100644 --- a/chainforge/react-server/src/App.tsx +++ b/chainforge/react-server/src/App.tsx @@ -37,7 +37,7 @@ import CodeEvaluatorNode from "./CodeEvaluatorNode"; import VisNode from "./VisNode"; import InspectNode from "./InspectorNode"; import ScriptNode from "./ScriptNode"; -import { AlertModalProvider, AlertModalContext } from "./AlertModal"; +import { AlertModalContext } from "./AlertModal"; import ItemsNode from "./ItemsNode"; import TabularDataNode from "./TabularDataNode"; import JoinNode from "./JoinNode"; @@ -898,7 +898,7 @@ const App = () => { ); } else return ( - +
{ snapToGrid={true} snapGrid={snapGrid} onInit={onInit} + onError={(err) => { + // Suppress ReactFlow warnings spamming the console. + // console.log(err); + }} > @@ -1223,7 +1227,7 @@ const App = () => { Send us feedback
-
+ ); }; diff --git a/chainforge/react-server/src/InspectorNode.tsx b/chainforge/react-server/src/InspectorNode.tsx index b6dcb14..e3c4a08 100644 --- a/chainforge/react-server/src/InspectorNode.tsx +++ b/chainforge/react-server/src/InspectorNode.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useContext } from "react"; import { Handle, Position } from "reactflow"; import useStore from "./store"; import BaseNode from "./BaseNode"; @@ -6,6 +6,7 @@ import NodeLabel from "./NodeLabelComponent"; import LLMResponseInspector, { exportToExcel } from "./LLMResponseInspector"; import { grabResponses } from "./backend/backend"; import { LLMResponse } from "./backend/typing"; +import { AlertModalContext } from "./AlertModal"; export interface InspectorNodeProps { data: { @@ -26,6 +27,7 @@ const InspectorNode: React.FC = ({ data, id }) => { const [pastInputs, setPastInputs] = useState(""); const inputEdgesForNode = useStore((state) => state.inputEdgesForNode); const setDataPropsForNode = useStore((state) => state.setDataPropsForNode); + const showAlert = useContext(AlertModalContext); const handleOnConnect = () => { // For some reason, 'on connect' is called twice upon connection. @@ -74,7 +76,13 @@ const InspectorNode: React.FC = ({ data, id }) => { , diff --git a/chainforge/react-server/src/LLMResponseInspector.tsx b/chainforge/react-server/src/LLMResponseInspector.tsx index e87fe53..da05760 100644 --- a/chainforge/react-server/src/LLMResponseInspector.tsx +++ b/chainforge/react-server/src/LLMResponseInspector.tsx @@ -38,7 +38,12 @@ import { genResponseTextsDisplay, } from "./ResponseBoxes"; import { getLabelForResponse } from "./ResponseRatingToolbar"; -import { Dict, LLMResponse, LLMResponseData } from "./backend/typing"; +import { + Dict, + LLMResponse, + LLMResponseData, + isImageResponseData, +} from "./backend/typing"; // Helper funcs const getLLMName = (resp_obj: LLMResponse) => @@ -55,8 +60,8 @@ function getIndicesOfSubstringMatches( escapeRegExp(substr), "g" + (caseSensitive ? "" : "i"), ); - let result; - const indices = []; + let result: RegExpExecArray | null; + const indices: number[] = []; while ((result = regex.exec(s))) indices.push(result.index); return indices; } @@ -71,9 +76,9 @@ function splitAndIncludeDelimiter( if (indices.length === 0) return [s]; const len_sub = substr.length; - const results = []; + const results: string[] = []; let prev_idx = 0; - indices.forEach((idx) => { + indices.forEach((idx: number) => { const pre_delim = s.substring(prev_idx, idx); const delim = s.substring(idx, idx + len_sub); results.push(pre_delim); @@ -119,10 +124,21 @@ export const exportToExcel = ( !jsonResponses || (Array.isArray(jsonResponses) && jsonResponses.length === 0) ) { - console.warn( + throw new Error( "No responses to export. Try connecting the inspector node to a prompt node or evaluator node.", ); - return; + } + + // Check format of responses + // TODO: Support export of images in Excel sheets + if ( + jsonResponses.some( + (r) => r.responses.length > 0 && isImageResponseData(r.responses[0]), + ) + ) { + throw new Error( + "Images cannot be exported to Excel at this time. If you need this feature and you are a developer, please consider submitting a PR to our GitHub repository.", + ); } // We can construct the data as an array of JSON dicts, with keys as header names: diff --git a/chainforge/react-server/src/LLMResponseInspectorModal.tsx b/chainforge/react-server/src/LLMResponseInspectorModal.tsx index 9b6dbfb..754efa6 100644 --- a/chainforge/react-server/src/LLMResponseInspectorModal.tsx +++ b/chainforge/react-server/src/LLMResponseInspectorModal.tsx @@ -2,11 +2,18 @@ * A fullscreen version of the Inspect node that * appears in a Mantine modal pop-up which takes up much of the screen. */ -import React, { forwardRef, useImperativeHandle, lazy, Suspense } from "react"; +import React, { + forwardRef, + useImperativeHandle, + lazy, + Suspense, + useContext, +} from "react"; import { LoadingOverlay, Modal } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { exportToExcel } from "./LLMResponseInspector"; import { LLMResponse } from "./backend/typing"; +import { AlertModalContext } from "./AlertModal"; // Lazy load the inspector view const LLMResponseInspector = lazy(() => import("./LLMResponseInspector")); @@ -25,6 +32,7 @@ const LLMResponseInspectorModal = forwardRef< >(function LLMResponseInspectorModal(props, ref) { // const inspectorRef = useRef(null); const [opened, { open, close }] = useDisclosure(false); + const showAlert = useContext(AlertModalContext); // const [openedOnce, setOpenedOnce] = useState(false); // This gives the parent access to triggering the modal @@ -50,7 +58,14 @@ const LLMResponseInspectorModal = forwardRef< diff --git a/chainforge/react-server/src/index.js b/chainforge/react-server/src/index.js index 56ac0a1..7f65980 100644 --- a/chainforge/react-server/src/index.js +++ b/chainforge/react-server/src/index.js @@ -4,13 +4,16 @@ import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { ContextMenuProvider } from "mantine-contextmenu"; +import { AlertModalProvider } from "./AlertModal"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - - + + + + + , );