mirror of
https://github.com/langgenius/dify.git
synced 2026-04-13 06:43:30 +08:00
wip: instruction field
This commit is contained in:
parent
232fb66edd
commit
eba4042a62
@ -89,7 +89,7 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
|
||||
const { t } = useTranslation()
|
||||
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
|
||||
<PortalToFollowElemTrigger className='w-full'>
|
||||
<div className='p-1 gap-0.5 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt select-none' onClick={() => setOpen(o => !o)}>
|
||||
<div className='h-8 p-1 gap-0.5 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt select-none' onClick={() => setOpen(o => !o)}>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
{icon && <div className='flex items-center justify-center w-6 h-6'><img
|
||||
src={icon}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { CredentialFormSchemaNumberInput } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { type CredentialFormSchema, FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { type CredentialFormSchema, FormTypeEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { ToolVarInputs } from '../../tool/types'
|
||||
import ListEmpty from '@/app/components/base/list-empty'
|
||||
import { AgentStrategySelector } from './agent-strategy-selector'
|
||||
@ -13,8 +13,9 @@ import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-sele
|
||||
import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector'
|
||||
import Field from './field'
|
||||
import type { ComponentProps } from 'react'
|
||||
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import { useDefaultModel, useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import Editor from './prompt/editor'
|
||||
import { strategyParamToCredientialForm } from '../../agent/panel'
|
||||
|
||||
export type Strategy = {
|
||||
agent_strategy_provider_name: string
|
||||
@ -36,10 +37,10 @@ type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { typ
|
||||
type ToolSelectorSchema = CustomSchema<'tool-selector'>
|
||||
type MultipleToolSelectorSchema = CustomSchema<'array[tools]'>
|
||||
type StringSchema = CustomSchema<'string', {
|
||||
template: {
|
||||
template?: {
|
||||
enabled: boolean
|
||||
},
|
||||
auto_generate: {
|
||||
auto_generate?: {
|
||||
type: string
|
||||
}
|
||||
}>
|
||||
@ -50,6 +51,7 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
|
||||
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange } = props
|
||||
const { t } = useTranslation()
|
||||
const language = useLanguage()
|
||||
const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration)
|
||||
const override: ComponentProps<typeof Form<CustomField>>['override'] = [
|
||||
[FormTypeEnum.textNumber],
|
||||
(schema, props) => {
|
||||
@ -125,14 +127,33 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
|
||||
}
|
||||
case 'string': {
|
||||
const value = props.value[schema.variable]
|
||||
const onChange = (value: any) => {
|
||||
const onChange = (value: string) => {
|
||||
props.onChange({ ...props.value, [schema.variable]: value })
|
||||
}
|
||||
return <Editor
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
title={schema.label[language]}
|
||||
headerClassName='bg-transparent'
|
||||
headerClassName='bg-transparent px-0 text-text-secondary system-sm-semibold-uppercase !text-base'
|
||||
containerClassName='bg-transparent'
|
||||
gradientBorder={false}
|
||||
isSupportPromptGenerator={!!schema.auto_generate?.type}
|
||||
titleTooltip={schema.tooltip?.[language]}
|
||||
editorContainerClassName='px-0'
|
||||
isSupportJinja={schema.template?.enabled}
|
||||
varList={[]}
|
||||
modelConfig={
|
||||
defaultModel.data
|
||||
? {
|
||||
mode: 'chat',
|
||||
name: defaultModel.data.model,
|
||||
provider: defaultModel.data.provider.provider,
|
||||
completion_params: {},
|
||||
} : undefined
|
||||
}
|
||||
onGenerated={onChange}
|
||||
placeholderClassName='px-2 py-1'
|
||||
inputClassName='px-2 py-1 bg-components-input-bg-normal focus:bg-components-input-bg-active focus:border-components-input-border-active focus:border rounded-lg'
|
||||
/>
|
||||
}
|
||||
}
|
||||
@ -143,7 +164,26 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
|
||||
strategy
|
||||
? <div>
|
||||
<Form<CustomField>
|
||||
formSchemas={formSchema}
|
||||
formSchemas={[
|
||||
...formSchema,
|
||||
...[{
|
||||
name: 'instruction2',
|
||||
type: 'string',
|
||||
required: true,
|
||||
label: {
|
||||
en_US: 'Instruction2',
|
||||
zh_Hans: '指令2',
|
||||
pt_BR: 'Instruction2',
|
||||
},
|
||||
auto_generate: {
|
||||
type: 'prompt_instruction',
|
||||
},
|
||||
template: {
|
||||
enabled: true,
|
||||
},
|
||||
// @ts-expect-error just for test
|
||||
}].map(strategyParamToCredientialForm),
|
||||
]}
|
||||
value={formValue}
|
||||
onChange={onFormValueChange}
|
||||
validating={false}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { FC, ReactNode } from 'react'
|
||||
import React, { useCallback, useRef } from 'react'
|
||||
import {
|
||||
RiDeleteBinLine,
|
||||
@ -37,7 +37,7 @@ import Switch from '@/app/components/base/switch'
|
||||
import { Jinja } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
|
||||
interface Props {
|
||||
type Props = {
|
||||
className?: string
|
||||
headerClassName?: string
|
||||
instanceId?: string
|
||||
@ -68,6 +68,12 @@ interface Props {
|
||||
onEditionTypeChange?: (editionType: EditionType) => void
|
||||
varList?: Variable[]
|
||||
handleAddVariable?: (payload: any) => void
|
||||
containerClassName?: string
|
||||
gradientBorder?: boolean
|
||||
titleTooltip?: ReactNode
|
||||
inputClassName?: string
|
||||
editorContainerClassName?: string
|
||||
placeholderClassName?: string
|
||||
}
|
||||
|
||||
const Editor: FC<Props> = ({
|
||||
@ -96,6 +102,12 @@ const Editor: FC<Props> = ({
|
||||
handleAddVariable,
|
||||
onGenerated,
|
||||
modelConfig,
|
||||
containerClassName,
|
||||
gradientBorder = true,
|
||||
titleTooltip,
|
||||
inputClassName,
|
||||
placeholderClassName,
|
||||
editorContainerClassName,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { eventEmitter } = useEventEmitterContextContext()
|
||||
@ -129,10 +141,13 @@ const Editor: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<Wrap className={cn(className, wrapClassName)} style={wrapStyle} isInNode isExpand={isExpand}>
|
||||
<div ref={ref} className={cn(isFocus ? s.gradientBorder : 'bg-gray-100', isExpand && 'h-full', '!rounded-[9px] p-0.5')}>
|
||||
<div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg')}>
|
||||
<div className={cn(headerClassName, 'pt-1 pl-3 pr-2 flex justify-between items-center')}>
|
||||
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
|
||||
<div ref={ref} className={cn(isFocus ? (gradientBorder && s.gradientBorder) : 'bg-gray-100', isExpand && 'h-full', '!rounded-[9px] p-0.5', containerClassName)}>
|
||||
<div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg', containerClassName)}>
|
||||
<div className={cn('pt-1 pl-3 pr-2 flex justify-between items-center', headerClassName)}>
|
||||
<div className='flex gap-2'>
|
||||
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
|
||||
{titleTooltip && <Tooltip popupContent={titleTooltip} />}
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div>
|
||||
{isSupportPromptGenerator && (
|
||||
@ -201,12 +216,13 @@ const Editor: FC<Props> = ({
|
||||
<div className={cn('pb-2', isExpand && 'flex flex-col grow')}>
|
||||
{!(isSupportJinja && editionType === EditionType.jinja2)
|
||||
? (
|
||||
<div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative px-3 min-h-[56px] overflow-y-auto')}>
|
||||
<div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative px-3 min-h-[56px] overflow-y-auto', editorContainerClassName)}>
|
||||
<PromptEditor
|
||||
key={controlPromptEditorRerenderKey}
|
||||
placeholderClassName={placeholderClassName}
|
||||
instanceId={instanceId}
|
||||
compact
|
||||
className='min-h-[56px]'
|
||||
className={cn('min-h-[56px]', inputClassName)}
|
||||
style={isExpand ? { height: editorExpandHeight - 5 } : {}}
|
||||
value={value}
|
||||
contextBlock={{
|
||||
@ -254,7 +270,7 @@ const Editor: FC<Props> = ({
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative px-3 min-h-[56px] overflow-y-auto')}>
|
||||
<div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative px-3 min-h-[56px] overflow-y-auto', editorContainerClassName)}>
|
||||
<CodeEditor
|
||||
availableVars={nodesOutputVars || []}
|
||||
varList={varList}
|
||||
@ -266,6 +282,7 @@ const Editor: FC<Props> = ({
|
||||
onChange={onChange}
|
||||
noWrapper
|
||||
isExpand={isExpand}
|
||||
className={inputClassName}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -11,7 +11,7 @@ import type { CredentialFormSchema } from '@/app/components/header/account-setti
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.agent'
|
||||
|
||||
function strategyParamToCredientialForm(param: StrategyParamItem): CredentialFormSchema {
|
||||
export function strategyParamToCredientialForm(param: StrategyParamItem): CredentialFormSchema {
|
||||
return {
|
||||
...param as any,
|
||||
variable: param.name,
|
||||
|
||||
@ -16,12 +16,18 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
||||
inputs,
|
||||
setInputs,
|
||||
})
|
||||
const strategies = useStrategyProviderDetail(
|
||||
const strategyProvider = useStrategyProviderDetail(
|
||||
inputs.agent_strategy_provider_name || '',
|
||||
)
|
||||
const currentStrategy = strategies.data?.declaration.strategies.find(
|
||||
const currentStrategy = strategyProvider.data?.declaration.strategies.find(
|
||||
str => str.identity.name === inputs.agent_strategy_name,
|
||||
)
|
||||
const currentStrategyStatus = useMemo(() => {
|
||||
if (strategyProvider.isLoading) return 'loading'
|
||||
if (strategyProvider.isError) return 'plugin-not-found'
|
||||
if (!currentStrategy) return 'strategy-not-found'
|
||||
return 'success'
|
||||
}, [currentStrategy, strategyProvider])
|
||||
const formData = useMemo(() => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(inputs.agent_parameters || {}).map(([key, value]) => {
|
||||
@ -31,12 +37,9 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
||||
}, [inputs.agent_parameters])
|
||||
const onFormChange = (value: Record<string, any>) => {
|
||||
const res: ToolVarInputs = {}
|
||||
const params = currentStrategy!.parameters
|
||||
Object.entries(value).forEach(([key, val]) => {
|
||||
const param = params.find(p => p.name === key)
|
||||
const isMixed = param?.type === 'string'
|
||||
res[key] = {
|
||||
type: isMixed ? VarType.mixed : VarType.constant,
|
||||
type: VarType.constant,
|
||||
value: val,
|
||||
}
|
||||
})
|
||||
@ -44,7 +47,6 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
||||
...inputs,
|
||||
agent_parameters: res,
|
||||
})
|
||||
console.log(res)
|
||||
}
|
||||
return {
|
||||
readOnly,
|
||||
@ -55,6 +57,8 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
||||
currentStrategy,
|
||||
formData,
|
||||
onFormChange,
|
||||
currentStrategyStatus,
|
||||
strategyProvider: strategyProvider.data,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user