wip: instruction field

pull/12372/head
AkaraChen 1 year ago
parent 232fb66edd
commit eba4042a62

@ -89,7 +89,7 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
const { t } = useTranslation() const { t } = useTranslation()
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'> return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
<PortalToFollowElemTrigger className='w-full'> <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 */} {/* eslint-disable-next-line @next/next/no-img-element */}
{icon && <div className='flex items-center justify-center w-6 h-6'><img {icon && <div className='flex items-center justify-center w-6 h-6'><img
src={icon} src={icon}

@ -1,5 +1,5 @@
import type { CredentialFormSchemaNumberInput } from '@/app/components/header/account-setting/model-provider-page/declarations' 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 type { ToolVarInputs } from '../../tool/types'
import ListEmpty from '@/app/components/base/list-empty' import ListEmpty from '@/app/components/base/list-empty'
import { AgentStrategySelector } from './agent-strategy-selector' 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 MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector'
import Field from './field' import Field from './field'
import type { ComponentProps } from 'react' 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 Editor from './prompt/editor'
import { strategyParamToCredientialForm } from '../../agent/panel'
export type Strategy = { export type Strategy = {
agent_strategy_provider_name: string agent_strategy_provider_name: string
@ -36,10 +37,10 @@ type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { typ
type ToolSelectorSchema = CustomSchema<'tool-selector'> type ToolSelectorSchema = CustomSchema<'tool-selector'>
type MultipleToolSelectorSchema = CustomSchema<'array[tools]'> type MultipleToolSelectorSchema = CustomSchema<'array[tools]'>
type StringSchema = CustomSchema<'string', { type StringSchema = CustomSchema<'string', {
template: { template?: {
enabled: boolean enabled: boolean
}, },
auto_generate: { auto_generate?: {
type: string type: string
} }
}> }>
@ -50,6 +51,7 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange } = props const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange } = props
const { t } = useTranslation() const { t } = useTranslation()
const language = useLanguage() const language = useLanguage()
const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration)
const override: ComponentProps<typeof Form<CustomField>>['override'] = [ const override: ComponentProps<typeof Form<CustomField>>['override'] = [
[FormTypeEnum.textNumber], [FormTypeEnum.textNumber],
(schema, props) => { (schema, props) => {
@ -125,14 +127,33 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
} }
case 'string': { case 'string': {
const value = props.value[schema.variable] const value = props.value[schema.variable]
const onChange = (value: any) => { const onChange = (value: string) => {
props.onChange({ ...props.value, [schema.variable]: value }) props.onChange({ ...props.value, [schema.variable]: value })
} }
return <Editor return <Editor
value={value} value={value}
onChange={onChange} onChange={onChange}
title={schema.label[language]} 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 strategy
? <div> ? <div>
<Form<CustomField> <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} value={formValue}
onChange={onFormValueChange} onChange={onFormValueChange}
validating={false} validating={false}

@ -1,5 +1,5 @@
'use client' 'use client'
import type { FC } from 'react' import type { FC, ReactNode } from 'react'
import React, { useCallback, useRef } from 'react' import React, { useCallback, useRef } from 'react'
import { import {
RiDeleteBinLine, RiDeleteBinLine,
@ -37,7 +37,7 @@ import Switch from '@/app/components/base/switch'
import { Jinja } from '@/app/components/base/icons/src/vender/workflow' import { Jinja } from '@/app/components/base/icons/src/vender/workflow'
import { useStore } from '@/app/components/workflow/store' import { useStore } from '@/app/components/workflow/store'
interface Props { type Props = {
className?: string className?: string
headerClassName?: string headerClassName?: string
instanceId?: string instanceId?: string
@ -68,6 +68,12 @@ interface Props {
onEditionTypeChange?: (editionType: EditionType) => void onEditionTypeChange?: (editionType: EditionType) => void
varList?: Variable[] varList?: Variable[]
handleAddVariable?: (payload: any) => void handleAddVariable?: (payload: any) => void
containerClassName?: string
gradientBorder?: boolean
titleTooltip?: ReactNode
inputClassName?: string
editorContainerClassName?: string
placeholderClassName?: string
} }
const Editor: FC<Props> = ({ const Editor: FC<Props> = ({
@ -96,6 +102,12 @@ const Editor: FC<Props> = ({
handleAddVariable, handleAddVariable,
onGenerated, onGenerated,
modelConfig, modelConfig,
containerClassName,
gradientBorder = true,
titleTooltip,
inputClassName,
placeholderClassName,
editorContainerClassName,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { eventEmitter } = useEventEmitterContextContext() const { eventEmitter } = useEventEmitterContextContext()
@ -129,10 +141,13 @@ const Editor: FC<Props> = ({
return ( return (
<Wrap className={cn(className, wrapClassName)} style={wrapStyle} isInNode isExpand={isExpand}> <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 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')}> <div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg', containerClassName)}>
<div className={cn(headerClassName, 'pt-1 pl-3 pr-2 flex justify-between items-center')}> <div className={cn('pt-1 pl-3 pr-2 flex justify-between items-center', headerClassName)}>
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div> <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='flex items-center'>
<div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div> <div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div>
{isSupportPromptGenerator && ( {isSupportPromptGenerator && (
@ -201,12 +216,13 @@ const Editor: FC<Props> = ({
<div className={cn('pb-2', isExpand && 'flex flex-col grow')}> <div className={cn('pb-2', isExpand && 'flex flex-col grow')}>
{!(isSupportJinja && editionType === EditionType.jinja2) {!(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 <PromptEditor
key={controlPromptEditorRerenderKey} key={controlPromptEditorRerenderKey}
placeholderClassName={placeholderClassName}
instanceId={instanceId} instanceId={instanceId}
compact compact
className='min-h-[56px]' className={cn('min-h-[56px]', inputClassName)}
style={isExpand ? { height: editorExpandHeight - 5 } : {}} style={isExpand ? { height: editorExpandHeight - 5 } : {}}
value={value} value={value}
contextBlock={{ contextBlock={{
@ -254,7 +270,7 @@ const Editor: FC<Props> = ({
</div> </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 <CodeEditor
availableVars={nodesOutputVars || []} availableVars={nodesOutputVars || []}
varList={varList} varList={varList}
@ -266,6 +282,7 @@ const Editor: FC<Props> = ({
onChange={onChange} onChange={onChange}
noWrapper noWrapper
isExpand={isExpand} isExpand={isExpand}
className={inputClassName}
/> />
</div> </div>
)} )}

@ -11,7 +11,7 @@ import type { CredentialFormSchema } from '@/app/components/header/account-setti
const i18nPrefix = 'workflow.nodes.agent' const i18nPrefix = 'workflow.nodes.agent'
function strategyParamToCredientialForm(param: StrategyParamItem): CredentialFormSchema { export function strategyParamToCredientialForm(param: StrategyParamItem): CredentialFormSchema {
return { return {
...param as any, ...param as any,
variable: param.name, variable: param.name,

@ -16,12 +16,18 @@ const useConfig = (id: string, payload: AgentNodeType) => {
inputs, inputs,
setInputs, setInputs,
}) })
const strategies = useStrategyProviderDetail( const strategyProvider = useStrategyProviderDetail(
inputs.agent_strategy_provider_name || '', 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, 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(() => { const formData = useMemo(() => {
return Object.fromEntries( return Object.fromEntries(
Object.entries(inputs.agent_parameters || {}).map(([key, value]) => { Object.entries(inputs.agent_parameters || {}).map(([key, value]) => {
@ -31,12 +37,9 @@ const useConfig = (id: string, payload: AgentNodeType) => {
}, [inputs.agent_parameters]) }, [inputs.agent_parameters])
const onFormChange = (value: Record<string, any>) => { const onFormChange = (value: Record<string, any>) => {
const res: ToolVarInputs = {} const res: ToolVarInputs = {}
const params = currentStrategy!.parameters
Object.entries(value).forEach(([key, val]) => { Object.entries(value).forEach(([key, val]) => {
const param = params.find(p => p.name === key)
const isMixed = param?.type === 'string'
res[key] = { res[key] = {
type: isMixed ? VarType.mixed : VarType.constant, type: VarType.constant,
value: val, value: val,
} }
}) })
@ -44,7 +47,6 @@ const useConfig = (id: string, payload: AgentNodeType) => {
...inputs, ...inputs,
agent_parameters: res, agent_parameters: res,
}) })
console.log(res)
} }
return { return {
readOnly, readOnly,
@ -55,6 +57,8 @@ const useConfig = (id: string, payload: AgentNodeType) => {
currentStrategy, currentStrategy,
formData, formData,
onFormChange, onFormChange,
currentStrategyStatus,
strategyProvider: strategyProvider.data,
} }
} }

Loading…
Cancel
Save