mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Modify the style of the agent operator form #10703 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -74,7 +74,7 @@ export function Collapse({
|
||||
<div>{rightContent}</div>
|
||||
</section>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="pt-2">{children}</CollapsibleContent>
|
||||
<CollapsibleContent className="pt-5">{children}</CollapsibleContent>
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ export function LargeModelFormField({
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button variant={'ghost'}>
|
||||
<Funnel />
|
||||
<Funnel className="text-text-disabled" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
|
||||
@ -140,7 +140,7 @@ export const SelectWithSearch = forwardRef<
|
||||
ref={ref}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
'bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px] [&_svg]:pointer-events-auto',
|
||||
'!bg-bg-input hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px] [&_svg]:pointer-events-auto',
|
||||
triggerClassName,
|
||||
)}
|
||||
>
|
||||
|
||||
@ -31,7 +31,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
'flex h-8 w-full rounded-md border border-input bg-bg-base px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-8 w-full rounded-md border border-input bg-bg-input px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-text-primary',
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
@ -26,7 +26,7 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-8 w-full items-center bg-bg-card justify-between rounded-md border border-input px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
'flex h-8 w-full items-center bg-bg-input justify-between rounded-md border border-input px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -291,7 +291,7 @@ export const RAGFlowSelect = forwardRef<
|
||||
onReset={handleReset}
|
||||
allowClear={allowClear}
|
||||
ref={ref}
|
||||
className={cn('bg-bg-base', triggerClassName)}
|
||||
className={triggerClassName}
|
||||
>
|
||||
<SelectValue placeholder={placeholder}>{label}</SelectValue>
|
||||
</SelectTrigger>
|
||||
|
||||
@ -18,7 +18,7 @@ const Separator = React.forwardRef<
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
'shrink-0 bg-border',
|
||||
'shrink-0 bg-border-button',
|
||||
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
||||
className,
|
||||
)}
|
||||
|
||||
@ -31,7 +31,7 @@ const SheetOverlay = React.forwardRef<
|
||||
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
||||
|
||||
const sheetVariants = cva(
|
||||
'fixed z-50 gap-4 bg-text-title-invert rounded-lg p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||
'fixed z-50 gap-4 bg-bg-base rounded-lg p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||
{
|
||||
variants: {
|
||||
side: {
|
||||
@ -73,7 +73,7 @@ const SheetContent = React.forwardRef<
|
||||
{children}
|
||||
{closeIcon ? (
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary ">
|
||||
<X className="h-4 w-4 " />
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close>
|
||||
) : null}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { Input } from '@/components/ui/input';
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
@ -10,17 +9,17 @@ import { IModalProps } from '@/interfaces/common';
|
||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { lowerFirst } from 'lodash';
|
||||
import { Play, X } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { BeginId, Operator } from '../constant';
|
||||
import { CirclePlay, X } from 'lucide-react';
|
||||
import { Operator } from '../constant';
|
||||
import { AgentFormContext } from '../context';
|
||||
import { RunTooltip } from '../flow-tooltip';
|
||||
import { useHandleNodeNameChange } from '../hooks/use-change-node-name';
|
||||
import { useIsMcp } from '../hooks/use-is-mcp';
|
||||
import OperatorIcon from '../operator-icon';
|
||||
import useGraphStore from '../store';
|
||||
import { needsSingleStepDebugging } from '../utils';
|
||||
import { FormConfigMap } from './form-config-map';
|
||||
import SingleDebugSheet from './single-debug-sheet';
|
||||
import { TitleInput } from './title-input';
|
||||
|
||||
interface IProps {
|
||||
node?: RAGFlowNodeType;
|
||||
@ -48,17 +47,7 @@ const FormSheet = ({
|
||||
|
||||
const OperatorForm = currentFormMap?.component ?? EmptyContent;
|
||||
|
||||
const { name, handleNameBlur, handleNameChange } = useHandleNodeNameChange({
|
||||
id: node?.id,
|
||||
data: node?.data,
|
||||
});
|
||||
|
||||
const isMcp = useMemo(() => {
|
||||
return (
|
||||
operatorName === Operator.Tool &&
|
||||
Object.values(Operator).every((x) => x !== clickedToolId)
|
||||
);
|
||||
}, [clickedToolId, operatorName]);
|
||||
const isMcp = useIsMcp(operatorName);
|
||||
|
||||
const { t } = useTranslate('flow');
|
||||
|
||||
@ -75,36 +64,19 @@ const FormSheet = ({
|
||||
<section className="flex-col border-b py-2 px-5">
|
||||
<div className="flex items-center gap-2 pb-3">
|
||||
<OperatorIcon name={operatorName}></OperatorIcon>
|
||||
|
||||
{isMcp ? (
|
||||
<div className="flex-1">MCP Config</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-1 flex-1">
|
||||
<label htmlFor="">{t('title')}</label>
|
||||
{node?.id === BeginId ? (
|
||||
<span>{t(BeginId)}</span>
|
||||
) : (
|
||||
<Input
|
||||
value={name}
|
||||
onBlur={handleNameBlur}
|
||||
onChange={handleNameChange}
|
||||
></Input>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<TitleInput node={node}></TitleInput>
|
||||
{needsSingleStepDebugging(operatorName) && (
|
||||
<RunTooltip>
|
||||
<Play
|
||||
className="size-5 cursor-pointer"
|
||||
<CirclePlay
|
||||
className="size-3.5 cursor-pointer"
|
||||
onClick={showSingleDebugDrawer}
|
||||
/>
|
||||
</RunTooltip>
|
||||
)}
|
||||
<X onClick={hideModal} />
|
||||
<X onClick={hideModal} className="size-3.5 cursor-pointer" />
|
||||
</div>
|
||||
{isMcp || (
|
||||
<span>
|
||||
<span className="text-text-secondary">
|
||||
{t(
|
||||
`${lowerFirst(operatorName === Operator.Tool ? clickedToolId : operatorName)}Description`,
|
||||
)}
|
||||
|
||||
61
web/src/pages/agent/form-sheet/title-input.tsx
Normal file
61
web/src/pages/agent/form-sheet/title-input.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { RAGFlowNodeType } from '@/interfaces/database/agent';
|
||||
import { PenLine } from 'lucide-react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BeginId, Operator } from '../constant';
|
||||
import { useHandleNodeNameChange } from '../hooks/use-change-node-name';
|
||||
import { useIsMcp } from '../hooks/use-is-mcp';
|
||||
|
||||
type TitleInputProps = {
|
||||
node?: RAGFlowNodeType;
|
||||
};
|
||||
|
||||
export function TitleInput({ node }: TitleInputProps) {
|
||||
const { t } = useTranslation();
|
||||
const { name, handleNameBlur, handleNameChange } = useHandleNodeNameChange({
|
||||
id: node?.id,
|
||||
data: node?.data,
|
||||
});
|
||||
|
||||
const operatorName: Operator = node?.data.label as Operator;
|
||||
|
||||
const isMcp = useIsMcp(operatorName);
|
||||
|
||||
const [isEditingMode, setIsEditingMode] = useState(false);
|
||||
|
||||
const switchIsEditingMode = useCallback(() => {
|
||||
setIsEditingMode((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
handleNameBlur();
|
||||
setIsEditingMode(false);
|
||||
}, [handleNameBlur]);
|
||||
|
||||
if (isMcp) {
|
||||
return <div className="flex-1 text-base">MCP Config</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1 flex-1">
|
||||
{node?.id === BeginId ? (
|
||||
<span>{t(BeginId)}</span>
|
||||
) : isEditingMode ? (
|
||||
<Input
|
||||
value={name}
|
||||
onBlur={handleBlur}
|
||||
onChange={handleNameChange}
|
||||
></Input>
|
||||
) : (
|
||||
<div className="flex items-center gap-2.5 text-base">
|
||||
{name}
|
||||
<PenLine
|
||||
onClick={switchIsEditingMode}
|
||||
className="size-3.5 text-text-secondary cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -28,18 +28,31 @@ import { useDeleteAgentNodeMCP } from './tool-popover/use-update-mcp';
|
||||
import { useDeleteAgentNodeTools } from './tool-popover/use-update-tools';
|
||||
import { useGetAgentMCPIds, useGetAgentToolNames } from './use-get-tools';
|
||||
|
||||
type ToolCardProps = React.HTMLAttributes<HTMLLIElement> &
|
||||
PropsWithChildren & {
|
||||
isNodeTool?: boolean;
|
||||
};
|
||||
|
||||
export function ToolCard({
|
||||
children,
|
||||
className,
|
||||
isNodeTool = true,
|
||||
...props
|
||||
}: PropsWithChildren & React.HTMLAttributes<HTMLLIElement>) {
|
||||
}: ToolCardProps) {
|
||||
const element = useMemo(() => {
|
||||
return (
|
||||
<LabelCard {...props} className={cn('flex justify-between', className)}>
|
||||
<LabelCard
|
||||
{...props}
|
||||
className={cn(
|
||||
'flex justify-between ',
|
||||
{ 'p-2.5 text-text-primary text-sm': !isNodeTool },
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</LabelCard>
|
||||
);
|
||||
}, [children, className, props]);
|
||||
}, [children, className, isNodeTool, props]);
|
||||
|
||||
if (children === Operator.Code) {
|
||||
return (
|
||||
@ -67,13 +80,13 @@ function ActionButton<T>({ deleteRecord, record, edit }: ActionButtonProps<T>) {
|
||||
}, [deleteRecord, record]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2 text-text-secondary">
|
||||
<div className="flex items-center gap-4 text-text-secondary">
|
||||
<PencilLine
|
||||
className="size-4 cursor-pointer"
|
||||
className="size-3.5 cursor-pointer"
|
||||
data-tool={record}
|
||||
onClick={edit}
|
||||
/>
|
||||
<X className="size-4 cursor-pointer" onClick={handleDelete} />
|
||||
<X className="size-3.5 cursor-pointer" onClick={handleDelete} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -102,10 +115,10 @@ export function AgentTools() {
|
||||
|
||||
return (
|
||||
<section className="space-y-2.5">
|
||||
<span className="text-text-secondary">{t('flow.tools')}</span>
|
||||
<ul className="space-y-2">
|
||||
<span className="text-text-secondary text-sm">{t('flow.tools')}</span>
|
||||
<ul className="space-y-2.5">
|
||||
{toolNames.map((x) => (
|
||||
<ToolCard key={x}>
|
||||
<ToolCard key={x} isNodeTool={false}>
|
||||
<div className="flex gap-2 items-center">
|
||||
<OperatorIcon name={x as Operator}></OperatorIcon>
|
||||
{x}
|
||||
@ -118,7 +131,7 @@ export function AgentTools() {
|
||||
</ToolCard>
|
||||
))}
|
||||
{mcpIds.map((id) => (
|
||||
<ToolCard key={id}>
|
||||
<ToolCard key={id} isNodeTool={false}>
|
||||
{findMcpById(id)?.name}
|
||||
<ActionButton
|
||||
record={id}
|
||||
@ -156,13 +169,13 @@ export function Agents({ node }: INextOperatorForm) {
|
||||
|
||||
return (
|
||||
<section className="space-y-2.5">
|
||||
<span className="text-text-secondary">{t('flow.agent')}</span>
|
||||
<ul className="space-y-2">
|
||||
<span className="text-text-secondary text-sm">{t('flow.agent')}</span>
|
||||
<ul className="space-y-2.5">
|
||||
{subBottomAgentNodeIds.map((id) => {
|
||||
const currentNode = getNode(id);
|
||||
|
||||
return (
|
||||
<ToolCard key={id}>
|
||||
<ToolCard key={id} isNodeTool={false}>
|
||||
{currentNode?.data.name}
|
||||
<ActionButton
|
||||
record={id}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Collapse } from '@/components/collapse';
|
||||
import { FormContainer } from '@/components/form-container';
|
||||
import {
|
||||
LargeModelFilterFormSchema,
|
||||
LargeModelFormField,
|
||||
@ -15,6 +14,7 @@ import {
|
||||
FormLabel,
|
||||
} from '@/components/ui/form';
|
||||
import { Input, NumberInput } from '@/components/ui/input';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { LlmModelType } from '@/constants/knowledge';
|
||||
import { useFindLlmByUuid } from '@/hooks/use-llm-request';
|
||||
@ -124,66 +124,53 @@ function AgentForm({ node }: INextOperatorForm) {
|
||||
return (
|
||||
<Form {...form}>
|
||||
<FormWrapper>
|
||||
<FormContainer>
|
||||
{isSubAgent && <DescriptionField></DescriptionField>}
|
||||
<LargeModelFormField showSpeech2TextModel></LargeModelFormField>
|
||||
{findLlmByUuid(llmId)?.model_type === LlmModelType.Image2text && (
|
||||
<QueryVariable
|
||||
name="visual_files_var"
|
||||
label="Visual Input File"
|
||||
type={VariableType.File}
|
||||
></QueryVariable>
|
||||
{isSubAgent && <DescriptionField></DescriptionField>}
|
||||
<LargeModelFormField showSpeech2TextModel></LargeModelFormField>
|
||||
{findLlmByUuid(llmId)?.model_type === LlmModelType.Image2text && (
|
||||
<QueryVariable
|
||||
name="visual_files_var"
|
||||
label="Visual Input File"
|
||||
type={VariableType.File}
|
||||
></QueryVariable>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`sys_prompt`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{t('flow.systemPrompt')}</FormLabel>
|
||||
<FormControl>
|
||||
<PromptEditor
|
||||
{...field}
|
||||
placeholder={t('flow.messagePlaceholder')}
|
||||
showToolbar={true}
|
||||
extraOptions={extraOptions}
|
||||
></PromptEditor>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
</FormContainer>
|
||||
|
||||
<FormContainer>
|
||||
/>
|
||||
{isSubAgent || (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`sys_prompt`}
|
||||
name={`prompts`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{t('flow.systemPrompt')}</FormLabel>
|
||||
<FormLabel>{t('flow.userPrompt')}</FormLabel>
|
||||
<FormControl>
|
||||
<PromptEditor
|
||||
{...field}
|
||||
placeholder={t('flow.messagePlaceholder')}
|
||||
showToolbar={true}
|
||||
extraOptions={extraOptions}
|
||||
></PromptEditor>
|
||||
<section>
|
||||
<PromptEditor {...field} showToolbar={true}></PromptEditor>
|
||||
</section>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</FormContainer>
|
||||
{isSubAgent || (
|
||||
<FormContainer>
|
||||
{/* <DynamicPrompt></DynamicPrompt> */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`prompts`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{t('flow.userPrompt')}</FormLabel>
|
||||
<FormControl>
|
||||
<section>
|
||||
<PromptEditor
|
||||
{...field}
|
||||
showToolbar={true}
|
||||
></PromptEditor>
|
||||
</section>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</FormContainer>
|
||||
)}
|
||||
|
||||
<FormContainer>
|
||||
<AgentTools></AgentTools>
|
||||
<Agents node={node}></Agents>
|
||||
</FormContainer>
|
||||
<Separator></Separator>
|
||||
<AgentTools></AgentTools>
|
||||
<Agents node={node}></Agents>
|
||||
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||
<FormContainer>
|
||||
<section className="space-y-5">
|
||||
<MessageHistoryWindowSizeFormField></MessageHistoryWindowSizeFormField>
|
||||
<FormField
|
||||
control={form.control}
|
||||
@ -270,7 +257,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</FormContainer>
|
||||
</section>
|
||||
</Collapse>
|
||||
<Output list={outputList}></Output>
|
||||
</FormWrapper>
|
||||
|
||||
@ -147,53 +147,48 @@ export function QueryTable({ data = [], deleteRecord, showModal }: IProps) {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div className="rounded-md border">
|
||||
<Table rootClassName="rounded-md">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
<div className="rounded-md border w-full bg-bg-card">
|
||||
<Table rootClassName="rounded-md">
|
||||
<TableHeader className="bg-bg-card">
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className={cn(cell.column.columnDef.meta?.cellClassName)}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className={cn(cell.column.columnDef.meta?.cellClassName)}
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableEmpty columnsLength={columns.length}></TableEmpty>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<TableEmpty columnsLength={columns.length}></TableEmpty>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
.typeahead-popover {
|
||||
background: #fff;
|
||||
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
position: fixed;
|
||||
@ -10,16 +9,6 @@
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.typeahead-popover ul::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.typeahead-popover ul {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.typeahead-popover ul li {
|
||||
@ -28,7 +17,6 @@
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.typeahead-popover ul li.selected {
|
||||
@ -37,7 +25,6 @@
|
||||
|
||||
.typeahead-popover li {
|
||||
margin: 0 8px 0 8px;
|
||||
color: #050505;
|
||||
cursor: pointer;
|
||||
line-height: 16px;
|
||||
font-size: 15px;
|
||||
@ -45,7 +32,6 @@
|
||||
align-content: center;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
background-color: #fff;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ function PromptContent({
|
||||
|
||||
return (
|
||||
<section
|
||||
className={cn('border rounded-sm ', { 'border-blue-400': !isBlur })}
|
||||
className={cn('border rounded-sm ', { 'border-accent-primary': !isBlur })}
|
||||
>
|
||||
{showToolbar && (
|
||||
<div className="border-b px-2 py-2 justify-end flex">
|
||||
@ -107,7 +107,7 @@ function PromptContent({
|
||||
)}
|
||||
<ContentEditable
|
||||
className={cn(
|
||||
'relative px-2 py-1 focus-visible:outline-none max-h-[50vh] overflow-auto',
|
||||
'relative px-2 py-1 focus-visible:outline-none max-h-[50vh] overflow-auto text-sm',
|
||||
{
|
||||
'min-h-40': multiLine,
|
||||
},
|
||||
@ -163,7 +163,7 @@ export function PromptEditor({
|
||||
placeholder={
|
||||
<div
|
||||
className={cn(
|
||||
'absolute top-1 left-2 text-text-secondary pointer-events-none',
|
||||
'absolute top-1 left-2 text-text-disabled pointer-events-none',
|
||||
{
|
||||
'truncate w-[90%]': !multiLine,
|
||||
'translate-y-10': multiLine,
|
||||
|
||||
@ -49,7 +49,7 @@ export class VariableNode extends DecoratorNode<ReactNode> {
|
||||
|
||||
decorate(): ReactNode {
|
||||
let content: ReactNode = (
|
||||
<div className="text-blue-600">{this.__label}</div>
|
||||
<div className="text-accent-primary">{this.__label}</div>
|
||||
);
|
||||
if (this.__parentLabel) {
|
||||
content = (
|
||||
@ -62,7 +62,7 @@ export class VariableNode extends DecoratorNode<ReactNode> {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="bg-gray-200 dark:bg-gray-400 text-sm inline-flex items-center rounded-md px-2 py-1">
|
||||
<div className="bg-accent-primary-5 text-sm inline-flex items-center rounded-md px-2 py-1">
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -91,13 +91,13 @@ function VariablePickerMenuItem({
|
||||
id={'typeahead-item-' + index}
|
||||
>
|
||||
<div>
|
||||
<span className="text text-slate-500">{option.title}</span>
|
||||
<span className="text text-text-secondary">{option.title}</span>
|
||||
<ul className="pl-2 py-1">
|
||||
{option.options.map((x) => (
|
||||
<li
|
||||
key={x.value}
|
||||
onClick={() => selectOptionAndCleanUp(x)}
|
||||
className="hover:bg-slate-300 p-1"
|
||||
className="hover:bg-bg-card p-1 text-text-primary rounded-sm"
|
||||
>
|
||||
{x.label}
|
||||
</li>
|
||||
@ -335,8 +335,8 @@ export default function VariablePickerMenuPlugin({
|
||||
const nextOptions = buildNextOptions();
|
||||
return anchorElementRef.current && nextOptions.length
|
||||
? ReactDOM.createPortal(
|
||||
<div className="typeahead-popover w-[200px] p-2">
|
||||
<ul className="overflow-y-auto !scrollbar-thin overflow-x-hidden">
|
||||
<div className="typeahead-popover w-[200px] p-2 bg-bg-base">
|
||||
<ul className="scroll-auto overflow-x-hidden">
|
||||
{nextOptions.map((option, i: number) => (
|
||||
<VariablePickerMenuItem
|
||||
index={i}
|
||||
|
||||
11
web/src/pages/agent/hooks/use-is-mcp.ts
Normal file
11
web/src/pages/agent/hooks/use-is-mcp.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Operator } from '../constant';
|
||||
import useGraphStore from '../store';
|
||||
|
||||
export function useIsMcp(operatorName: Operator) {
|
||||
const clickedToolId = useGraphStore((state) => state.clickedToolId);
|
||||
|
||||
return (
|
||||
operatorName === Operator.Tool &&
|
||||
Object.values(Operator).every((x) => x !== clickedToolId)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user