From f82a89c2f98bc8931134f1699d8b944920d3b77b Mon Sep 17 00:00:00 2001 From: Markov Date: Sat, 14 Mar 2026 17:10:02 +0100 Subject: [PATCH] feat: improved create agent form (role, labels, chat/task listen, mentionable) --- src/components/CreateAgentModal.tsx | 115 +++++++++++++++++++--------- src/components/MentionInput.tsx | 11 ++- src/lib/api.ts | 3 + 3 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/components/CreateAgentModal.tsx b/src/components/CreateAgentModal.tsx index 7a813b8..8519a77 100644 --- a/src/components/CreateAgentModal.tsx +++ b/src/components/CreateAgentModal.tsx @@ -1,4 +1,3 @@ - import { useState } from "react"; import type { MemberCreateResponse } from "@/lib/api"; import { createMember } from "@/lib/api"; @@ -10,7 +9,11 @@ interface Props { export default function CreateAgentModal({ onCreated, onClose }: Props) { const [name, setName] = useState(""); - const [capabilities, setCapabilities] = useState(""); + const [role, setRole] = useState("member"); + const [chatListen, setChatListen] = useState("mentions"); + const [taskListen, setTaskListen] = useState("assigned"); + const [labels, setLabels] = useState(""); + const [mentionable, setMentionable] = useState(true); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [token, setToken] = useState(null); @@ -29,18 +32,17 @@ export default function CreateAgentModal({ onCreated, onClose }: Props) { setLoading(true); setError(""); try { - const caps = capabilities - .split(",") - .map((c) => c.trim()) - .filter(Boolean); + const labelList = labels.split(",").map((l) => l.trim()).filter(Boolean); const member = await createMember({ name: name.trim(), slug, type: "agent", + role, agent_config: { - capabilities: caps, - chat_listen: "mentions", - task_listen: "assigned", + labels: labelList, + chat_listen: chatListen, + task_listen: taskListen, + mentionable, }, }); if (member.token) { @@ -71,22 +73,16 @@ export default function CreateAgentModal({ onCreated, onClose }: Props) { >

Агент создан

- ⚠️ Токен показывается только один раз. Сохраните его сейчас! + ⚠️ Токен показывается только один раз. Сохраните его!
{token}
- -
@@ -100,49 +96,92 @@ export default function CreateAgentModal({ onCreated, onClose }: Props) {
e.stopPropagation()} onSubmit={handleSubmit} - className="bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 w-96" + className="bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 w-[420px] max-h-[90vh] overflow-y-auto" >

Новый агент

{error && ( -
- {error} -
+
{error}
)} + {/* Название */} setName(e.target.value)} - className="w-full mb-1 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg - outline-none focus:border-[var(--accent)] text-sm" + className="w-full mb-1 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm" placeholder="Code Assistant" /> - {slug &&
Slug: {slug}
} + {slug &&
slug: {slug}
} - + {/* Роль */} + + + + {/* Labels */} + setCapabilities(e.target.value)} - className="w-full mb-4 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg - outline-none focus:border-[var(--accent)] text-sm" - placeholder="code, review, deploy" + value={labels} + onChange={(e) => setLabels(e.target.value)} + className="w-full mb-3 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm" + placeholder="backend, python, devops" /> + {/* Chat Listen */} +
+
+ + +
+
+ + +
+
+ + {/* Mentionable */} + +
- diff --git a/src/components/MentionInput.tsx b/src/components/MentionInput.tsx index a8da63c..ebbe479 100644 --- a/src/components/MentionInput.tsx +++ b/src/components/MentionInput.tsx @@ -27,10 +27,13 @@ export default function MentionInput({ projectId, value, onChange, onSubmit, onM getProjectMembers(projectId).then(setMembers).catch(() => {}); }, [projectId]); - const filtered = members.filter((m) => - m.name.toLowerCase().includes(filter.toLowerCase()) || - m.slug.toLowerCase().includes(filter.toLowerCase()) - ); + const filtered = members.filter((m) => { + // Скрываем не-mentionable (bridge, system agents) + if (m.agent_config?.mentionable === false) return false; + if (m.type === "bridge") return false; + return m.name.toLowerCase().includes(filter.toLowerCase()) || + m.slug.toLowerCase().includes(filter.toLowerCase()); + }); const insertMention = useCallback((member: ProjectMember) => { if (mentionStart < 0) return; diff --git a/src/lib/api.ts b/src/lib/api.ts index 76b5482..31578a1 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -59,6 +59,7 @@ export interface AgentConfig { task_listen: string; prompt: string | null; model: string | null; + mentionable: boolean; } export interface Member { @@ -96,6 +97,7 @@ export interface ProjectMember { slug: string; type: string; role: string; + agent_config?: AgentConfig | null; } export interface Step { @@ -309,6 +311,7 @@ export async function createMember(data: { name: string; slug: string; type?: string; + role?: string; agent_config?: Partial; }): Promise { return request("/api/v1/members", { method: "POST", body: JSON.stringify(data) });