mirror of
https://github.com/langgenius/dify.git
synced 2026-05-10 14:14:17 +08:00
Merge branch 'feat/support-agent-sandbox' of https://github.com/langgenius/dify into feat/support-agent-sandbox
This commit is contained in:
commit
c9edd71395
@ -1,6 +1,15 @@
|
||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { ToolParameter } from '@/app/components/tools/types'
|
||||
import type { CodeNodeType } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { ContextGenerateMessage, ContextGenerateResponse } from '@/service/debug'
|
||||
import type { ToolNodeType } from '@/app/components/workflow/nodes/tool/types'
|
||||
import type { Node, NodeOutPutVar, Var } from '@/app/components/workflow/types'
|
||||
import type {
|
||||
ContextGenerateAvailableVar,
|
||||
ContextGenerateCodeContext,
|
||||
ContextGenerateMessage,
|
||||
ContextGenerateParameterInfo,
|
||||
ContextGenerateResponse,
|
||||
} from '@/service/debug'
|
||||
import type { CompletionParams, Model, ModelModeType } from '@/types/app'
|
||||
import { useSessionStorageState } from 'ahooks'
|
||||
import useBoolean from 'ahooks/lib/useBoolean'
|
||||
@ -9,7 +18,10 @@ import { useTranslation } from 'react-i18next'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { useGetLanguage } from '@/context/i18n'
|
||||
import { languages } from '@/i18n-config/language'
|
||||
import { fetchContextGenerateSuggestedQuestions, generateContext } from '@/service/debug'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
@ -37,12 +49,94 @@ export const normalizeCodeLanguage = (value?: string) => {
|
||||
return CodeLanguage.python3
|
||||
}
|
||||
|
||||
// FIXME: Implement buildValueSelector function
|
||||
const buildValueSelector = (nodeId: string, variable: Var): string[] => {
|
||||
if (!nodeId)
|
||||
return variable.variable.split('.')
|
||||
const isSys = variable.variable.startsWith('sys.')
|
||||
const isEnv = variable.variable.startsWith('env.')
|
||||
const isChatVar = variable.variable.startsWith('conversation.')
|
||||
const isRagVariable = variable.isRagVariable
|
||||
if (isSys || isEnv || isChatVar || isRagVariable)
|
||||
return variable.variable.split('.')
|
||||
return [nodeId, ...variable.variable.split('.')]
|
||||
}
|
||||
|
||||
const resolveVarSchema = (variable: Var): Record<string, unknown> | undefined => {
|
||||
const children = variable.children
|
||||
if (!children || Array.isArray(children))
|
||||
return undefined
|
||||
if (!('schema' in children))
|
||||
return undefined
|
||||
const schema = children.schema
|
||||
if (!schema)
|
||||
return undefined
|
||||
if (typeof schema === 'string') {
|
||||
try {
|
||||
return JSON.parse(schema) as Record<string, unknown>
|
||||
}
|
||||
catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
return schema as Record<string, unknown>
|
||||
}
|
||||
|
||||
const toAvailableVarsPayload = (
|
||||
availableVars: NodeOutPutVar[],
|
||||
nodeMap: Map<string, { data?: { type?: string } }>,
|
||||
): ContextGenerateAvailableVar[] => {
|
||||
const results: ContextGenerateAvailableVar[] = []
|
||||
availableVars.forEach((nodeVar) => {
|
||||
nodeVar.vars.forEach((variable) => {
|
||||
const valueSelector = buildValueSelector(nodeVar.nodeId, variable)
|
||||
if (!valueSelector.length)
|
||||
return
|
||||
const schema = resolveVarSchema(variable)
|
||||
const description = (variable as { description?: string }).description || variable.des
|
||||
const nodeInfo = nodeMap.get(nodeVar.nodeId)
|
||||
results.push({
|
||||
value_selector: valueSelector,
|
||||
type: variable.type,
|
||||
description,
|
||||
node_id: nodeVar.nodeId,
|
||||
node_title: nodeVar.title,
|
||||
node_type: nodeInfo?.data?.type,
|
||||
schema: schema ?? undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
const mapCodeNodeOutputs = (outputs?: Record<string, { type: string } | { type: string, children?: null }>) => {
|
||||
if (!outputs)
|
||||
return undefined
|
||||
const next: Record<string, { type: string }> = {}
|
||||
Object.entries(outputs).forEach(([key, value]) => {
|
||||
if (!value)
|
||||
return
|
||||
next[key] = { type: value.type }
|
||||
})
|
||||
return Object.keys(next).length ? next : undefined
|
||||
}
|
||||
|
||||
const mapCodeNodeVariables = (variables?: Array<{ variable: string, value_selector?: string[] | null }>) => {
|
||||
if (!variables)
|
||||
return undefined
|
||||
return variables.map(variable => ({
|
||||
variable: variable.variable,
|
||||
value_selector: Array.isArray(variable.value_selector) ? variable.value_selector : [],
|
||||
}))
|
||||
}
|
||||
|
||||
type UseContextGenerateOptions = {
|
||||
storageKey: string
|
||||
flowId: string
|
||||
toolNodeId: string
|
||||
paramKey: string
|
||||
codeNodeData?: CodeNodeType
|
||||
availableVars?: NodeOutPutVar[]
|
||||
availableNodes?: Node[]
|
||||
}
|
||||
|
||||
type VersionOption = {
|
||||
@ -77,12 +171,14 @@ type UseContextGenerateResult = {
|
||||
|
||||
const useContextGenerate = ({
|
||||
storageKey,
|
||||
flowId,
|
||||
toolNodeId,
|
||||
paramKey,
|
||||
codeNodeData,
|
||||
availableVars,
|
||||
availableNodes,
|
||||
}: UseContextGenerateOptions): UseContextGenerateResult => {
|
||||
const { t, i18n } = useTranslation()
|
||||
const locale = useGetLanguage()
|
||||
const {
|
||||
versions,
|
||||
addVersion,
|
||||
@ -102,6 +198,77 @@ const useContextGenerate = ({
|
||||
const [suggestedQuestions, setSuggestedQuestions] = useState<string[]>([])
|
||||
const [hasFetchedSuggestions, setHasFetchedSuggestions] = useState<boolean>(false)
|
||||
|
||||
const nodes = useStore(s => s.nodes)
|
||||
const toolNodeData = useMemo(() => {
|
||||
if (!toolNodeId)
|
||||
return undefined
|
||||
return nodes.find(node => node.id === toolNodeId)?.data as ToolNodeType | undefined
|
||||
}, [nodes, toolNodeId])
|
||||
|
||||
const { availableVars: derivedAvailableVars, availableNodesWithParent } = useAvailableVarList(toolNodeId, {
|
||||
onlyLeafNodeVar: false,
|
||||
filterVar: () => true,
|
||||
passedInAvailableNodes: availableNodes,
|
||||
})
|
||||
const resolvedAvailableVars = useMemo(() => {
|
||||
if (availableVars && availableVars.length)
|
||||
return availableVars
|
||||
return derivedAvailableVars
|
||||
}, [availableVars, derivedAvailableVars])
|
||||
const resolvedAvailableNodes = useMemo(() => {
|
||||
if (availableNodes && availableNodes.length)
|
||||
return availableNodes
|
||||
return availableNodesWithParent
|
||||
}, [availableNodes, availableNodesWithParent])
|
||||
const availableNodesMap = useMemo(() => {
|
||||
return new Map(resolvedAvailableNodes.map(node => [node.id, node]))
|
||||
}, [resolvedAvailableNodes])
|
||||
const availableVarsPayload = useMemo(() => {
|
||||
return toAvailableVarsPayload(resolvedAvailableVars, availableNodesMap)
|
||||
}, [availableNodesMap, resolvedAvailableVars])
|
||||
|
||||
const parameterInfo = useMemo<ContextGenerateParameterInfo>(() => {
|
||||
const defaultInfo: ContextGenerateParameterInfo = {
|
||||
name: paramKey,
|
||||
type: 'string',
|
||||
description: '',
|
||||
}
|
||||
if (!Array.isArray(toolNodeData?.paramSchemas) || !toolNodeData.paramSchemas.length)
|
||||
return defaultInfo
|
||||
const paramSchema = (toolNodeData.paramSchemas as ToolParameter[]).find(param => param.name === paramKey)
|
||||
if (!paramSchema)
|
||||
return defaultInfo
|
||||
const description = paramSchema.llm_description
|
||||
|| paramSchema.human_description?.[locale]
|
||||
|| paramSchema.human_description?.en_US
|
||||
|| ''
|
||||
return {
|
||||
name: paramSchema.name || paramKey,
|
||||
type: paramSchema.type || 'string',
|
||||
description,
|
||||
required: paramSchema.required,
|
||||
options: paramSchema.options?.map(option => option.value),
|
||||
min: paramSchema.min,
|
||||
max: paramSchema.max,
|
||||
default: paramSchema.default ?? null,
|
||||
multiple: paramSchema.multiple,
|
||||
label: paramSchema.label?.[locale] || paramSchema.label?.en_US,
|
||||
}
|
||||
}, [locale, paramKey, toolNodeData])
|
||||
|
||||
const codeContext = useMemo<ContextGenerateCodeContext | undefined>(() => {
|
||||
const code = current?.code || codeNodeData?.code || ''
|
||||
const outputs = mapCodeNodeOutputs(current?.outputs || codeNodeData?.outputs)
|
||||
const variables = mapCodeNodeVariables(current?.variables || codeNodeData?.variables)
|
||||
if (!code && !outputs && !variables)
|
||||
return undefined
|
||||
return {
|
||||
code,
|
||||
outputs,
|
||||
variables,
|
||||
}
|
||||
}, [codeNodeData?.code, codeNodeData?.outputs, codeNodeData?.variables, current?.code, current?.outputs, current?.variables])
|
||||
|
||||
const [isFetchingSuggestions, { setTrue: setFetchingSuggestionsTrue, setFalse: setFetchingSuggestionsFalse }] = useBoolean(false)
|
||||
const suggestedQuestionsAbortControllerRef = useRef<AbortController | null>(null)
|
||||
|
||||
@ -196,7 +363,7 @@ const useContextGenerate = ({
|
||||
}, [clearVersions, isGenerating, setPromptMessages])
|
||||
|
||||
const handleFetchSuggestedQuestions = useCallback(async () => {
|
||||
if (!flowId || !toolNodeId || !paramKey)
|
||||
if (!toolNodeId || !paramKey)
|
||||
return
|
||||
if (!model.name || !model.provider)
|
||||
return
|
||||
@ -208,15 +375,14 @@ const useContextGenerate = ({
|
||||
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,
|
||||
},
|
||||
available_vars: availableVarsPayload,
|
||||
parameter_info: parameterInfo,
|
||||
}, (abortController) => {
|
||||
suggestedQuestionsAbortControllerRef.current = abortController
|
||||
})
|
||||
@ -252,7 +418,7 @@ const useContextGenerate = ({
|
||||
setFetchingSuggestionsFalse()
|
||||
}
|
||||
}, [
|
||||
flowId,
|
||||
availableVarsPayload,
|
||||
hasFetchedSuggestions,
|
||||
isFetchingSuggestions,
|
||||
isInitView,
|
||||
@ -260,6 +426,7 @@ const useContextGenerate = ({
|
||||
model.name,
|
||||
model.provider,
|
||||
paramKey,
|
||||
parameterInfo,
|
||||
promptLanguage,
|
||||
setFetchingSuggestionsFalse,
|
||||
setFetchingSuggestionsTrue,
|
||||
@ -281,7 +448,7 @@ const useContextGenerate = ({
|
||||
const trimmed = inputValue.trim()
|
||||
if (!trimmed || isGenerating)
|
||||
return
|
||||
if (!flowId || !toolNodeId || !paramKey)
|
||||
if (!toolNodeId || !paramKey)
|
||||
return
|
||||
|
||||
const userMessage: ContextGenerateChatMessage = { role: 'user', content: trimmed }
|
||||
@ -292,16 +459,20 @@ const useContextGenerate = ({
|
||||
generateStartRef.current = Date.now()
|
||||
try {
|
||||
const response = await generateContext({
|
||||
workflow_id: flowId,
|
||||
node_id: toolNodeId,
|
||||
parameter_name: paramKey,
|
||||
language: normalizeCodeLanguage(current?.code_language || codeNodeData?.code_language) as 'python3' | 'javascript',
|
||||
prompt_messages: nextMessages.map(({ role, content }) => ({ role, content })),
|
||||
prompt_messages: nextMessages.map(({ role, content, tool_call_id }) => ({
|
||||
role,
|
||||
content,
|
||||
tool_call_id,
|
||||
})),
|
||||
model_config: {
|
||||
provider: model.provider,
|
||||
name: model.name,
|
||||
completion_params: model.completion_params,
|
||||
},
|
||||
available_vars: availableVarsPayload,
|
||||
parameter_info: parameterInfo,
|
||||
code_context: codeContext,
|
||||
})
|
||||
|
||||
if (response.error) {
|
||||
@ -328,16 +499,18 @@ const useContextGenerate = ({
|
||||
}
|
||||
}, [
|
||||
addVersion,
|
||||
availableVarsPayload,
|
||||
codeContext,
|
||||
codeNodeData?.code_language,
|
||||
current?.code_language,
|
||||
defaultAssistantMessage,
|
||||
flowId,
|
||||
inputValue,
|
||||
isGenerating,
|
||||
model.completion_params,
|
||||
model.name,
|
||||
model.provider,
|
||||
paramKey,
|
||||
parameterInfo,
|
||||
promptMessages,
|
||||
setPromptMessages,
|
||||
setGeneratingFalse,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use client'
|
||||
import type { CodeNodeType, OutputVar } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { Node, NodeOutPutVar } from '@/app/components/workflow/types'
|
||||
import type { ContextGenerateResponse } from '@/service/debug'
|
||||
import * as React from 'react'
|
||||
import { forwardRef, useCallback, useImperativeHandle, useMemo } from 'react'
|
||||
@ -20,6 +21,8 @@ type Props = {
|
||||
toolNodeId: string
|
||||
paramKey: string
|
||||
codeNodeId: string
|
||||
availableVars?: NodeOutPutVar[]
|
||||
availableNodes?: Node[]
|
||||
}
|
||||
|
||||
export type ContextGenerateModalHandle = {
|
||||
@ -54,6 +57,8 @@ const ContextGenerateModal = forwardRef<ContextGenerateModalHandle, Props>(({
|
||||
toolNodeId,
|
||||
paramKey,
|
||||
codeNodeId,
|
||||
availableVars,
|
||||
availableNodes,
|
||||
}, ref) => {
|
||||
const configsMap = useHooksStore(s => s.configsMap)
|
||||
const nodes = useStore(s => s.nodes)
|
||||
@ -111,10 +116,11 @@ const ContextGenerateModal = forwardRef<ContextGenerateModalHandle, Props>(({
|
||||
isInitView,
|
||||
} = useContextGenerate({
|
||||
storageKey,
|
||||
flowId,
|
||||
toolNodeId,
|
||||
paramKey,
|
||||
codeNodeData,
|
||||
availableVars,
|
||||
availableNodes,
|
||||
})
|
||||
|
||||
const handleCloseModal = useCallback(() => {
|
||||
|
||||
@ -460,6 +460,8 @@ const MixedVariableTextInput = ({
|
||||
toolNodeId={toolNodeId}
|
||||
paramKey={paramKey}
|
||||
codeNodeId={assembleExtractorNodeId || `${toolNodeId}_ext_${paramKey}`}
|
||||
availableVars={nodesOutputVars}
|
||||
availableNodes={availableNodes}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { SandboxFileTreeNode } from '@/types/sandbox-file'
|
||||
import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react'
|
||||
import { RiArrowDownSLine, RiArrowRightSLine, RiLoader2Line } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -23,9 +23,7 @@ const ArtifactsSection: FC<ArtifactsSectionProps> = ({ className }) => {
|
||||
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
|
||||
const { data: treeData, hasFiles, isLoading } = useSandboxFilesTree(sandboxId, {
|
||||
enabled: isExpanded,
|
||||
})
|
||||
const { data: treeData, hasFiles, isLoading } = useSandboxFilesTree(sandboxId)
|
||||
|
||||
const downloadMutation = useDownloadSandboxFile(sandboxId)
|
||||
|
||||
@ -44,6 +42,7 @@ const ArtifactsSection: FC<ArtifactsSectionProps> = ({ className }) => {
|
||||
}, [downloadMutation])
|
||||
|
||||
const showBlueDot = !isExpanded && hasFiles
|
||||
const showSpinner = isLoading
|
||||
|
||||
return (
|
||||
<div className={cn('shrink-0 border-t border-divider-regular p-1', className)}>
|
||||
@ -68,40 +67,40 @@ const ArtifactsSection: FC<ArtifactsSectionProps> = ({ className }) => {
|
||||
</div>
|
||||
|
||||
<div className="relative flex items-center">
|
||||
{showBlueDot && (
|
||||
<div className="absolute -left-2 size-[7px] rounded-full border border-white bg-state-accent-solid" />
|
||||
)}
|
||||
{isExpanded
|
||||
? <RiArrowDownSLine className="size-4 text-text-tertiary" aria-hidden="true" />
|
||||
: <RiArrowRightSLine className="size-4 text-text-tertiary" aria-hidden="true" />}
|
||||
{showSpinner
|
||||
? <RiLoader2Line className="size-3.5 animate-spin text-text-tertiary" aria-hidden="true" />
|
||||
: (
|
||||
<>
|
||||
{showBlueDot && (
|
||||
<div className="absolute -left-2 size-[7px] rounded-full border border-white bg-state-accent-solid" />
|
||||
)}
|
||||
{isExpanded
|
||||
? <RiArrowDownSLine className="size-4 text-text-tertiary" aria-hidden="true" />
|
||||
: <RiArrowRightSLine className="size-4 text-text-tertiary" aria-hidden="true" />}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{isExpanded && (
|
||||
{isExpanded && !isLoading && (
|
||||
<div className="flex flex-col gap-px">
|
||||
{isLoading
|
||||
{hasFiles
|
||||
? (
|
||||
<div className="px-2.5 py-3" aria-hidden="true">
|
||||
<div className="h-4 w-full animate-pulse rounded bg-components-panel-bg" />
|
||||
</div>
|
||||
<ArtifactsTree
|
||||
data={treeData}
|
||||
onDownload={handleDownload}
|
||||
isDownloading={downloadMutation.isPending}
|
||||
/>
|
||||
)
|
||||
: hasFiles
|
||||
? (
|
||||
<ArtifactsTree
|
||||
data={treeData}
|
||||
onDownload={handleDownload}
|
||||
isDownloading={downloadMutation.isPending}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<div className="px-2.5 pb-1.5 pt-0.5">
|
||||
<div className="rounded-lg bg-background-section p-3">
|
||||
<p className="system-xs-regular text-text-tertiary">
|
||||
{t('skillSidebar.artifacts.emptyState')}
|
||||
</p>
|
||||
</div>
|
||||
: (
|
||||
<div className="px-2.5 pb-1.5 pt-0.5">
|
||||
<div className="rounded-lg bg-background-section p-3">
|
||||
<p className="system-xs-regular text-text-tertiary">
|
||||
{t('skillSidebar.artifacts.emptyState')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import type { SandboxFileTreeNode } from '@/types/sandbox-file'
|
||||
import { RiDownloadLine, RiFile3Fill, RiFolderLine } from '@remixicon/react'
|
||||
import { RiDownloadLine, RiFolderLine, RiFolderOpenLine } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import FileTypeIcon from '@/app/components/base/file-uploader/file-type-icon'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { getFileIconType } from '../utils/file-utils'
|
||||
import TreeGuideLines from './tree-guide-lines'
|
||||
|
||||
const INDENT_SIZE = 20
|
||||
|
||||
type ArtifactsTreeProps = {
|
||||
data: SandboxFileTreeNode[] | undefined
|
||||
@ -40,6 +46,8 @@ const ArtifactsTreeNode: FC<ArtifactsTreeNodeProps> = ({
|
||||
onDownload(node)
|
||||
}, [node, onDownload])
|
||||
|
||||
const fileIconType = !isFolder ? getFileIconType(node.name) : null
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
@ -55,19 +63,24 @@ const ArtifactsTreeNode: FC<ArtifactsTreeNodeProps> = ({
|
||||
}
|
||||
: undefined}
|
||||
className={cn(
|
||||
'group flex items-center gap-0 rounded-md py-0.5 pr-1.5',
|
||||
'group relative flex h-6 items-center rounded-md px-2',
|
||||
isFolder && 'cursor-pointer hover:bg-state-base-hover focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-components-input-border-active',
|
||||
!isFolder && 'hover:bg-state-base-hover',
|
||||
)}
|
||||
style={{ paddingLeft: `${8 + depth * 20}px` }}
|
||||
style={{ paddingLeft: `${8 + depth * INDENT_SIZE}px` }}
|
||||
>
|
||||
<TreeGuideLines level={depth} lineOffset={2} />
|
||||
<div className="flex size-5 shrink-0 items-center justify-center">
|
||||
{isFolder
|
||||
? <RiFolderLine className="size-4 text-text-tertiary" />
|
||||
: <RiFile3Fill className="size-4 text-text-quaternary" />}
|
||||
? (
|
||||
isExpanded
|
||||
? <RiFolderOpenLine className="size-4 text-text-accent" aria-hidden="true" />
|
||||
: <RiFolderLine className="size-4 text-text-secondary" aria-hidden="true" />
|
||||
)
|
||||
: <FileTypeIcon type={fileIconType as FileAppearanceType} size="sm" />}
|
||||
</div>
|
||||
|
||||
<span className="system-sm-regular flex-1 truncate px-1 py-0.5 text-text-secondary">
|
||||
<span className="min-w-0 flex-1 truncate text-[13px] font-normal leading-4 text-text-secondary">
|
||||
{node.name}
|
||||
</span>
|
||||
|
||||
|
||||
@ -316,10 +316,16 @@ export enum ValueType {
|
||||
constant = 'constant',
|
||||
}
|
||||
|
||||
export type VarSchemaContainer = {
|
||||
schema?: StructuredOutput['schema'] | Record<string, unknown> | string
|
||||
}
|
||||
|
||||
export type VarChildren = Var[] | StructuredOutput | VarSchemaContainer
|
||||
|
||||
export type Var = {
|
||||
variable: string
|
||||
type: VarType
|
||||
children?: Var[] | StructuredOutput // if type is obj, has the children struct
|
||||
children?: VarChildren // if type is obj, has the children struct
|
||||
isParagraph?: boolean
|
||||
isSelect?: boolean
|
||||
options?: string[]
|
||||
|
||||
@ -27,14 +27,42 @@ export type CodeGenRes = {
|
||||
}
|
||||
|
||||
export type ContextGenerateMessage = {
|
||||
role: 'user' | 'assistant' | 'system'
|
||||
role: 'user' | 'assistant' | 'system' | 'tool'
|
||||
content: string
|
||||
tool_call_id?: string
|
||||
}
|
||||
|
||||
// FIXME
|
||||
export type ContextGenerateAvailableVar = {
|
||||
value_selector: string[]
|
||||
type: string
|
||||
description?: string
|
||||
node_id?: string
|
||||
node_title?: string
|
||||
node_type?: string
|
||||
schema?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export type ContextGenerateParameterInfo = {
|
||||
name: string
|
||||
type?: string
|
||||
description?: string
|
||||
required?: boolean
|
||||
options?: string[]
|
||||
min?: number
|
||||
max?: number
|
||||
default?: string | number | boolean | null
|
||||
multiple?: boolean
|
||||
label?: string
|
||||
}
|
||||
|
||||
export type ContextGenerateCodeContext = {
|
||||
code: string
|
||||
outputs?: Record<string, { type: string }>
|
||||
variables?: ContextGenerateVariable[]
|
||||
}
|
||||
|
||||
export type ContextGenerateRequest = {
|
||||
workflow_id: string
|
||||
node_id: string
|
||||
parameter_name: string
|
||||
language?: 'python3' | 'javascript'
|
||||
prompt_messages: ContextGenerateMessage[]
|
||||
model_config: {
|
||||
@ -42,6 +70,9 @@ export type ContextGenerateRequest = {
|
||||
name: string
|
||||
completion_params?: CompletionParams
|
||||
}
|
||||
available_vars: ContextGenerateAvailableVar[]
|
||||
parameter_info: ContextGenerateParameterInfo
|
||||
code_context?: ContextGenerateCodeContext | null
|
||||
}
|
||||
|
||||
export type ContextGenerateVariable = {
|
||||
@ -59,15 +90,14 @@ export type ContextGenerateResponse = {
|
||||
}
|
||||
|
||||
export type ContextGenerateSuggestedQuestionsRequest = {
|
||||
workflow_id: string
|
||||
node_id: string
|
||||
parameter_name: string
|
||||
language: string
|
||||
model_config: {
|
||||
model_config?: {
|
||||
provider: string
|
||||
name: string
|
||||
completion_params?: CompletionParams
|
||||
}
|
||||
available_vars: ContextGenerateAvailableVar[]
|
||||
parameter_info: ContextGenerateParameterInfo
|
||||
}
|
||||
|
||||
export type ContextGenerateSuggestedQuestionsResponse = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user