@@ -18,7 +18,12 @@ import {
1818 searchToolConfig ,
1919 updateToolConfig ,
2020} from "@/services/agentConfigService" ;
21- import { Agent , AgentSetupOrchestratorProps , Tool } from "@/types/agentConfig" ;
21+ import {
22+ Agent ,
23+ AgentSetupOrchestratorProps ,
24+ Tool ,
25+ ToolParam ,
26+ } from "@/types/agentConfig" ;
2227import log from "@/lib/logger" ;
2328
2429import SubAgentPool from "./agent/SubAgentPool" ;
@@ -90,6 +95,9 @@ export default function AgentSetupOrchestrator({
9095 const [ enabledToolIds , setEnabledToolIds ] = useState < number [ ] > ( [ ] ) ;
9196 const [ isLoadingTools , setIsLoadingTools ] = useState ( false ) ;
9297 const [ isImporting , setIsImporting ] = useState ( false ) ;
98+ const [ toolConfigDrafts , setToolConfigDrafts ] = useState <
99+ Record < string , ToolParam [ ] >
100+ > ( { } ) ;
93101 // Use generation state passed from parent component, not local state
94102
95103 // Delete confirmation popup status
@@ -146,6 +154,19 @@ export default function AgentSetupOrchestrator({
146154 [ ]
147155 ) ;
148156
157+ const numericMainAgentId =
158+ mainAgentId !== null &&
159+ mainAgentId !== undefined &&
160+ String ( mainAgentId ) . trim ( ) !== ""
161+ ? Number ( mainAgentId )
162+ : null ;
163+ const hasPersistedMainAgentId =
164+ typeof numericMainAgentId === "number" &&
165+ ! Number . isNaN ( numericMainAgentId ) &&
166+ numericMainAgentId > 0 ;
167+ const isDraftCreationSession =
168+ isCreatingNewAgent && ! hasPersistedMainAgentId && ! isEditingAgent ;
169+
149170 // Add a flag to track if it has been initialized to avoid duplicate calls
150171 const hasInitialized = useRef ( false ) ;
151172 // Baseline snapshot for change detection
@@ -256,6 +277,12 @@ export default function AgentSetupOrchestrator({
256277 }
257278 } , [ isEditingAgent , editingAgent ] ) ;
258279
280+ useEffect ( ( ) => {
281+ if ( ! isDraftCreationSession ) {
282+ setToolConfigDrafts ( { } ) ;
283+ }
284+ } , [ isDraftCreationSession ] ) ;
285+
259286 // Initialize baseline when entering create mode so draft changes don't attach to previous agent
260287 useEffect ( ( ) => {
261288 if ( isCreatingNewAgent && ! isEditingAgent ) {
@@ -478,6 +505,36 @@ export default function AgentSetupOrchestrator({
478505 [ hasUnsavedChanges ]
479506 ) ;
480507
508+ const handleToolConfigDraftSave = useCallback (
509+ ( updatedTool : Tool ) => {
510+ if ( ! isDraftCreationSession ) {
511+ return ;
512+ }
513+ setToolConfigDrafts ( ( prev ) => ( {
514+ ...prev ,
515+ [ updatedTool . id ] :
516+ updatedTool . initParams ?. map ( ( param ) => ( { ...param } ) ) || [ ] ,
517+ } ) ) ;
518+ setSelectedTools ( ( prev : Tool [ ] ) => {
519+ if ( ! prev || prev . length === 0 ) {
520+ return prev ;
521+ }
522+ const index = prev . findIndex ( ( tool ) => tool . id === updatedTool . id ) ;
523+ if ( index === - 1 ) {
524+ return prev ;
525+ }
526+ const next = [ ...prev ] ;
527+ next [ index ] = {
528+ ...updatedTool ,
529+ initParams :
530+ updatedTool . initParams ?. map ( ( param ) => ( { ...param } ) ) || [ ] ,
531+ } ;
532+ return next ;
533+ } ) ;
534+ } ,
535+ [ isDraftCreationSession , setSelectedTools ]
536+ ) ;
537+
481538 // Function to directly update enabledAgentIds
482539 const handleUpdateEnabledAgentIds = ( newEnabledAgentIds : number [ ] ) => {
483540 setEnabledAgentIds ( newEnabledAgentIds ) ;
@@ -512,21 +569,46 @@ export default function AgentSetupOrchestrator({
512569 }
513570 } , [ isCreatingNewAgent , isEditingAgent , mainAgentId ] ) ;
514571
572+ const applyDraftParamsToTool = useCallback (
573+ ( tool : Tool ) : Tool => {
574+ if ( ! isDraftCreationSession ) {
575+ return tool ;
576+ }
577+ const draft = toolConfigDrafts [ tool . id ] ;
578+ if ( ! draft || draft . length === 0 ) {
579+ return tool ;
580+ }
581+ return {
582+ ...tool ,
583+ initParams : draft . map ( ( param ) => ( { ...param } ) ) ,
584+ } ;
585+ } ,
586+ [ isDraftCreationSession , toolConfigDrafts ]
587+ ) ;
588+
515589 // Listen for changes in the tool status, update the selected tool
516590 useEffect ( ( ) => {
517591 if ( ! tools || isLoadingTools ) return ;
518592 // Allow empty enabledToolIds array (it's valid when no tools are selected)
519593 if ( enabledToolIds === undefined || enabledToolIds === null ) return ;
520594
521595 // Filter out unavailable tools (is_available === false) to prevent deleted MCP tools from showing
522- const enabledTools = tools . filter (
523- ( tool ) =>
524- enabledToolIds . includes ( Number ( tool . id ) ) &&
525- tool . is_available !== false
526- ) ;
596+ const enabledTools = tools
597+ . filter (
598+ ( tool ) =>
599+ enabledToolIds . includes ( Number ( tool . id ) ) &&
600+ tool . is_available !== false
601+ )
602+ . map ( ( tool ) => applyDraftParamsToTool ( tool ) ) ;
527603
528604 setSelectedTools ( enabledTools ) ;
529- } , [ tools , enabledToolIds , isLoadingTools ] ) ;
605+ } , [
606+ tools ,
607+ enabledToolIds ,
608+ isLoadingTools ,
609+ applyDraftParamsToTool ,
610+ setSelectedTools ,
611+ ] ) ;
530612
531613 // Auto-unselect knowledge_base_search if embedding is not configured
532614 useEffect ( ( ) => {
@@ -913,6 +995,61 @@ export default function AgentSetupOrchestrator({
913995 } ;
914996
915997 // Handle the creation of a new Agent
998+ const persistDraftToolConfigs = useCallback (
999+ async ( agentId : number , toolIdsToEnable : number [ ] ) => {
1000+ if ( ! toolIdsToEnable || toolIdsToEnable . length === 0 ) {
1001+ return ;
1002+ }
1003+
1004+ const payloads = toolIdsToEnable
1005+ . map ( ( toolId ) => {
1006+ const toolIdStr = String ( toolId ) ;
1007+ const draftParams = toolConfigDrafts [ toolIdStr ] ;
1008+ const baseTool =
1009+ selectedTools . find ( ( tool ) => Number ( tool . id ) === toolId ) ||
1010+ tools . find ( ( tool ) => Number ( tool . id ) === toolId ) ;
1011+ const paramsSource =
1012+ ( draftParams && draftParams . length > 0
1013+ ? draftParams
1014+ : baseTool ?. initParams ) || [ ] ;
1015+ if ( ! paramsSource || paramsSource . length === 0 ) {
1016+ return null ;
1017+ }
1018+ const params = paramsSource . reduce ( ( acc , param ) => {
1019+ acc [ param . name ] = param . value ;
1020+ return acc ;
1021+ } , { } as Record < string , any > ) ;
1022+ return {
1023+ toolId,
1024+ params,
1025+ } ;
1026+ } )
1027+ . filter ( Boolean ) as Array < {
1028+ toolId : number ;
1029+ params : Record < string , any > ;
1030+ } > ;
1031+
1032+ if ( payloads . length === 0 ) {
1033+ return ;
1034+ }
1035+
1036+ let persistError = false ;
1037+ for ( const payload of payloads ) {
1038+ try {
1039+ await updateToolConfig ( payload . toolId , agentId , payload . params , true ) ;
1040+ } catch ( error ) {
1041+ persistError = true ;
1042+ log . error ( "Failed to persist tool configuration for new agent:" , error ) ;
1043+ }
1044+ }
1045+
1046+ if ( persistError ) {
1047+ message . error ( t ( "toolConfig.message.saveError" ) ) ;
1048+ }
1049+ } ,
1050+ [ toolConfigDrafts , selectedTools , tools , message , t ]
1051+ ) ;
1052+
9161053 const handleSaveNewAgent = async (
9171054 name : string ,
9181055 description : string ,
@@ -987,6 +1124,13 @@ export default function AgentSetupOrchestrator({
9871124 }
9881125
9891126 if ( result . success ) {
1127+ if ( ! isEditingAgent && result . data ?. agent_id ) {
1128+ await persistDraftToolConfigs (
1129+ Number ( result . data . agent_id ) ,
1130+ deduplicatedToolIds
1131+ ) ;
1132+ setToolConfigDrafts ( { } ) ;
1133+ }
9901134 // If created, set new mainAgentId for subsequent operations
9911135 if ( ! isEditingAgent && result . data ?. agent_id ) {
9921136 setMainAgentId ( String ( result . data . agent_id ) ) ;
@@ -1723,6 +1867,8 @@ export default function AgentSetupOrchestrator({
17231867 isGeneratingAgent = { isGeneratingAgent }
17241868 isEmbeddingConfigured = { isEmbeddingConfigured }
17251869 agentUnavailableReasons = { agentUnavailableReasons }
1870+ onToolConfigSave = { handleToolConfigDraftSave }
1871+ toolConfigDrafts = { toolConfigDrafts }
17261872 />
17271873 </ div >
17281874 </ div >
0 commit comments