mirror of
https://github.com/langgenius/dify.git
synced 2026-03-28 01:29:55 +08:00
feat: Add suggested questions to context generate modal
This commit is contained in:
@ -1,10 +1,11 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import type { CodeLanguage } from '../../code/types'
|
import type { CodeLanguage } from '../../code/types'
|
||||||
|
import type { ContextGenerateModalHandle } from '../../tool/components/context-generate-modal'
|
||||||
import type { GenRes } from '@/service/debug'
|
import type { GenRes } from '@/service/debug'
|
||||||
import { useBoolean } from 'ahooks'
|
import { useBoolean } from 'ahooks'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo, useRef } from 'react'
|
||||||
import { GetCodeGeneratorResModal } from '@/app/components/app/configuration/config/code-generator/get-code-generator-res'
|
import { GetCodeGeneratorResModal } from '@/app/components/app/configuration/config/code-generator/get-code-generator-res'
|
||||||
import { ActionButton } from '@/app/components/base/action-button'
|
import { ActionButton } from '@/app/components/base/action-button'
|
||||||
import { Generator } from '@/app/components/base/icons/src/vender/other'
|
import { Generator } from '@/app/components/base/icons/src/vender/other'
|
||||||
@ -32,6 +33,7 @@ const CodeGenerateBtn: FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
|
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
|
||||||
const nodes = useStore(s => s.nodes)
|
const nodes = useStore(s => s.nodes)
|
||||||
|
const contextGenerateModalRef = useRef<ContextGenerateModalHandle>(null)
|
||||||
const handleAutomaticRes = useCallback((res: GenRes) => {
|
const handleAutomaticRes = useCallback((res: GenRes) => {
|
||||||
onGenerated?.(res.modified)
|
onGenerated?.(res.modified)
|
||||||
showAutomaticFalse()
|
showAutomaticFalse()
|
||||||
@ -64,11 +66,20 @@ const CodeGenerateBtn: FC<Props> = ({
|
|||||||
}
|
}
|
||||||
}, [nodeId, nodes, parseExtractorNodeId])
|
}, [nodeId, nodes, parseExtractorNodeId])
|
||||||
|
|
||||||
|
const handleOpenAutomatic = useCallback(() => {
|
||||||
|
showAutomaticTrue()
|
||||||
|
if (!contextGenerateConfig)
|
||||||
|
return
|
||||||
|
setTimeout(() => {
|
||||||
|
contextGenerateModalRef.current?.onOpen()
|
||||||
|
}, 0)
|
||||||
|
}, [contextGenerateConfig, showAutomaticTrue])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn(className)}>
|
<div className={cn(className)}>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className="hover:bg-[#155EFF]/8"
|
className="hover:bg-[#155EFF]/8"
|
||||||
onClick={showAutomaticTrue}
|
onClick={handleOpenAutomatic}
|
||||||
>
|
>
|
||||||
<Generator className="h-4 w-4 text-primary-600" />
|
<Generator className="h-4 w-4 text-primary-600" />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
@ -76,6 +87,7 @@ const CodeGenerateBtn: FC<Props> = ({
|
|||||||
contextGenerateConfig
|
contextGenerateConfig
|
||||||
? (
|
? (
|
||||||
<ContextGenerateModal
|
<ContextGenerateModal
|
||||||
|
ref={contextGenerateModalRef}
|
||||||
isShow={showAutomatic}
|
isShow={showAutomatic}
|
||||||
onClose={showAutomaticFalse}
|
onClose={showAutomaticFalse}
|
||||||
toolNodeId={contextGenerateConfig.toolNodeId}
|
toolNodeId={contextGenerateConfig.toolNodeId}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
|
||||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
import type { TriggerProps } from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger'
|
import type { TriggerProps } from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger'
|
||||||
import type { CodeNodeType, OutputVar } from '@/app/components/workflow/nodes/code/types'
|
import type { CodeNodeType, OutputVar } from '@/app/components/workflow/nodes/code/types'
|
||||||
@ -9,7 +8,7 @@ import { RiArrowDownSLine, RiArrowRightLine, RiCheckLine, RiCloseLine, RiRefresh
|
|||||||
import { useEventListener, useSessionStorageState, useSize } from 'ahooks'
|
import { useEventListener, useSessionStorageState, useSize } from 'ahooks'
|
||||||
import useBoolean from 'ahooks/lib/useBoolean'
|
import useBoolean from 'ahooks/lib/useBoolean'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
@ -32,7 +31,8 @@ import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
|||||||
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
import { NodeRunningStatus, VarType } from '@/app/components/workflow/types'
|
import { NodeRunningStatus, VarType } from '@/app/components/workflow/types'
|
||||||
import { renderI18nObject } from '@/i18n-config'
|
import { renderI18nObject } from '@/i18n-config'
|
||||||
import { generateContext } from '@/service/debug'
|
import { languages } from '@/i18n-config/language'
|
||||||
|
import { fetchContextGenerateSuggestedQuestions, generateContext } from '@/service/debug'
|
||||||
import { AppModeEnum } from '@/types/app'
|
import { AppModeEnum } from '@/types/app'
|
||||||
import { cn } from '@/utils/classnames'
|
import { cn } from '@/utils/classnames'
|
||||||
import useContextGenData from './use-context-gen-data'
|
import useContextGenData from './use-context-gen-data'
|
||||||
@ -49,6 +49,10 @@ type ContextGenerateChatMessage = ContextGenerateMessage & {
|
|||||||
durationMs?: number
|
durationMs?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ContextGenerateModalHandle = {
|
||||||
|
onOpen: () => void
|
||||||
|
}
|
||||||
|
|
||||||
const minCodeHeight = 80
|
const minCodeHeight = 80
|
||||||
const minOutputHeight = 80
|
const minOutputHeight = 80
|
||||||
const splitHandleHeight = 4
|
const splitHandleHeight = 4
|
||||||
@ -93,13 +97,13 @@ const mapOutputsToResponse = (outputs?: OutputVar) => {
|
|||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContextGenerateModal: FC<Props> = ({
|
const ContextGenerateModal = forwardRef<ContextGenerateModalHandle, Props>(({
|
||||||
isShow,
|
isShow,
|
||||||
onClose,
|
onClose,
|
||||||
toolNodeId,
|
toolNodeId,
|
||||||
paramKey,
|
paramKey,
|
||||||
codeNodeId,
|
codeNodeId,
|
||||||
}) => {
|
}, ref) => {
|
||||||
const { t, i18n } = useTranslation()
|
const { t, i18n } = useTranslation()
|
||||||
const configsMap = useHooksStore(s => s.configsMap)
|
const configsMap = useHooksStore(s => s.configsMap)
|
||||||
const nodes = useStore(s => s.nodes)
|
const nodes = useStore(s => s.nodes)
|
||||||
@ -149,7 +153,22 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
{ defaultValue: [] },
|
{ defaultValue: [] },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const [suggestedQuestions, setSuggestedQuestions] = useSessionStorageState<string[]>(
|
||||||
|
`${storageKey}-suggested-questions`,
|
||||||
|
{ defaultValue: [] },
|
||||||
|
)
|
||||||
|
const [hasFetchedSuggestions, setHasFetchedSuggestions] = useSessionStorageState<boolean>(
|
||||||
|
`${storageKey}-suggested-questions-fetched`,
|
||||||
|
{ defaultValue: false },
|
||||||
|
)
|
||||||
|
const [isFetchingSuggestions, { setTrue: setFetchingSuggestionsTrue, setFalse: setFetchingSuggestionsFalse }] = useBoolean(false)
|
||||||
|
const suggestedQuestionsAbortControllerRef = useRef<AbortController | null>(null)
|
||||||
|
|
||||||
const language = useMemo(() => (i18n.language || 'en-US').replace('-', '_'), [i18n.language])
|
const language = useMemo(() => (i18n.language || 'en-US').replace('-', '_'), [i18n.language])
|
||||||
|
const promptLanguage = useMemo(() => {
|
||||||
|
const matched = languages.find(item => item.value === i18n.language)
|
||||||
|
return matched?.prompt_name || 'English'
|
||||||
|
}, [i18n.language])
|
||||||
const [inputValue, setInputValue] = useState('')
|
const [inputValue, setInputValue] = useState('')
|
||||||
const [isGenerating, { setTrue: setGeneratingTrue, setFalse: setGeneratingFalse }] = useBoolean(false)
|
const [isGenerating, { setTrue: setGeneratingTrue, setFalse: setGeneratingFalse }] = useBoolean(false)
|
||||||
const [modelOverride, setModelOverride] = useState<Model | null>(() => {
|
const [modelOverride, setModelOverride] = useState<Model | null>(() => {
|
||||||
@ -213,6 +232,8 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
const hasHistory = (versions?.length ?? 0) > 0 || promptMessageCount > 0
|
const hasHistory = (versions?.length ?? 0) > 0 || promptMessageCount > 0
|
||||||
const isInitView = !isGenerating && !hasHistory
|
const isInitView = !isGenerating && !hasHistory
|
||||||
const defaultAssistantMessage = t('nodes.tool.contextGenerate.defaultAssistantMessage', { ns: 'workflow' })
|
const defaultAssistantMessage = t('nodes.tool.contextGenerate.defaultAssistantMessage', { ns: 'workflow' })
|
||||||
|
const shouldShowSuggestedSkeleton = isInitView && !hasFetchedSuggestions
|
||||||
|
const suggestedQuestionsSafe = suggestedQuestions ?? []
|
||||||
const suggestedSkeletonItems = useMemo(() => ([
|
const suggestedSkeletonItems = useMemo(() => ([
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -255,6 +276,95 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
clearVersions()
|
clearVersions()
|
||||||
}, [clearVersions, isGenerating, setPromptMessages])
|
}, [clearVersions, isGenerating, setPromptMessages])
|
||||||
|
|
||||||
|
const handleSuggestedQuestionClick = useCallback((question: string) => {
|
||||||
|
setInputValue(question)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleFetchSuggestedQuestions = useCallback(async () => {
|
||||||
|
if (!flowId || !toolNodeId || !paramKey)
|
||||||
|
return
|
||||||
|
if (!model.name || !model.provider)
|
||||||
|
return
|
||||||
|
if (hasFetchedSuggestions || isFetchingSuggestions || !isInitView)
|
||||||
|
return
|
||||||
|
|
||||||
|
setFetchingSuggestionsTrue()
|
||||||
|
let shouldMarkFetched = true
|
||||||
|
suggestedQuestionsAbortControllerRef.current?.abort()
|
||||||
|
try {
|
||||||
|
const response = await fetchContextGenerateSuggestedQuestions({
|
||||||
|
workflow_id: flowId,
|
||||||
|
node_id: toolNodeId,
|
||||||
|
parameter_name: paramKey,
|
||||||
|
language: promptLanguage,
|
||||||
|
model_config: {
|
||||||
|
provider: model.provider,
|
||||||
|
name: model.name,
|
||||||
|
completion_params: model.completion_params,
|
||||||
|
},
|
||||||
|
}, (abortController) => {
|
||||||
|
suggestedQuestionsAbortControllerRef.current = abortController
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.error) {
|
||||||
|
shouldMarkFetched = false
|
||||||
|
Toast.notify({
|
||||||
|
type: 'error',
|
||||||
|
message: t('modal.errors.networkError', { ns: 'pluginTrigger' }),
|
||||||
|
})
|
||||||
|
setSuggestedQuestions([])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextQuestions = (response.questions || []).filter(question => question && question.trim())
|
||||||
|
setSuggestedQuestions(nextQuestions)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (String(error).includes('AbortError')) {
|
||||||
|
shouldMarkFetched = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
shouldMarkFetched = false
|
||||||
|
Toast.notify({
|
||||||
|
type: 'error',
|
||||||
|
message: t('modal.errors.networkError', { ns: 'pluginTrigger' }),
|
||||||
|
})
|
||||||
|
setSuggestedQuestions([])
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (shouldMarkFetched)
|
||||||
|
setHasFetchedSuggestions(true)
|
||||||
|
setFetchingSuggestionsFalse()
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
flowId,
|
||||||
|
hasFetchedSuggestions,
|
||||||
|
isFetchingSuggestions,
|
||||||
|
isInitView,
|
||||||
|
model.completion_params,
|
||||||
|
model.name,
|
||||||
|
model.provider,
|
||||||
|
paramKey,
|
||||||
|
promptLanguage,
|
||||||
|
setFetchingSuggestionsFalse,
|
||||||
|
setFetchingSuggestionsTrue,
|
||||||
|
setHasFetchedSuggestions,
|
||||||
|
setSuggestedQuestions,
|
||||||
|
t,
|
||||||
|
toolNodeId,
|
||||||
|
])
|
||||||
|
|
||||||
|
const handleCloseModal = useCallback(() => {
|
||||||
|
suggestedQuestionsAbortControllerRef.current?.abort()
|
||||||
|
onClose()
|
||||||
|
}, [onClose])
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
onOpen: () => {
|
||||||
|
void handleFetchSuggestedQuestions()
|
||||||
|
},
|
||||||
|
}), [handleFetchSuggestedQuestions])
|
||||||
|
|
||||||
const renderModelTrigger = useCallback((params: TriggerProps) => {
|
const renderModelTrigger = useCallback((params: TriggerProps) => {
|
||||||
const label = params.currentModel?.label
|
const label = params.currentModel?.label
|
||||||
? renderI18nObject(params.currentModel.label, language)
|
? renderI18nObject(params.currentModel.label, language)
|
||||||
@ -396,8 +506,8 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (closeOnApply)
|
if (closeOnApply)
|
||||||
onClose()
|
handleCloseModal()
|
||||||
}, [codeNodeData, codeNodeId, current, handleNodeDataUpdateWithSyncDraft, onClose])
|
}, [codeNodeData, codeNodeId, current, handleCloseModal, handleNodeDataUpdateWithSyncDraft])
|
||||||
|
|
||||||
const handleRun = useCallback(() => {
|
const handleRun = useCallback(() => {
|
||||||
if (!codeNodeId)
|
if (!codeNodeId)
|
||||||
@ -475,7 +585,7 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isShow={isShow}
|
isShow={isShow}
|
||||||
onClose={onClose}
|
onClose={handleCloseModal}
|
||||||
className={cn(
|
className={cn(
|
||||||
'max-w-[calc(100vw-32px)] border-[0.5px] border-components-panel-border bg-background-body !p-0 shadow-xl shadow-shadow-shadow-5',
|
'max-w-[calc(100vw-32px)] border-[0.5px] border-components-panel-border bg-background-body !p-0 shadow-xl shadow-shadow-shadow-5',
|
||||||
isInitView ? 'w-[1280px]' : 'w-[1200px]',
|
isInitView ? 'w-[1280px]' : 'w-[1200px]',
|
||||||
@ -565,15 +675,28 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-px px-2">
|
<div className="flex flex-col gap-px px-2">
|
||||||
<div className="flex items-center px-3 pb-2 pt-4">
|
<div className="flex items-center px-3 pb-2 pt-4">
|
||||||
<SkeletonRectangle className="h-3 w-20" />
|
<span className="text-xs font-semibold uppercase text-text-tertiary">
|
||||||
|
{t('nodes.tool.contextGenerate.suggestedQuestionsTitle', { ns: 'workflow' })}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1 px-3">
|
<div className="flex flex-col gap-1 px-3">
|
||||||
{suggestedSkeletonItems.map(item => (
|
{shouldShowSuggestedSkeleton && suggestedSkeletonItems.map(item => (
|
||||||
<SkeletonRow key={item} className="py-1">
|
<SkeletonRow key={item} className="py-1">
|
||||||
<div className="h-4 w-4 rounded-sm bg-divider-subtle opacity-60" />
|
<div className="h-4 w-4 rounded-sm bg-divider-subtle opacity-60" />
|
||||||
<SkeletonRectangle className="h-3 w-[260px]" />
|
<SkeletonRectangle className="h-3 w-[260px]" />
|
||||||
</SkeletonRow>
|
</SkeletonRow>
|
||||||
))}
|
))}
|
||||||
|
{!shouldShowSuggestedSkeleton && suggestedQuestionsSafe.map((question, index) => (
|
||||||
|
<button
|
||||||
|
key={`${question}-${index}`}
|
||||||
|
type="button"
|
||||||
|
className="flex items-start gap-2 rounded-lg px-2 py-1 text-left text-sm text-text-secondary transition hover:bg-state-base-hover"
|
||||||
|
onClick={() => handleSuggestedQuestionClick(question)}
|
||||||
|
>
|
||||||
|
<span className="mt-1 h-1.5 w-1.5 shrink-0 rounded-full bg-divider-regular" />
|
||||||
|
<span className="flex-1 whitespace-pre-wrap">{question}</span>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -716,7 +839,7 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
>
|
>
|
||||||
{isInitView && (
|
{isInitView && (
|
||||||
<div className="flex h-10 items-center justify-end px-3 py-1">
|
<div className="flex h-10 items-center justify-end px-3 py-1">
|
||||||
<ActionButton size="m" className="!h-8 !w-8" onClick={onClose}>
|
<ActionButton size="m" className="!h-8 !w-8" onClick={handleCloseModal}>
|
||||||
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
|
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
@ -804,7 +927,7 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
{t('nodes.tool.contextGenerate.apply', { ns: 'workflow' })}
|
{t('nodes.tool.contextGenerate.apply', { ns: 'workflow' })}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="mx-1 h-4 w-px bg-divider-regular" />
|
<div className="mx-1 h-4 w-px bg-divider-regular" />
|
||||||
<ActionButton size="m" className="!h-8 !w-8" onClick={onClose}>
|
<ActionButton size="m" className="!h-8 !w-8" onClick={handleCloseModal}>
|
||||||
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
|
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
@ -897,6 +1020,8 @@ const ContextGenerateModal: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
|
ContextGenerateModal.displayName = 'ContextGenerateModal'
|
||||||
|
|
||||||
export default React.memo(ContextGenerateModal)
|
export default React.memo(ContextGenerateModal)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import type { ContextGenerateModalHandle } from '../context-generate-modal'
|
||||||
import type { DetectedAgent } from './hooks'
|
import type { DetectedAgent } from './hooks'
|
||||||
import type { AgentNode, WorkflowVariableBlockType } from '@/app/components/base/prompt-editor/types'
|
import type { AgentNode, WorkflowVariableBlockType } from '@/app/components/base/prompt-editor/types'
|
||||||
import type { StrategyDetail, StrategyPluginDetail } from '@/app/components/plugins/types'
|
import type { StrategyDetail, StrategyPluginDetail } from '@/app/components/plugins/types'
|
||||||
@ -13,6 +14,7 @@ import {
|
|||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -91,6 +93,7 @@ const MixedVariableTextInput = ({
|
|||||||
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
|
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
|
||||||
const [isSubGraphModalOpen, setIsSubGraphModalOpen] = useState(false)
|
const [isSubGraphModalOpen, setIsSubGraphModalOpen] = useState(false)
|
||||||
const [isContextGenerateModalOpen, setIsContextGenerateModalOpen] = useState(false)
|
const [isContextGenerateModalOpen, setIsContextGenerateModalOpen] = useState(false)
|
||||||
|
const contextGenerateModalRef = useRef<ContextGenerateModalHandle>(null)
|
||||||
|
|
||||||
const nodesByIdMap = useMemo(() => {
|
const nodesByIdMap = useMemo(() => {
|
||||||
return availableNodes.reduce((acc, node) => {
|
return availableNodes.reduce((acc, node) => {
|
||||||
@ -319,6 +322,9 @@ const MixedVariableTextInput = ({
|
|||||||
onChange?.(assemblePlaceholder, VarKindTypeEnum.mixed, null)
|
onChange?.(assemblePlaceholder, VarKindTypeEnum.mixed, null)
|
||||||
setControlPromptEditorRerenderKey(Date.now())
|
setControlPromptEditorRerenderKey(Date.now())
|
||||||
setIsContextGenerateModalOpen(true)
|
setIsContextGenerateModalOpen(true)
|
||||||
|
setTimeout(() => {
|
||||||
|
contextGenerateModalRef.current?.onOpen()
|
||||||
|
}, 0)
|
||||||
return [extractorNodeId, 'result']
|
return [extractorNodeId, 'result']
|
||||||
}, [assembleExtractorNodeId, assemblePlaceholder, ensureAssembleExtractorNode, onChange, paramKey, setControlPromptEditorRerenderKey, toolNodeId])
|
}, [assembleExtractorNodeId, assemblePlaceholder, ensureAssembleExtractorNode, onChange, paramKey, setControlPromptEditorRerenderKey, toolNodeId])
|
||||||
|
|
||||||
@ -439,6 +445,7 @@ const MixedVariableTextInput = ({
|
|||||||
)}
|
)}
|
||||||
{toolNodeId && paramKey && (
|
{toolNodeId && paramKey && (
|
||||||
<ContextGenerateModal
|
<ContextGenerateModal
|
||||||
|
ref={contextGenerateModalRef}
|
||||||
isShow={isContextGenerateModalOpen}
|
isShow={isContextGenerateModalOpen}
|
||||||
onClose={handleCloseContextGenerateModal}
|
onClose={handleCloseContextGenerateModal}
|
||||||
toolNodeId={toolNodeId}
|
toolNodeId={toolNodeId}
|
||||||
|
|||||||
@ -805,6 +805,7 @@
|
|||||||
"nodes.tool.contextGenerate.run": "Run",
|
"nodes.tool.contextGenerate.run": "Run",
|
||||||
"nodes.tool.contextGenerate.running": "Running",
|
"nodes.tool.contextGenerate.running": "Running",
|
||||||
"nodes.tool.contextGenerate.subtitle": "Assemble multiple variables into one from previous nodes",
|
"nodes.tool.contextGenerate.subtitle": "Assemble multiple variables into one from previous nodes",
|
||||||
|
"nodes.tool.contextGenerate.suggestedQuestionsTitle": "Suggested Questions",
|
||||||
"nodes.tool.contextGenerate.title": "Assemble Variables",
|
"nodes.tool.contextGenerate.title": "Assemble Variables",
|
||||||
"nodes.tool.inputVars": "Input Variables",
|
"nodes.tool.inputVars": "Input Variables",
|
||||||
"nodes.tool.insertPlaceholder1": "Type or press",
|
"nodes.tool.insertPlaceholder1": "Type or press",
|
||||||
|
|||||||
@ -770,13 +770,20 @@
|
|||||||
"nodes.tool.contextGenerate.apply": "適用",
|
"nodes.tool.contextGenerate.apply": "適用",
|
||||||
"nodes.tool.contextGenerate.code": "コード",
|
"nodes.tool.contextGenerate.code": "コード",
|
||||||
"nodes.tool.contextGenerate.codeBlock": "コードブロック",
|
"nodes.tool.contextGenerate.codeBlock": "コードブロック",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.javascript": "JavaScript",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.python3": "Python 3",
|
||||||
"nodes.tool.contextGenerate.defaultAssistantMessage": "完了しました。確認してください。",
|
"nodes.tool.contextGenerate.defaultAssistantMessage": "完了しました。確認してください。",
|
||||||
|
"nodes.tool.contextGenerate.generatedCode": "生成されたコード",
|
||||||
"nodes.tool.contextGenerate.generating": "生成中...",
|
"nodes.tool.contextGenerate.generating": "生成中...",
|
||||||
|
"nodes.tool.contextGenerate.initPlaceholder": "上流ノードの変数の組み立て方を説明し、'/' を押して変数を挿入してください。",
|
||||||
"nodes.tool.contextGenerate.inputPlaceholder": "変更を依頼...",
|
"nodes.tool.contextGenerate.inputPlaceholder": "変更を依頼...",
|
||||||
"nodes.tool.contextGenerate.output": "出力",
|
"nodes.tool.contextGenerate.output": "出力",
|
||||||
"nodes.tool.contextGenerate.resizeHandle": "サイズ調整ハンドル",
|
"nodes.tool.contextGenerate.resizeHandle": "サイズ調整ハンドル",
|
||||||
"nodes.tool.contextGenerate.rightSidePlaceholder": "左側に指示を入力してください。生成されたコードがここに表示されます。",
|
"nodes.tool.contextGenerate.rightSidePlaceholder": "左側に指示を入力してください。生成されたコードがここに表示されます。",
|
||||||
"nodes.tool.contextGenerate.run": "実行",
|
"nodes.tool.contextGenerate.run": "実行",
|
||||||
|
"nodes.tool.contextGenerate.running": "実行中",
|
||||||
|
"nodes.tool.contextGenerate.subtitle": "前のノードの複数変数を1つにまとめる",
|
||||||
|
"nodes.tool.contextGenerate.suggestedQuestionsTitle": "おすすめ質問",
|
||||||
"nodes.tool.contextGenerate.title": "変数を組み立てる",
|
"nodes.tool.contextGenerate.title": "変数を組み立てる",
|
||||||
"nodes.tool.inputVars": "入力変数",
|
"nodes.tool.inputVars": "入力変数",
|
||||||
"nodes.tool.insertPlaceholder1": "タイプするか押してください",
|
"nodes.tool.insertPlaceholder1": "タイプするか押してください",
|
||||||
|
|||||||
@ -780,6 +780,25 @@
|
|||||||
"nodes.tool.agentPlaceholder": "告诉我 {{paramKey}}...",
|
"nodes.tool.agentPlaceholder": "告诉我 {{paramKey}}...",
|
||||||
"nodes.tool.assembleVariables": "组装变量",
|
"nodes.tool.assembleVariables": "组装变量",
|
||||||
"nodes.tool.authorize": "授权",
|
"nodes.tool.authorize": "授权",
|
||||||
|
"nodes.tool.contextGenerate.apply": "应用",
|
||||||
|
"nodes.tool.contextGenerate.code": "代码",
|
||||||
|
"nodes.tool.contextGenerate.codeBlock": "代码块",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.javascript": "JavaScript",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.python3": "Python 3",
|
||||||
|
"nodes.tool.contextGenerate.defaultAssistantMessage": "已完成,请检查。",
|
||||||
|
"nodes.tool.contextGenerate.generatedCode": "生成的代码",
|
||||||
|
"nodes.tool.contextGenerate.generating": "生成中...",
|
||||||
|
"nodes.tool.contextGenerate.initPlaceholder": "描述如何从上游节点组装变量,并按“/”插入变量。",
|
||||||
|
"nodes.tool.contextGenerate.inputPlaceholder": "输入修改需求...",
|
||||||
|
"nodes.tool.contextGenerate.instruction": "指令",
|
||||||
|
"nodes.tool.contextGenerate.output": "输出",
|
||||||
|
"nodes.tool.contextGenerate.resizeHandle": "调整大小把手",
|
||||||
|
"nodes.tool.contextGenerate.rightSidePlaceholder": "请在左侧输入指令。\n生成的代码将显示在这里。",
|
||||||
|
"nodes.tool.contextGenerate.run": "运行",
|
||||||
|
"nodes.tool.contextGenerate.running": "运行中",
|
||||||
|
"nodes.tool.contextGenerate.subtitle": "从之前的节点组装多个变量为一个",
|
||||||
|
"nodes.tool.contextGenerate.suggestedQuestionsTitle": "推荐问题",
|
||||||
|
"nodes.tool.contextGenerate.title": "组装变量",
|
||||||
"nodes.tool.inputVars": "输入变量",
|
"nodes.tool.inputVars": "输入变量",
|
||||||
"nodes.tool.insertPlaceholder1": "键入",
|
"nodes.tool.insertPlaceholder1": "键入",
|
||||||
"nodes.tool.insertPlaceholder2": "插入变量",
|
"nodes.tool.insertPlaceholder2": "插入变量",
|
||||||
|
|||||||
@ -770,14 +770,21 @@
|
|||||||
"nodes.tool.contextGenerate.apply": "套用",
|
"nodes.tool.contextGenerate.apply": "套用",
|
||||||
"nodes.tool.contextGenerate.code": "程式碼",
|
"nodes.tool.contextGenerate.code": "程式碼",
|
||||||
"nodes.tool.contextGenerate.codeBlock": "程式碼區塊",
|
"nodes.tool.contextGenerate.codeBlock": "程式碼區塊",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.javascript": "JavaScript",
|
||||||
|
"nodes.tool.contextGenerate.codeLanguage.python3": "Python 3",
|
||||||
"nodes.tool.contextGenerate.defaultAssistantMessage": "我已完成,請查看。",
|
"nodes.tool.contextGenerate.defaultAssistantMessage": "我已完成,請查看。",
|
||||||
|
"nodes.tool.contextGenerate.generatedCode": "生成的程式碼",
|
||||||
"nodes.tool.contextGenerate.generating": "生成中...",
|
"nodes.tool.contextGenerate.generating": "生成中...",
|
||||||
|
"nodes.tool.contextGenerate.initPlaceholder": "描述如何從上游節點組裝變數,並按「/」插入變數。",
|
||||||
"nodes.tool.contextGenerate.inputPlaceholder": "請求修改...",
|
"nodes.tool.contextGenerate.inputPlaceholder": "請求修改...",
|
||||||
"nodes.tool.contextGenerate.instruction": "指令",
|
"nodes.tool.contextGenerate.instruction": "指令",
|
||||||
"nodes.tool.contextGenerate.output": "輸出",
|
"nodes.tool.contextGenerate.output": "輸出",
|
||||||
"nodes.tool.contextGenerate.resizeHandle": "調整大小把手",
|
"nodes.tool.contextGenerate.resizeHandle": "調整大小把手",
|
||||||
"nodes.tool.contextGenerate.rightSidePlaceholder": "請在左側輸入指令。生成的程式碼將顯示在這裡。",
|
"nodes.tool.contextGenerate.rightSidePlaceholder": "請在左側輸入指令。生成的程式碼將顯示在這裡。",
|
||||||
"nodes.tool.contextGenerate.run": "執行",
|
"nodes.tool.contextGenerate.run": "執行",
|
||||||
|
"nodes.tool.contextGenerate.running": "執行中",
|
||||||
|
"nodes.tool.contextGenerate.subtitle": "從之前的節點組裝多個變數為一個",
|
||||||
|
"nodes.tool.contextGenerate.suggestedQuestionsTitle": "推薦問題",
|
||||||
"nodes.tool.contextGenerate.title": "組裝變數",
|
"nodes.tool.contextGenerate.title": "組裝變數",
|
||||||
"nodes.tool.inputVars": "輸入變數",
|
"nodes.tool.inputVars": "輸入變數",
|
||||||
"nodes.tool.insertPlaceholder1": "輸入或按壓",
|
"nodes.tool.insertPlaceholder1": "輸入或按壓",
|
||||||
|
|||||||
@ -58,6 +58,23 @@ export type ContextGenerateResponse = {
|
|||||||
error: string
|
error: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ContextGenerateSuggestedQuestionsRequest = {
|
||||||
|
workflow_id: string
|
||||||
|
node_id: string
|
||||||
|
parameter_name: string
|
||||||
|
language: string
|
||||||
|
model_config: {
|
||||||
|
provider: string
|
||||||
|
name: string
|
||||||
|
completion_params?: CompletionParams
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ContextGenerateSuggestedQuestionsResponse = {
|
||||||
|
questions: string[]
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
export type TextGenerationMessageFile = FileEntity & {
|
export type TextGenerationMessageFile = FileEntity & {
|
||||||
belongs_to?: 'assistant' | 'user' | string
|
belongs_to?: 'assistant' | 'user' | string
|
||||||
}
|
}
|
||||||
@ -149,6 +166,18 @@ export const generateContext = (body: ContextGenerateRequest) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fetchContextGenerateSuggestedQuestions = (
|
||||||
|
body: ContextGenerateSuggestedQuestionsRequest,
|
||||||
|
getAbortController?: (abortController: AbortController) => void,
|
||||||
|
) => {
|
||||||
|
return post<ContextGenerateSuggestedQuestionsResponse>('/context-generate/suggested-questions', {
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
getAbortController,
|
||||||
|
silent: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const fetchModelParams = (providerName: string, modelId: string) => {
|
export const fetchModelParams = (providerName: string, modelId: string) => {
|
||||||
return get(`workspaces/current/model-providers/${providerName}/models/parameter-rules`, {
|
return get(`workspaces/current/model-providers/${providerName}/models/parameter-rules`, {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
Reference in New Issue
Block a user