From 44a0c9ad1d5352e31a1323fd95b6dd5d07781ca7 Mon Sep 17 00:00:00 2001 From: Kraft-Single Date: Tue, 17 Dec 2024 14:22:38 -0500 Subject: [PATCH] Added "add column" prompt & button in TablePopover modified: src/AiPopover.tsx Added handleGenerateColumn so that a column can be generated given a prompt. Added changes to the TablePopover UI Now extend is diveded into AddRow and AddColumn sections. modified: src/TabularDataNode.tsx Modified addColumns so that its safer. Added optional pass of rowValue to support generateColumn. modified: src/backend/ai.ts Added generateColumn and it's corresponding system message. Cleaned up some comments and added missing commas. --- chainforge/react-server/src/AiPopover.tsx | 111 +++++++++++++++--- .../react-server/src/TabularDataNode.tsx | 56 +++++++-- chainforge/react-server/src/backend/ai.ts | 91 +++++++++++++- 3 files changed, 229 insertions(+), 29 deletions(-) diff --git a/chainforge/react-server/src/AiPopover.tsx b/chainforge/react-server/src/AiPopover.tsx index 36d179c..934f3fd 100644 --- a/chainforge/react-server/src/AiPopover.tsx +++ b/chainforge/react-server/src/AiPopover.tsx @@ -10,10 +10,12 @@ import { Badge, Textarea, Alert, + Divider, } from "@mantine/core"; import { autofill, autofillTable, + generateColumn, generateAndReplace, AIError, getAIFeaturesModels, @@ -246,7 +248,10 @@ export interface AIGenReplaceTablePopoverProps { rows: TabularDataRowType[], ) => void; // Function to add new columns - onAddColumns: (newColumns: TabularDataColType[]) => void; + onAddColumns: ( + newColumns: TabularDataColType[], + rowValues?: string[] // Optional row values + ) => void; // Indicates if values are loading areValuesLoading: boolean; // Callback to set loading state @@ -283,6 +288,11 @@ export function AIGenReplaceTablePopover({ const [didGenerateAndReplaceTableError, setDidGenerateAndReplaceTableError] = useState(false); + // Generate Column state + const [isGenerateColumnLoading, setIsGenerateColumnLoading] = useState(false); + const [generateColumnPrompt, setGenerateColumnPrompt] = useState(""); + const [didGenerateColumnError, setDidGenerateColumnError] = useState(false); + // Check if there are any non-empty rows const nonEmptyRows = useMemo( () => @@ -350,22 +360,21 @@ export function AIGenReplaceTablePopover({ setDidCommandFillError(false); try { - // Extract columns from the values, excluding the __uid column const tableColumns = Object.keys(values[0] || {}).filter( - (col) => col !== "__uid" + (col) => col !== "__uid", ); // Extract rows as strings, excluding the __uid column and handling empty rows const tableRows = values .slice(0, -1) // Remove the last empty row .map((row) => - tableColumns.map((col) => row[col]?.trim() || "").join(" | ") + tableColumns.map((col) => row[col]?.trim() || "").join(" | "), ); const tableInput = { cols: tableColumns, - rows: tableRows + rows: tableRows, }; // Fetch new rows from the autofillTable function @@ -396,6 +405,51 @@ export function AIGenReplaceTablePopover({ } }; + const handleGenerateColumn = async () => { + setDidGenerateColumnError(false); + setIsGenerateColumnLoading(true); + + try { + // Extract columns from the values, excluding the __uid column + const tableColumns = Object.keys(values[0] || {}).filter( + (col) => col !== "__uid", + ); + + // Extract rows as strings, excluding the __uid column and handling empty rows + const tableRows = values + .slice(0, -1) // Remove the last empty row + .map((row) => + tableColumns.map((col) => row[col]?.trim() || "").join(" | "), + ); + + const tableInput = { + cols: tableColumns, + rows: tableRows, + }; + // Fetch the generated column + const generatedColumn = await generateColumn( + tableInput, + generateColumnPrompt, + aiFeaturesProvider, + apiKeys, + ); + + const rowValues = generatedColumn.rows; + + // Append the new column to the existing columns + onAddColumns( + [{ key: `col-${values.length}`, header: generatedColumn.col }], + rowValues + ); + } catch (error) { + console.error("Error generating column:", error); + setDidGenerateColumnError(true); + showAlert && showAlert("Failed to generate a new column. Please try again."); + } finally { + setIsGenerateColumnLoading(false); + } + }; + const extendUI = ( {didCommandFillError && ( @@ -403,29 +457,54 @@ export function AIGenReplaceTablePopover({ Failed to generate rows. Please try again. )} - setCommandFillNumber(num || 1)} - /> +
+ setCommandFillNumber(num || 1)} + style={{ flex: 1 }} + /> + +
{showWarning && ( You may want to add more fields for better suggestions. )} + + {didGenerateColumnError && ( + + Failed to generate column. Please try again. + + )} +