Spaces:
Paused
Paused
File size: 3,547 Bytes
0b9dc2e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | import { CircleAlert, Loader2, PlusCircle } from 'lucide-react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import type { ContextConfig, ReActConfig } from '@/api';
import {
AgentFormFields,
defaultAgentFormValues,
type AgentFormValues,
type AgentSection,
} from '@/components/form/AgentFormFields';
import type { SchemaFormValue } from '@/components/form/SchemaForm';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogDescription,
DialogTrigger,
} from '@/components/ui/dialog';
import { useAgents } from '@/hooks/useAgents';
import { useAgentSchema } from '@/hooks/useAgentSchema';
interface Props {
onCreated?: () => void;
triggerId?: string;
}
export function AgentDialog({ onCreated, triggerId }: Props) {
const { create } = useAgents();
const { t } = useTranslation();
const { schema } = useAgentSchema();
const [open, setOpen] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [values, setValues] = useState<AgentFormValues | null>(null);
useEffect(() => {
if (open && schema && !values) {
setValues(defaultAgentFormValues(schema));
}
if (!open) setValues(null);
}, [open, schema, values]);
const handleChange = (section: AgentSection, key: string, value: SchemaFormValue) => {
setValues((prev) =>
prev ? { ...prev, [section]: { ...prev[section], [key]: value } } : prev,
);
};
const handleSubmit = async () => {
if (!values) return;
const name = (values.identity.name as string | undefined)?.trim();
if (!name) return;
setSubmitting(true);
try {
await create({
name,
system_prompt: values.identity.system_prompt as string | undefined,
context_config: values.context_config as unknown as ContextConfig,
react_config: values.react_config as unknown as ReActConfig,
});
setOpen(false);
onCreated?.();
} finally {
setSubmitting(false);
}
};
const nameValid = !!(values?.identity.name as string | undefined)?.trim();
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button id={triggerId}>
<PlusCircle />
<span>{t('dialog-agent-create.trigger')}</span>
</Button>
</DialogTrigger>
<DialogContent className="!w-[500px] !max-w-[500px]">
<DialogHeader>
<DialogTitle>{t('dialog-agent-create.title')}</DialogTitle>
<DialogDescription className="sr-only">
{t('dialog-agent-create.description')}
</DialogDescription>
</DialogHeader>
<div className="no-scrollbar -mx-4 max-h-[75vh] overflow-y-auto px-4">
{schema && values ? (
<AgentFormFields schema={schema} values={values} onChange={handleChange} />
) : (
<p className="text-muted-foreground text-sm">{t('common.loading')}</p>
)}
</div>
<DialogFooter>
<Button variant="ghost" onClick={() => setOpen(false)} disabled={submitting}>
<CircleAlert className="size-3.5" />
{t('common.cancel')}
</Button>
<Button
onClick={handleSubmit}
disabled={!nameValid || submitting || !schema || !values}
>
{submitting ? (
<Loader2 className="size-3.5 animate-spin" />
) : (
<PlusCircle className="size-3.5" />
)}
{submitting ? t('common.creating') : t('common.create')}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
|