import * as React from "react"; import { useTranslation } from "react-i18next"; import { GitBranch, ListPlus, Minus, Plus, Settings2, Users } from "lucide-react"; import { listAgents } from "@/api/agents"; import { createTeam, createTeamConfig, updateTeam, updateTeamConfig } from "@/api"; import { Button } from "@/components/ui/button"; import { Dialog } from "@/components/ui/dialog"; import { Input, Textarea } from "@/components/ui/input"; import { Select } from "@/components/ui/select"; import { toast } from "@/components/ui/toaster"; import { useAuthStore } from "@/stores/auth"; import type { AgentDefinition, JSONObject, TeamConfig, TeamDefinition } from "@/types"; type MemberDraft = { role: string; agent_id: string; responsibility: string; }; type PolicyDraft = { max_rounds: string; handoff: string; failure_mode: string; }; const DEFAULT_POLICY: PolicyDraft = { max_rounds: "3", handoff: "supervisor", failure_mode: "stop_on_critical", }; function createDefaultMember(): MemberDraft { return { role: "executor", agent_id: "", responsibility: "" }; } export function CreateTeamDialog({ open, onOpenChange, onCreated, }: { open: boolean; onOpenChange: (open: boolean) => void; onCreated: (team: TeamDefinition) => void; }) { const { t } = useTranslation(); const { userId } = useAuthStore(); const [form, setForm] = React.useState({ name: "", description: "", coordination_mode: "supervisor", objective: "" }); const [members, setMembers] = React.useState([createDefaultMember()]); const [policy, setPolicy] = React.useState(DEFAULT_POLICY); const [agents, setAgents] = React.useState([]); const [formError, setFormError] = React.useState(); const [submitting, setSubmitting] = React.useState(false); React.useEffect(() => { if (!open) return; void listAgents().then(setAgents).catch(() => {}); }, [open]); function reset() { setForm({ name: "", description: "", coordination_mode: "supervisor", objective: "" }); setMembers([createDefaultMember()]); setPolicy(DEFAULT_POLICY); setFormError(undefined); } async function submit(event: React.FormEvent) { event.preventDefault(); if (!form.name.trim()) return; const configPayload = buildTeamConfig(members, agents, policy, t); if (!configPayload.ok) { setFormError(configPayload.message); return; } setSubmitting(true); setFormError(undefined); try { const team = await createTeam({ name: form.name, description: form.description || undefined, team_type: "collaborative", owner_user_id: userId }); await createTeamConfig({ team_id: team.id, coordination_mode: form.coordination_mode, objective: form.objective || undefined, member_refs: configPayload.memberRefs, policy_json: configPayload.policyJson, }); toast.success(t("teams.teamCreated")); onOpenChange(false); reset(); onCreated(team); } catch (err) { toast.error(err instanceof Error ? err.message : t("teams.failedCreateTeam")); } finally { setSubmitting(false); } } return ( { if (!value) reset(); onOpenChange(value); }} title={t("teams.newTeam")} description={t("teams.createTeamDefineObjective")} className="max-w-6xl" >
} label={t("teams.coordination")} value={t(`teams.${form.coordination_mode}`)} /> } label={t("teams.members")} value={String(members.length)} /> } label={t("teams.maxRoundsField")} value={policy.max_rounds} />
} title={t("teams.basicInfo")} />
setForm({ ...form, name: event.target.value })} />