fix: remove capabilities/prompt/model from agent modal, add mentionable
This commit is contained in:
parent
be2b073e4c
commit
c00a3ea1f1
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import type { Member, Label } from "@/lib/api";
|
import type { Member, Label } from "@/lib/api";
|
||||||
import { updateMember, regenerateToken, revokeToken, getLabels } from "@/lib/api";
|
import { updateMember, regenerateToken, revokeToken, getLabels } from "@/lib/api";
|
||||||
@ -13,13 +12,9 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
const [name, setName] = useState(agent.name);
|
const [name, setName] = useState(agent.name);
|
||||||
const [slug, setSlug] = useState(agent.slug);
|
const [slug, setSlug] = useState(agent.slug);
|
||||||
const [slugError, setSlugError] = useState("");
|
const [slugError, setSlugError] = useState("");
|
||||||
const [capabilities, setCapabilities] = useState(
|
|
||||||
agent.agent_config?.capabilities?.join(", ") || ""
|
|
||||||
);
|
|
||||||
const [chatListen, setChatListen] = useState(agent.agent_config?.chat_listen || "mentions");
|
const [chatListen, setChatListen] = useState(agent.agent_config?.chat_listen || "mentions");
|
||||||
const [taskListen, setTaskListen] = useState(agent.agent_config?.task_listen || "assigned");
|
const [taskListen, setTaskListen] = useState(agent.agent_config?.task_listen || "assigned");
|
||||||
const [prompt, setPrompt] = useState(agent.agent_config?.prompt || "");
|
const [mentionable, setMentionable] = useState(agent.agent_config?.mentionable ?? true);
|
||||||
const [model, setModel] = useState(agent.agent_config?.model || "");
|
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [currentToken, setCurrentToken] = useState<string | null>(agent.token || null);
|
const [currentToken, setCurrentToken] = useState<string | null>(agent.token || null);
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
@ -35,7 +30,6 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
try {
|
try {
|
||||||
const caps = capabilities.split(",").map((c) => c.trim()).filter(Boolean);
|
|
||||||
const trimmedSlug = slug.trim().toLowerCase().replace(/[^a-z0-9_-]/g, '');
|
const trimmedSlug = slug.trim().toLowerCase().replace(/[^a-z0-9_-]/g, '');
|
||||||
if (!trimmedSlug) {
|
if (!trimmedSlug) {
|
||||||
setSlugError("Slug не может быть пустым");
|
setSlugError("Slug не может быть пустым");
|
||||||
@ -45,12 +39,10 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
name: name.trim(),
|
name: name.trim(),
|
||||||
slug: trimmedSlug !== agent.slug ? trimmedSlug : undefined,
|
slug: trimmedSlug !== agent.slug ? trimmedSlug : undefined,
|
||||||
agent_config: {
|
agent_config: {
|
||||||
capabilities: caps,
|
|
||||||
labels: agentLabels,
|
labels: agentLabels,
|
||||||
chat_listen: chatListen,
|
chat_listen: chatListen,
|
||||||
task_listen: taskListen,
|
task_listen: taskListen,
|
||||||
prompt: prompt.trim() || null,
|
mentionable,
|
||||||
model: model.trim() || null,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
onUpdated(updated);
|
onUpdated(updated);
|
||||||
@ -97,13 +89,13 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={onClose}>
|
<div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={onClose}>
|
||||||
<div
|
<div
|
||||||
className="bg-[var(--card)] border border-[var(--border)] rounded-xl w-full max-w-lg"
|
className="bg-[var(--card)] border border-[var(--border)] rounded-xl w-full max-w-lg max-h-[90vh] overflow-y-auto"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<div className="p-5 border-b border-[var(--border)] flex items-center justify-between">
|
<div className="p-5 border-b border-[var(--border)] flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-lg font-bold">{agent.name}</h2>
|
<h2 className="text-lg font-bold">{agent.name}</h2>
|
||||||
<div className="text-xs text-[var(--muted)]">@{agent.slug}</div>
|
<div className="text-xs text-[var(--muted)]">@{agent.slug} • {agent.type}</div>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
className={`text-xs px-2 py-0.5 rounded-full ${
|
className={`text-xs px-2 py-0.5 rounded-full ${
|
||||||
@ -137,16 +129,6 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
{slugError && <div className="text-xs text-red-400 mt-1">{slugError}</div>}
|
{slugError && <div className="text-xs text-red-400 mt-1">{slugError}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm text-[var(--muted)] mb-1">Capabilities</label>
|
|
||||||
<input
|
|
||||||
value={capabilities}
|
|
||||||
onChange={(e) => setCapabilities(e.target.value)}
|
|
||||||
className="w-full 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"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Labels */}
|
{/* Labels */}
|
||||||
{allLabels.length > 0 && (
|
{allLabels.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
@ -177,51 +159,41 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-[var(--muted)] mb-1">Chat listen</label>
|
<label className="block text-sm text-[var(--muted)] mb-1">Чат</label>
|
||||||
<select
|
<select
|
||||||
value={chatListen}
|
value={chatListen}
|
||||||
onChange={(e) => setChatListen(e.target.value)}
|
onChange={(e) => setChatListen(e.target.value)}
|
||||||
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm"
|
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm"
|
||||||
>
|
>
|
||||||
<option value="all">all</option>
|
<option value="all">Все сообщения</option>
|
||||||
<option value="mentions">mentions</option>
|
<option value="mentions">Только @упоминания</option>
|
||||||
<option value="none">none</option>
|
<option value="none">Не слушать</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-[var(--muted)] mb-1">Task listen</label>
|
<label className="block text-sm text-[var(--muted)] mb-1">Задачи</label>
|
||||||
<select
|
<select
|
||||||
value={taskListen}
|
value={taskListen}
|
||||||
onChange={(e) => setTaskListen(e.target.value)}
|
onChange={(e) => setTaskListen(e.target.value)}
|
||||||
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm"
|
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm"
|
||||||
>
|
>
|
||||||
<option value="all">all</option>
|
<option value="all">Все задачи</option>
|
||||||
<option value="assigned">assigned</option>
|
<option value="assigned">Назначенные</option>
|
||||||
<option value="none">none</option>
|
<option value="none">Не слушать</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
{/* Mentionable */}
|
||||||
<label className="block text-sm text-[var(--muted)] mb-1">Prompt</label>
|
<label className="flex items-center gap-2 cursor-pointer">
|
||||||
<textarea
|
|
||||||
value={prompt}
|
|
||||||
onChange={(e) => setPrompt(e.target.value)}
|
|
||||||
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm resize-y min-h-[60px]"
|
|
||||||
rows={3}
|
|
||||||
placeholder="Системный промпт агента..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm text-[var(--muted)] mb-1">Модель</label>
|
|
||||||
<input
|
<input
|
||||||
value={model}
|
type="checkbox"
|
||||||
onChange={(e) => setModel(e.target.value)}
|
checked={mentionable}
|
||||||
className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm"
|
onChange={(e) => setMentionable(e.target.checked)}
|
||||||
placeholder="claude-sonnet-4-20250514, gpt-4o, ..."
|
className="accent-[var(--accent)]"
|
||||||
/>
|
/>
|
||||||
</div>
|
<span className="text-sm">Можно @упоминать</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
{/* Token section */}
|
{/* Token section */}
|
||||||
<div className="pt-3 border-t border-[var(--border)]">
|
<div className="pt-3 border-t border-[var(--border)]">
|
||||||
@ -231,7 +203,7 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) {
|
|||||||
<div className="p-3 bg-[var(--bg)] border border-[var(--border)] rounded-lg font-mono text-xs break-all select-all mb-2">
|
<div className="p-3 bg-[var(--bg)] border border-[var(--border)] rounded-lg font-mono text-xs break-all select-all mb-2">
|
||||||
{currentToken}
|
{currentToken}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
<button
|
<button
|
||||||
onClick={copyToken}
|
onClick={copyToken}
|
||||||
className="px-3 py-1.5 bg-[var(--accent)] text-white rounded text-xs hover:opacity-90"
|
className="px-3 py-1.5 bg-[var(--accent)] text-white rounded text-xs hover:opacity-90"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user