wip: instruction field

This commit is contained in:
AkaraChen 2024-12-31 11:52:15 +08:00
parent 232fb66edd
commit eba4042a62
5 changed files with 86 additions and 25 deletions

View File

@ -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}

View File

@ -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}

View File

@ -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>
)}

View File

@ -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,

View File

@ -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,
}
}