mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 23:01:09 +03:00
get rid of credential for langchain hub
This commit is contained in:
@@ -1044,18 +1044,9 @@ export class App {
|
|||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
this.app.post('/api/v1/load-prompt', async (req: Request, res: Response) => {
|
this.app.post('/api/v1/load-prompt', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const credential = await this.AppDataSource.getRepository(Credential).findOneBy({
|
let hub = new Client()
|
||||||
id: req.body.credential
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!credential) return res.status(404).json({ error: `Credential ${req.body.credential} not found` })
|
|
||||||
|
|
||||||
// Decrypt credentialData
|
|
||||||
const decryptedCredentialData = await decryptCredentialData(credential.encryptedData, credential.credentialName, undefined)
|
|
||||||
let hub = new Client({ apiKey: decryptedCredentialData.langsmithApiKey, apiUrl: decryptedCredentialData.langsmithEndpoint })
|
|
||||||
const prompt = await hub.pull(req.body.promptName)
|
const prompt = await hub.pull(req.body.promptName)
|
||||||
const templates = parsePrompt(prompt)
|
const templates = parsePrompt(prompt)
|
||||||
|
|
||||||
return res.json({ status: 'OK', prompt: req.body.promptName, templates: templates })
|
return res.json({ status: 'OK', prompt: req.body.promptName, templates: templates })
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return res.json({ status: 'ERROR', prompt: req.body.promptName, error: e?.message })
|
return res.json({ status: 'ERROR', prompt: req.body.promptName, error: e?.message })
|
||||||
@@ -1064,22 +1055,10 @@ export class App {
|
|||||||
|
|
||||||
this.app.post('/api/v1/prompts-list', async (req: Request, res: Response) => {
|
this.app.post('/api/v1/prompts-list', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const credential = await this.AppDataSource.getRepository(Credential).findOneBy({
|
|
||||||
id: req.body.credential
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!credential) return res.status(404).json({ error: `Credential ${req.body.credential} not found` })
|
|
||||||
// Decrypt credentialData
|
|
||||||
const decryptedCredentialData = await decryptCredentialData(credential.encryptedData, credential.credentialName, undefined)
|
|
||||||
|
|
||||||
const headers = {}
|
|
||||||
// @ts-ignore
|
|
||||||
headers['x-api-key'] = decryptedCredentialData.langsmithApiKey
|
|
||||||
|
|
||||||
const tags = req.body.tags ? `tags=${req.body.tags}` : ''
|
const tags = req.body.tags ? `tags=${req.body.tags}` : ''
|
||||||
// Default to 100, TODO: add pagination and use offset & limit
|
// Default to 100, TODO: add pagination and use offset & limit
|
||||||
const url = `https://web.hub.langchain.com/repos/?limit=100&${tags}has_commits=true&sort_field=num_likes&sort_direction=desc&is_archived=false`
|
const url = `https://api.hub.langchain.com/repos/?limit=100&${tags}has_commits=true&sort_field=num_likes&sort_direction=desc&is_archived=false`
|
||||||
axios.get(url, headers).then((response) => {
|
axios.get(url).then((response) => {
|
||||||
if (response.data.repos) {
|
if (response.data.repos) {
|
||||||
return res.json({ status: 'OK', repos: response.data.repos })
|
return res.json({ status: 'OK', repos: response.data.repos })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ import ClearIcon from '@mui/icons-material/Clear'
|
|||||||
import { styled } from '@mui/material/styles'
|
import { styled } from '@mui/material/styles'
|
||||||
|
|
||||||
//Project Import
|
//Project Import
|
||||||
import CredentialInputHandler from 'views/canvas/CredentialInputHandler'
|
|
||||||
import { StyledButton } from 'ui-component/button/StyledButton'
|
import { StyledButton } from 'ui-component/button/StyledButton'
|
||||||
import { MemoizedReactMarkdown } from 'ui-component/markdown/MemoizedReactMarkdown'
|
import { MemoizedReactMarkdown } from 'ui-component/markdown/MemoizedReactMarkdown'
|
||||||
import { CodeBlock } from 'ui-component/markdown/CodeBlock'
|
import { CodeBlock } from 'ui-component/markdown/CodeBlock'
|
||||||
import promptEmptySVG from 'assets/images/prompt_empty.svg'
|
import promptEmptySVG from 'assets/images/prompt_empty.svg'
|
||||||
|
|
||||||
|
import useApi from 'hooks/useApi'
|
||||||
import promptApi from 'api/prompt'
|
import promptApi from 'api/prompt'
|
||||||
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
|
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
|
||||||
|
|
||||||
@@ -89,6 +89,7 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
const portalElement = document.getElementById('portal')
|
const portalElement = document.getElementById('portal')
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const customization = useSelector((state) => state.customization)
|
const customization = useSelector((state) => state.customization)
|
||||||
|
const getAvailablePromptsApi = useApi(promptApi.getAvailablePrompts)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
|
if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
|
||||||
@@ -98,6 +99,22 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [show, dispatch])
|
}, [show, dispatch])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (promptType) {
|
||||||
|
getAvailablePromptsApi.request({ tags: promptType === 'template' ? 'StringPromptTemplate&' : 'ChatPromptTemplate&' })
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [promptType])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (getAvailablePromptsApi.data && getAvailablePromptsApi.data.repos) {
|
||||||
|
setAvailablePrompNameList(getAvailablePromptsApi.data.repos)
|
||||||
|
if (getAvailablePromptsApi.data.repos?.length) handleListItemClick(0, getAvailablePromptsApi.data.repos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [getAvailablePromptsApi.data])
|
||||||
|
|
||||||
const ITEM_HEIGHT = 48
|
const ITEM_HEIGHT = 48
|
||||||
const ITEM_PADDING_TOP = 8
|
const ITEM_PADDING_TOP = 8
|
||||||
const MenuProps = {
|
const MenuProps = {
|
||||||
@@ -156,7 +173,6 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
const [availablePrompNameList, setAvailablePrompNameList] = useState([])
|
const [availablePrompNameList, setAvailablePrompNameList] = useState([])
|
||||||
const [selectedPrompt, setSelectedPrompt] = useState({})
|
const [selectedPrompt, setSelectedPrompt] = useState({})
|
||||||
|
|
||||||
const [credentialId, setCredentialId] = useState('')
|
|
||||||
const [accordionExpanded, setAccordionExpanded] = useState(['prompt'])
|
const [accordionExpanded, setAccordionExpanded] = useState(['prompt'])
|
||||||
|
|
||||||
const handleAccordionChange = (accordionName) => (event, isExpanded) => {
|
const handleAccordionChange = (accordionName) => (event, isExpanded) => {
|
||||||
@@ -173,7 +189,6 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
|
|
||||||
if (!prompt.detailed) {
|
if (!prompt.detailed) {
|
||||||
const createResp = await promptApi.getPrompt({
|
const createResp = await promptApi.getPrompt({
|
||||||
credential: credentialId,
|
|
||||||
promptName: prompt.full_name
|
promptName: prompt.full_name
|
||||||
})
|
})
|
||||||
if (createResp.data) {
|
if (createResp.data) {
|
||||||
@@ -194,14 +209,7 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
language.forEach((item) => {
|
language.forEach((item) => {
|
||||||
tags += `tags=${item.name}&`
|
tags += `tags=${item.name}&`
|
||||||
})
|
})
|
||||||
const createResp = await promptApi.getAvailablePrompts({
|
getAvailablePromptsApi.request({ tags: tags })
|
||||||
credential: credentialId,
|
|
||||||
tags: tags
|
|
||||||
})
|
|
||||||
if (createResp.data) {
|
|
||||||
setAvailablePrompNameList(createResp.data.repos)
|
|
||||||
if (createResp.data.repos?.length) await handleListItemClick(0, createResp.data.repos)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeDuplicates = (value) => {
|
const removeDuplicates = (value) => {
|
||||||
@@ -238,176 +246,139 @@ const PromptLangsmithHubDialog = ({ promptType, show, onCancel, onSubmit }) => {
|
|||||||
setLanguage(removeDuplicates(value))
|
setLanguage(removeDuplicates(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
const clear = () => {
|
|
||||||
setModelName([])
|
|
||||||
setUsecase([])
|
|
||||||
setLanguage([])
|
|
||||||
setSelectedPrompt({})
|
|
||||||
setAvailablePrompNameList([])
|
|
||||||
setAccordionExpanded(['prompt'])
|
|
||||||
}
|
|
||||||
|
|
||||||
const component = show ? (
|
const component = show ? (
|
||||||
<Dialog
|
<Dialog
|
||||||
onClose={onCancel}
|
onClose={onCancel}
|
||||||
open={show}
|
open={show}
|
||||||
fullWidth
|
fullWidth
|
||||||
maxWidth={credentialId ? 'lg' : 'sm'}
|
maxWidth={'lg'}
|
||||||
aria-labelledby='prompt-dialog-title'
|
aria-labelledby='prompt-dialog-title'
|
||||||
aria-describedby='prompt-dialog-description'
|
aria-describedby='prompt-dialog-description'
|
||||||
>
|
>
|
||||||
<DialogTitle sx={{ fontSize: '1rem' }} id='prompt-dialog-title'>
|
<DialogTitle sx={{ fontSize: '1rem' }} id='prompt-dialog-title'>
|
||||||
Load Prompts from Langsmith Hub ({promptType === 'template' ? 'PromptTemplate' : 'ChatPromptTemplate'})
|
Langchain Hub ({promptType === 'template' ? 'PromptTemplate' : 'ChatPromptTemplate'})
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent dividers sx={{ p: 1 }}>
|
<DialogContent dividers sx={{ p: 1 }}>
|
||||||
<Box sx={{ width: credentialId ? '40%' : '100%', display: 'flex', flexDirection: 'row', p: 2, alignItems: 'center' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'row', p: 2, pt: 1, alignItems: 'center' }}>
|
||||||
<Typography sx={{ mr: 2 }}>
|
<FormControl sx={{ mr: 1, width: '30%' }}>
|
||||||
Langsmith Credential
|
<InputLabel size='small' id='model-checkbox-label'>
|
||||||
<span style={{ color: 'red' }}>*</span>
|
Model
|
||||||
</Typography>
|
</InputLabel>
|
||||||
<FormControl sx={{ flex: 1 }}>
|
<Select
|
||||||
<CredentialInputHandler
|
id='model-checkbox'
|
||||||
|
labelId='model-checkbox-label'
|
||||||
|
multiple
|
||||||
size='small'
|
size='small'
|
||||||
sx={{ flexGrow: 1 }}
|
value={modelName}
|
||||||
key={credentialId}
|
onChange={handleModelChange}
|
||||||
data={credentialId ? { credential: credentialId } : {}}
|
input={<OutlinedInput label='Model' />}
|
||||||
inputParam={{
|
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
||||||
label: 'Connect Credential',
|
endAdornment={
|
||||||
name: 'credential',
|
modelName.length ? (
|
||||||
type: 'credential',
|
<IconButton sx={{ mr: 2 }} onClick={() => setModelName([])}>
|
||||||
credentialNames: ['langsmithApi']
|
<ClearIcon style={{ width: 20, height: 20 }} />
|
||||||
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
'.MuiSvgIcon-root ': {
|
||||||
|
fill: customization.isDarkMode ? 'white !important' : ''
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onSelect={(newValue) => {
|
MenuProps={MenuProps}
|
||||||
setCredentialId(newValue)
|
>
|
||||||
if (!newValue) clear()
|
{models.map((variant) => (
|
||||||
|
<MenuItem key={variant.id} value={variant}>
|
||||||
|
<Checkbox id={variant.id} checked={modelName.findIndex((item) => item.id === variant.id) >= 0} />
|
||||||
|
<ListItemText primary={variant.name} />
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl sx={{ mr: 1, width: '30%' }}>
|
||||||
|
<InputLabel size='small' id='usecase-checkbox-label'>
|
||||||
|
Usecase
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
autoWidth={false}
|
||||||
|
labelId='usecase-checkbox-label'
|
||||||
|
id='usecase-checkbox'
|
||||||
|
multiple
|
||||||
|
size='small'
|
||||||
|
value={usecase}
|
||||||
|
onChange={handleUsecaseChange}
|
||||||
|
input={<OutlinedInput label='Usecase' />}
|
||||||
|
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
||||||
|
endAdornment={
|
||||||
|
usecase.length ? (
|
||||||
|
<IconButton sx={{ mr: 2 }} onClick={() => setUsecase([])}>
|
||||||
|
<ClearIcon style={{ width: 20, height: 20 }} />
|
||||||
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
'.MuiSvgIcon-root ': {
|
||||||
|
fill: customization.isDarkMode ? 'white !important' : ''
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
MenuProps={MenuProps}
|
||||||
|
>
|
||||||
|
{usecases.map((variant) => (
|
||||||
|
<MenuItem key={variant.id} value={variant}>
|
||||||
|
<Checkbox id={variant.id} checked={usecase.findIndex((item) => item.id === variant.id) >= 0} />
|
||||||
|
<ListItemText primary={variant.name} />
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl sx={{ mr: 1, width: '30%' }}>
|
||||||
|
<InputLabel size='small' id='language-checkbox-label'>
|
||||||
|
Language
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId='language-checkbox-label'
|
||||||
|
id='language-checkbox'
|
||||||
|
multiple
|
||||||
|
size='small'
|
||||||
|
value={language}
|
||||||
|
onChange={handleLanguageChange}
|
||||||
|
input={<OutlinedInput label='language' />}
|
||||||
|
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
||||||
|
endAdornment={
|
||||||
|
language.length ? (
|
||||||
|
<IconButton sx={{ mr: 2 }} onClick={() => setLanguage([])}>
|
||||||
|
<ClearIcon style={{ width: 20, height: 20 }} />
|
||||||
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
'.MuiSvgIcon-root ': {
|
||||||
|
fill: customization.isDarkMode ? 'white !important' : ''
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
MenuProps={MenuProps}
|
||||||
|
>
|
||||||
|
{languages.map((variant) => (
|
||||||
|
<MenuItem key={variant.id} value={variant}>
|
||||||
|
<Checkbox id={variant.id} checked={language.findIndex((item) => item.id === variant.id) >= 0} />
|
||||||
|
<ListItemText primary={variant.name} />
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl sx={{ width: '10%' }}>
|
||||||
|
<Button disableElevation variant='outlined' onClick={fetchPrompts}>
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
{credentialId && (
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'row', p: 2, pt: 1, alignItems: 'center' }}>
|
|
||||||
<FormControl sx={{ mr: 1, width: '30%' }}>
|
|
||||||
<InputLabel size='small' id='model-checkbox-label'>
|
|
||||||
Model
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
disabled={!credentialId}
|
|
||||||
id='model-checkbox'
|
|
||||||
labelId='model-checkbox-label'
|
|
||||||
multiple
|
|
||||||
size='small'
|
|
||||||
value={modelName}
|
|
||||||
onChange={handleModelChange}
|
|
||||||
input={<OutlinedInput label='Model' />}
|
|
||||||
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
|
||||||
endAdornment={
|
|
||||||
modelName.length ? (
|
|
||||||
<IconButton sx={{ mr: 2 }} onClick={() => setModelName([])}>
|
|
||||||
<ClearIcon style={{ width: 20, height: 20 }} />
|
|
||||||
</IconButton>
|
|
||||||
) : (
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sx={{
|
|
||||||
'.MuiSvgIcon-root ': {
|
|
||||||
fill: customization.isDarkMode ? 'white !important' : ''
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
MenuProps={MenuProps}
|
|
||||||
>
|
|
||||||
{models.map((variant) => (
|
|
||||||
<MenuItem key={variant.id} value={variant}>
|
|
||||||
<Checkbox id={variant.id} checked={modelName.findIndex((item) => item.id === variant.id) >= 0} />
|
|
||||||
<ListItemText primary={variant.name} />
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl sx={{ mr: 1, width: '30%' }}>
|
|
||||||
<InputLabel size='small' id='usecase-checkbox-label'>
|
|
||||||
Usecase
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
autoWidth={false}
|
|
||||||
disabled={!credentialId}
|
|
||||||
labelId='usecase-checkbox-label'
|
|
||||||
id='usecase-checkbox'
|
|
||||||
multiple
|
|
||||||
size='small'
|
|
||||||
value={usecase}
|
|
||||||
onChange={handleUsecaseChange}
|
|
||||||
input={<OutlinedInput label='Usecase' />}
|
|
||||||
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
|
||||||
endAdornment={
|
|
||||||
usecase.length ? (
|
|
||||||
<IconButton sx={{ mr: 2 }} onClick={() => setUsecase([])}>
|
|
||||||
<ClearIcon style={{ width: 20, height: 20 }} />
|
|
||||||
</IconButton>
|
|
||||||
) : (
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sx={{
|
|
||||||
'.MuiSvgIcon-root ': {
|
|
||||||
fill: customization.isDarkMode ? 'white !important' : ''
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
MenuProps={MenuProps}
|
|
||||||
>
|
|
||||||
{usecases.map((variant) => (
|
|
||||||
<MenuItem key={variant.id} value={variant}>
|
|
||||||
<Checkbox id={variant.id} checked={usecase.findIndex((item) => item.id === variant.id) >= 0} />
|
|
||||||
<ListItemText primary={variant.name} />
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl sx={{ mr: 1, width: '30%' }}>
|
|
||||||
<InputLabel size='small' id='language-checkbox-label'>
|
|
||||||
Language
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId='language-checkbox-label'
|
|
||||||
id='language-checkbox'
|
|
||||||
disabled={!credentialId}
|
|
||||||
multiple
|
|
||||||
size='small'
|
|
||||||
value={language}
|
|
||||||
onChange={handleLanguageChange}
|
|
||||||
input={<OutlinedInput label='language' />}
|
|
||||||
renderValue={(selected) => selected.map((x) => x.name).join(', ')}
|
|
||||||
endAdornment={
|
|
||||||
language.length ? (
|
|
||||||
<IconButton sx={{ mr: 2 }} onClick={() => setLanguage([])}>
|
|
||||||
<ClearIcon style={{ width: 20, height: 20 }} />
|
|
||||||
</IconButton>
|
|
||||||
) : (
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sx={{
|
|
||||||
'.MuiSvgIcon-root ': {
|
|
||||||
fill: customization.isDarkMode ? 'white !important' : ''
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
MenuProps={MenuProps}
|
|
||||||
>
|
|
||||||
{languages.map((variant) => (
|
|
||||||
<MenuItem key={variant.id} value={variant}>
|
|
||||||
<Checkbox id={variant.id} checked={language.findIndex((item) => item.id === variant.id) >= 0} />
|
|
||||||
<ListItemText primary={variant.name} />
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl sx={{ width: '10%' }}>
|
|
||||||
<Button disableElevation variant='outlined' onClick={fetchPrompts}>
|
|
||||||
Search
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{availablePrompNameList && availablePrompNameList.length == 0 && (
|
{availablePrompNameList && availablePrompNameList.length == 0 && (
|
||||||
<Stack sx={{ alignItems: 'center', justifyContent: 'center', width: '100%', pb: 3 }} flexDirection='column'>
|
<Stack sx={{ alignItems: 'center', justifyContent: 'center', width: '100%', pb: 3 }} flexDirection='column'>
|
||||||
<Box sx={{ p: 5, height: 'auto' }}>
|
<Box sx={{ p: 5, height: 'auto' }}>
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
|
|||||||
onClick={() => onShowPromptHubButtonClicked()}
|
onClick={() => onShowPromptHubButtonClicked()}
|
||||||
endIcon={<IconAutoFixHigh />}
|
endIcon={<IconAutoFixHigh />}
|
||||||
>
|
>
|
||||||
Langsmith Prompt Hub
|
Langchain Hub
|
||||||
</Button>
|
</Button>
|
||||||
<PromptLangsmithHubDialog
|
<PromptLangsmithHubDialog
|
||||||
promptType={inputParam.name}
|
promptType={inputParam.name}
|
||||||
|
|||||||
Reference in New Issue
Block a user