diff --git a/packages/ui/src/assets/images/prompt_empty.svg b/packages/ui/src/assets/images/prompt_empty.svg new file mode 100644 index 00000000..61df7e32 --- /dev/null +++ b/packages/ui/src/assets/images/prompt_empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/ui/src/ui-component/dialog/PromptLangsmithHubDialog.js b/packages/ui/src/ui-component/dialog/PromptLangsmithHubDialog.js index 35f1f754..e1cfaaa9 100644 --- a/packages/ui/src/ui-component/dialog/PromptLangsmithHubDialog.js +++ b/packages/ui/src/ui-component/dialog/PromptLangsmithHubDialog.js @@ -1,6 +1,14 @@ import { createPortal } from 'react-dom' import { useState, useEffect } from 'react' +import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' + +import rehypeMathjax from 'rehype-mathjax' +import rehypeRaw from 'rehype-raw' +import remarkGfm from 'remark-gfm' +import remarkMath from 'remark-math' + +// MUI import { Box, Button, @@ -10,7 +18,7 @@ import { DialogActions, DialogContent, DialogTitle, - Divider, + Chip, Grid, InputLabel, List, @@ -18,23 +26,30 @@ import { ListItemText, OutlinedInput, Select, - Typography + Typography, + Stack, + IconButton, + FormControl, + Checkbox, + MenuItem } from '@mui/material' -import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from '../../store/actions' -import { useDispatch } from 'react-redux' -import FormControl from '@mui/material/FormControl' -import Checkbox from '@mui/material/Checkbox' -import MenuItem from '@mui/material/MenuItem' -import ReactMarkdown from 'react-markdown' -import CredentialInputHandler from '../../views/canvas/CredentialInputHandler' -import promptApi from '../../api/prompt' -import { StyledButton } from '../button/StyledButton' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' -import { styled } from '@mui/material/styles' -import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp' import MuiAccordion from '@mui/material/Accordion' import MuiAccordionSummary from '@mui/material/AccordionSummary' import MuiAccordionDetails from '@mui/material/AccordionDetails' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp' +import ClearIcon from '@mui/icons-material/Clear' +import { styled } from '@mui/material/styles' + +//Project Import +import CredentialInputHandler from 'views/canvas/CredentialInputHandler' +import { StyledButton } from 'ui-component/button/StyledButton' +import { MemoizedReactMarkdown } from 'ui-component/markdown/MemoizedReactMarkdown' +import { CodeBlock } from 'ui-component/markdown/CodeBlock' +import promptEmptySVG from 'assets/images/prompt_empty.svg' + +import promptApi from 'api/prompt' +import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions' const NewLineToBr = ({ children = '' }) => { return children.split('\n').reduce(function (arr, line) { @@ -73,6 +88,7 @@ const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => { const portalElement = document.getElementById('portal') const dispatch = useDispatch() + const customization = useSelector((state) => state.customization) useEffect(() => { if (show) dispatch({ type: SHOW_CANVAS_DIALOG }) @@ -141,19 +157,24 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => { const [selectedPrompt, setSelectedPrompt] = useState({}) const [credentialId, setCredentialId] = useState('') - const [accordionExpanded, setAccordionExpanded] = useState('panel2') + const [accordionExpanded, setAccordionExpanded] = useState(['prompt']) - const handleAccordionChange = (panel) => { - setAccordionExpanded(panel) + const handleAccordionChange = (accordionName) => (event, isExpanded) => { + const accordians = [...accordionExpanded] + if (!isExpanded) setAccordionExpanded(accordians.filter((accr) => accr !== accordionName)) + else { + accordians.push(accordionName) + setAccordionExpanded(accordians) + } } - const handleListItemClick = async (event, index) => { - const prompt = availablePrompNameList[index] + const handleListItemClick = async (index, overridePromptNameList = []) => { + const prompt = overridePromptNameList.length ? overridePromptNameList[index] : availablePrompNameList[index] if (!prompt.detailed) { const createResp = await promptApi.getPrompt({ credential: credentialId, - promptName: selectedPrompt.full_name + promptName: prompt.full_name }) if (createResp.data) { prompt.detailed = createResp.data.templates @@ -180,6 +201,7 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => { }) if (createResp.data) { setAvailablePrompNameList(createResp.data.repos) + if (createResp.data.repos?.length) handleListItemClick(0, createResp.data.repos) } } @@ -217,12 +239,21 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => { setLanguage(removeDuplicates(value)) } + const clear = () => { + setModelName([]) + setUsecase([]) + setLanguage([]) + setSelectedPrompt({}) + setAvailablePrompNameList([]) + setAccordionExpanded(['prompt']) + } + const component = show ? ( @@ -230,12 +261,12 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => { Load Prompts from Langsmith Hub ({promptType === 'template' ? 'PromptTemplate' : 'ChatPromptTemplate'}) - - - Langsmith Credential + + + Langsmith Credential   * - + { }} onSelect={(newValue) => { setCredentialId(newValue) + if (!newValue) clear() }} /> - - - - Model - - - - - - Usecase - - - - - - Language - - - - - - - - - - - - - - - Available Prompts - - - {availablePrompNameList.map((item, index) => ( - handleListItemClick(event, index)} - > - {item.full_name} - - ))} - - - + {credentialId && ( + + + + Model + + + + + + Usecase + + + + + + Language + + + + + + + + )} + {availablePrompNameList && availablePrompNameList.length == 0 && ( + + + promptEmptySVG - - - - - - handleAccordionChange('panel1')}> - } - id='panel1d-header' - > - Description - - - - {selectedPrompt?.description} - - - - handleAccordionChange('panel2')}> - } - id='panel2d-header' - > - Prompt - - - - {selectedPrompt?.detailed?.map((item) => ( - <> - - {item.typeDisplay.toUpperCase()} +
No Available Prompts
+ + )} + {availablePrompNameList && availablePrompNameList.length > 0 && ( + + + + + + + + + Available Prompts + + + {availablePrompNameList.map((item, index) => ( + handleListItemClick(index)} + > +
+ + {item.full_name} + +
+ {item.tags.map((tag, index) => ( + + ))} +
+
+
+ ))} +
+
+
+
+
+ + + + + + } + id='panel2d-header' + > + Prompt + + + + {selectedPrompt?.detailed?.map((item) => ( + <> + + {item.typeDisplay.toUpperCase()} + + +

+ {item.template} +

+
+ + ))}
- -

+ + + } + id='panel1d-header' + > + Description + + + + {selectedPrompt?.description} + + + + + } + aria-controls='panel3d-content' + id='panel3d-header' + > + Readme + + +

+ + ) : ( + + {children} + + ) + } }} > - {item.template} -

- - - ))} - - - - handleAccordionChange('panel3')}> - } - aria-controls='panel3d-content' - id='panel3d-header' - > - Readme - - - - {selectedPrompt?.readme} - - - - - + {selectedPrompt?.readme} +
+
+
+
+
+
+
+
+
-
-
+ + )}
- - - onSubmit(selectedPrompt.detailed)} variant='contained'> - Submit - - + {availablePrompNameList && availablePrompNameList.length > 0 && ( + + + onSubmit(selectedPrompt.detailed)} + variant='contained' + > + Load + + + )}
) : null diff --git a/packages/ui/src/views/canvas/NodeInputHandler.js b/packages/ui/src/views/canvas/NodeInputHandler.js index 24ba3c92..7920af6a 100644 --- a/packages/ui/src/views/canvas/NodeInputHandler.js +++ b/packages/ui/src/views/canvas/NodeInputHandler.js @@ -231,7 +231,7 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA flexDirection: 'row', width: '100%' }} - sx={{ borderRadius: 25, width: '100%', mb: 2, mt: 2 }} + sx={{ borderRadius: 25, width: '100%', mb: 2, mt: 0 }} variant='outlined' onClick={() => onShowPromptHubButtonClicked()} endIcon={}