diff --git a/web/src/components/projects/integration-form.tsx b/web/src/components/projects/integration-form.tsx index 668daaea..8b28dc55 100644 --- a/web/src/components/projects/integration-form.tsx +++ b/web/src/components/projects/integration-form.tsx @@ -546,7 +546,7 @@ function SCMTab({ />

- Trigger configuration has moved to the Agent Configs tab. + Trigger configuration has moved to the Agents tab.

diff --git a/web/src/components/projects/pm-wizard-common-steps.tsx b/web/src/components/projects/pm-wizard-common-steps.tsx index e9ac410a..71bac5e7 100644 --- a/web/src/components/projects/pm-wizard-common-steps.tsx +++ b/web/src/components/projects/pm-wizard-common-steps.tsx @@ -300,7 +300,7 @@ export function SaveStep({

- Trigger configuration is managed separately in the Agent Configs tab. + Trigger configuration is managed separately in the Agents tab.

diff --git a/web/src/components/projects/project-agent-configs.tsx b/web/src/components/projects/project-agent-configs.tsx index dd998781..7d907083 100644 --- a/web/src/components/projects/project-agent-configs.tsx +++ b/web/src/components/projects/project-agent-configs.tsx @@ -13,6 +13,7 @@ import { SelectTrigger, SelectValue, } from '@/components/ui/select.js'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs.js'; import { AGENT_LABELS, CATEGORY_LABELS, @@ -22,7 +23,6 @@ import { import { trpc, trpcClient } from '@/lib/trpc.js'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { Link } from '@tanstack/react-router'; -import { ChevronDown, ChevronRight } from 'lucide-react'; import { useEffect, useMemo, useRef, useState } from 'react'; import { toast } from 'sonner'; @@ -40,19 +40,6 @@ interface Engine { label: string; } -function AgentConfigBadge({ config }: { config: AgentConfig | null }) { - if (!config) { - return Using defaults; - } - const parts: string[] = []; - if (config.model) parts.push(config.model); - if (config.maxIterations) parts.push(`${config.maxIterations} iterations`); - if (config.maxConcurrency) parts.push(`max ${config.maxConcurrency} concurrent`); - if (config.agentEngine) parts.push(config.agentEngine); - if (parts.length === 0) return Configured; - return {parts.join(' ยท ')}; -} - // ============================================================================ // Definition-Based Agent Section (New) // ============================================================================ @@ -99,7 +86,6 @@ function DefinitionAgentSection({ onTriggerToggle, onTriggerParamChange, }: DefinitionAgentSectionProps) { - const [expanded, setExpanded] = useState(false); const [saved, setSaved] = useState(false); const savedTimerRef = useRef | null>(null); // Tracks whether a successful save is in flight (prevents config sync from clearing "Saved") @@ -199,160 +185,134 @@ function DefinitionAgentSection({ }; return ( -
- {/* Header */} - +
+
+ + setMaxConcurrency(e.target.value)} + placeholder="Optional" + /> +
+
+ + +
+
+
+ +

+ Prompts are managed in{' '} + + Agent Definitions + +

+
+
- {/* Expanded content */} - {expanded && ( -
- {/* Config fields */} -
+ {/* Render triggers by category */} + {(['pm', 'scm', 'internal'] as const).map((category) => { + const categoryTriggers = triggersByCategory[category]; + if (categoryTriggers.length === 0) return null; + + return ( +

- Configuration + {CATEGORY_LABELS[category] ?? category} Triggers

-
-
- - -
-
- - setMaxIterations(e.target.value)} - placeholder="Optional" - /> -
-
-
-
- - setMaxConcurrency(e.target.value)} - placeholder="Optional" - /> -
-
- - -
-
-
- -

- Prompts are managed in{' '} - - Agent Definitions - -

-
+ onTriggerToggle(agentType, event, enabled)} + onParamChange={(event, params) => { + // Find the current trigger to get its enabled state + const currentTrigger = categoryTriggers.find((t) => t.event === event); + onTriggerParamChange(agentType, event, params, currentTrigger?.enabled ?? true); + }} + idPrefix={`${agentType}-${category}`} + />
+ ); + })} - {/* Render triggers by category */} - {(['pm', 'scm', 'internal'] as const).map((category) => { - const categoryTriggers = triggersByCategory[category]; - if (categoryTriggers.length === 0) return null; - - return ( -
-

- {CATEGORY_LABELS[category] ?? category} Triggers -

- onTriggerToggle(agentType, event, enabled)} - onParamChange={(event, params) => { - // Find the current trigger to get its enabled state - const currentTrigger = categoryTriggers.find((t) => t.event === event); - onTriggerParamChange(agentType, event, params, currentTrigger?.enabled ?? true); - }} - idPrefix={`${agentType}-${category}`} - /> -
- ); - })} - - {!hasTriggers && ( -

- No trigger configuration for this agent. -

- )} - - {/* Footer actions */} -
-
- - - {saved && Saved} -
- {config && ( - - )} -
-
+ {!hasTriggers && ( +

No trigger configuration for this agent.

)} + + {/* Footer actions */} +
+
+ + + {saved && Saved} +
+ {config && ( + + )} +
); } @@ -361,6 +321,7 @@ function DefinitionAgentSection({ // Main Component // ============================================================================ +// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: main config component with mutations and lifecycle state export function ProjectAgentConfigs({ projectId }: { projectId: string }) { const queryClient = useQueryClient(); @@ -618,6 +579,7 @@ export function ProjectAgentConfigs({ projectId }: { projectId: string }) { // Get list of agent types to display const agentTypes = Array.from(triggersByAgent.keys()); + const defaultTab = agentTypes[0] ?? ''; return (
@@ -625,27 +587,37 @@ export function ProjectAgentConfigs({ projectId }: { projectId: string }) { Per-agent configuration and trigger settings scoped to this project.

- {/* Agent sections */} -
- {agentTypes.map((type) => ( - deleteMutation.mutate(id)} - onTriggerToggle={handleTriggerToggle} - onTriggerParamChange={handleTriggerParamChange} - /> - ))} -
+ {/* Agent tabs */} + {agentTypes.length > 0 && ( + + + {agentTypes.map((type) => ( + + {(AGENT_LABELS as Record)[type] ?? type} + + ))} + + {agentTypes.map((type) => ( + + deleteMutation.mutate(id)} + onTriggerToggle={handleTriggerToggle} + onTriggerParamChange={handleTriggerParamChange} + /> + + ))} + + )} {/* Lifecycle triggers section */} {LIFECYCLE_TRIGGERS.length > 0 && ( diff --git a/web/src/lib/project-sections.ts b/web/src/lib/project-sections.ts index f5366dba..88698d2d 100644 --- a/web/src/lib/project-sections.ts +++ b/web/src/lib/project-sections.ts @@ -24,7 +24,7 @@ export const PROJECT_SECTIONS: { }, { id: 'agent-configs', - label: 'Agent Configs', + label: 'Agents', path: 'agent-configs', route: '/projects/$projectId/agent-configs', },