fix(permissions): tools MCP inter-projets exposés (idea_project_*) + contactable agent/template persisté — update_agent_contactable (application/web-server/app-tauri), defaultContactable TemplateEditor save/reopen, groupes MCP 'IdeA inter-projets' avec fallback, permissions agent Contactable — #267 (QA verte)
This commit is contained in:
@ -4,12 +4,16 @@ import remarkGfm from "remark-gfm";
|
||||
|
||||
import type {
|
||||
AgentProfile,
|
||||
McpToolCatalogue,
|
||||
McpToolPolicy,
|
||||
NetworkPolicy,
|
||||
SystemPermissionSet,
|
||||
Template,
|
||||
} from "@/domain";
|
||||
import { MCP_TOOL_GROUPS, mcpToolLabel } from "@/features/permissions/mcpToolGroups";
|
||||
import {
|
||||
mcpToolGroupsForCatalogue,
|
||||
mcpToolLabel,
|
||||
} from "@/features/permissions/mcpToolGroups";
|
||||
import { Button, Input, SmallDropdown, cn } from "@/shared";
|
||||
import { profileLabel } from "./templatePresentation";
|
||||
|
||||
@ -18,6 +22,7 @@ export interface TemplateEditorSaveInput {
|
||||
content: string;
|
||||
defaultProfileId: string;
|
||||
defaultAgentName: string | null;
|
||||
defaultContactable: boolean;
|
||||
systemPermissions: SystemPermissionSet | null;
|
||||
mcpToolPermissions: McpToolPolicy | null;
|
||||
}
|
||||
@ -25,6 +30,7 @@ export interface TemplateEditorSaveInput {
|
||||
export interface TemplateEditorProps {
|
||||
template?: Template | null;
|
||||
profiles: AgentProfile[];
|
||||
mcpCatalogue: McpToolCatalogue;
|
||||
onSave: (input: TemplateEditorSaveInput) => Promise<void>;
|
||||
onClose: () => void;
|
||||
busy?: boolean;
|
||||
@ -42,13 +48,10 @@ const NETWORK_OPTIONS: { value: "" | NetworkPolicy; label: string }[] = [
|
||||
const TEMPLATE_CROSS_PROJECT_HELP =
|
||||
"Les agents créés avec ce template reprendront cette permission.";
|
||||
|
||||
const ALL_MCP_TOOLS = Array.from(
|
||||
new Set(MCP_TOOL_GROUPS.flatMap((group) => group.tools)),
|
||||
);
|
||||
|
||||
export function TemplateEditor({
|
||||
template,
|
||||
profiles,
|
||||
mcpCatalogue,
|
||||
onSave,
|
||||
onClose,
|
||||
busy = false,
|
||||
@ -64,13 +67,21 @@ export function TemplateEditor({
|
||||
const [network, setNetwork] = useState<"" | NetworkPolicy>(
|
||||
template?.systemPermissions?.network ?? "",
|
||||
);
|
||||
const [crossProjectContactable, setCrossProjectContactable] = useState(
|
||||
template?.systemPermissions?.crossProjectContactable ?? false,
|
||||
const [defaultContactable, setDefaultContactable] = useState(
|
||||
template?.defaultContactable ?? false,
|
||||
);
|
||||
const [allowedTools, setAllowedTools] = useState<string[]>(
|
||||
template?.mcpToolPermissions?.allowedTools ?? [],
|
||||
);
|
||||
const [tab, setTab] = useState<EditorTab>("edit");
|
||||
const toolGroups = useMemo(
|
||||
() => mcpToolGroupsForCatalogue(mcpCatalogue),
|
||||
[mcpCatalogue],
|
||||
);
|
||||
const allMcpTools = useMemo(
|
||||
() => toolGroups.flatMap((group) => group.tools),
|
||||
[toolGroups],
|
||||
);
|
||||
|
||||
const allowed = useMemo(() => new Set(allowedTools), [allowedTools]);
|
||||
const canSave = name.trim().length > 0 && !busy;
|
||||
@ -91,15 +102,8 @@ export function TemplateEditor({
|
||||
content,
|
||||
defaultProfileId,
|
||||
defaultAgentName: defaultAgentName.trim() || null,
|
||||
systemPermissions:
|
||||
network || crossProjectContactable
|
||||
? {
|
||||
...(network ? { network } : {}),
|
||||
...(crossProjectContactable
|
||||
? { crossProjectContactable: true }
|
||||
: {}),
|
||||
}
|
||||
: null,
|
||||
defaultContactable,
|
||||
systemPermissions: network ? { network } : null,
|
||||
mcpToolPermissions:
|
||||
allowedTools.length > 0 ? { allowedTools: [...allowedTools] } : null,
|
||||
});
|
||||
@ -275,8 +279,8 @@ export function TemplateEditor({
|
||||
<input
|
||||
type="checkbox"
|
||||
aria-label="Contactable depuis d’autres projets"
|
||||
checked={crossProjectContactable}
|
||||
onChange={(e) => setCrossProjectContactable(e.target.checked)}
|
||||
checked={defaultContactable}
|
||||
onChange={(e) => setDefaultContactable(e.target.checked)}
|
||||
disabled={busy}
|
||||
className="mt-0.5 h-4 w-4 shrink-0 accent-primary disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
@ -298,7 +302,7 @@ export function TemplateEditor({
|
||||
</h3>
|
||||
<span className="text-xs text-faint">{allowedTools.length} autorisé(s)</span>
|
||||
</div>
|
||||
{ALL_MCP_TOOLS.length === 0 ? (
|
||||
{allMcpTools.length === 0 ? (
|
||||
<p className="text-sm text-muted">Aucun tool MCP IdeA disponible.</p>
|
||||
) : (
|
||||
<>
|
||||
@ -308,7 +312,7 @@ export function TemplateEditor({
|
||||
</p>
|
||||
)}
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
|
||||
{MCP_TOOL_GROUPS.map((group) => (
|
||||
{toolGroups.map((group) => (
|
||||
<div key={group.id} className="flex min-w-0 flex-col gap-2">
|
||||
<h4 className="text-xs font-semibold text-content">{group.label}</h4>
|
||||
{group.tools.map((tool) => (
|
||||
|
||||
Reference in New Issue
Block a user