11import React , { useState , useCallback , useEffect } from 'react' ;
22import { useTranslation } from 'react-i18next' ;
33import Button from '../Button' ;
4+ import ButtonIcon from '../ButtonIcon' ;
45import InputText from '../InputText' ;
56import Textarea from '../Textarea' ;
67import Select from '../Select' ;
78import MCPServerManager from './MCPServerManager' ;
9+ import ModalDialog from '../ModalDialog' ;
810import { MODELS } from '../../hooks/useModel' ;
911import { AgentConfiguration } from 'generative-ai-use-cases' ;
12+ import usePromptGeneration from '../../hooks/usePromptGeneration' ;
13+ import useMCPServers from '../../hooks/useMCPServers' ;
14+ import { PiSparkle , PiStop } from 'react-icons/pi' ;
1015
1116export interface AgentFormData {
1217 name : string ;
1318 description : string ;
1419 systemPrompt : string ;
1520 modelId : string ;
16- mcpServers : string [ ] ; // Changed to string array
21+ mcpServers : string [ ] ;
1722 codeExecutionEnabled : boolean ;
1823 isPublic : boolean ;
1924 tags : string [ ] ;
@@ -55,6 +60,38 @@ const AgentForm: React.FC<AgentFormProps> = ({
5560 } ) ;
5661
5762 const [ tagsInput , setTagsInput ] = useState ( '' ) ;
63+ const [ showOverwriteDialog , setShowOverwriteDialog ] = useState ( false ) ;
64+
65+ // Load available MCP servers using the shared hook
66+ const availableMCPServers = useMCPServers ( ) ;
67+
68+ // Use the prompt generation hook
69+ const {
70+ generatedPrompt,
71+ suggestedMCPServers,
72+ isGenerating,
73+ generate : generatePrompt ,
74+ cancel : cancelGeneration ,
75+ } = usePromptGeneration ( {
76+ modelId : formData . modelId ,
77+ agentName : formData . name ,
78+ agentDescription : formData . description ,
79+ availableMCPServers,
80+ } ) ;
81+
82+ // Update systemPrompt when generation produces new content
83+ useEffect ( ( ) => {
84+ if ( generatedPrompt ) {
85+ setFormData ( ( prev ) => ( { ...prev , systemPrompt : generatedPrompt } ) ) ;
86+ }
87+ } , [ generatedPrompt ] ) ;
88+
89+ // Update MCP servers when AI suggests them
90+ useEffect ( ( ) => {
91+ if ( suggestedMCPServers . length > 0 ) {
92+ setFormData ( ( prev ) => ( { ...prev , mcpServers : suggestedMCPServers } ) ) ;
93+ }
94+ } , [ suggestedMCPServers ] ) ;
5895
5996 // Update formData.modelId when availableModels becomes available
6097 useEffect ( ( ) => {
@@ -86,7 +123,6 @@ const AgentForm: React.FC<AgentFormProps> = ({
86123 // Notify parent component when form data changes
87124 useEffect ( ( ) => {
88125 if ( onFormDataChange ) {
89- // Parse tags from input for real-time updates
90126 const tags = tagsInput
91127 . split ( ',' )
92128 . map ( ( tag ) => tag . trim ( ) )
@@ -103,7 +139,6 @@ const AgentForm: React.FC<AgentFormProps> = ({
103139
104140 const handleSave = useCallback ( async ( ) => {
105141 try {
106- // Parse tags from input
107142 const tags = tagsInput
108143 . split ( ',' )
109144 . map ( ( tag ) => tag . trim ( ) )
@@ -115,11 +150,34 @@ const AgentForm: React.FC<AgentFormProps> = ({
115150 } ;
116151
117152 await onSave ( agentData ) ;
118- } catch ( error ) {
119- console . error ( 'Error saving agent:' , error ) ;
153+ } catch ( err ) {
154+ console . error ( 'Error saving agent:' , err ) ;
120155 }
121156 } , [ formData , tagsInput , onSave ] ) ;
122157
158+ const handleGenerateClick = useCallback ( ( ) => {
159+ if ( formData . systemPrompt . trim ( ) ) {
160+ setShowOverwriteDialog ( true ) ;
161+ } else {
162+ setFormData ( ( prev ) => ( { ...prev , systemPrompt : '' } ) ) ;
163+ generatePrompt ( ) ;
164+ }
165+ } , [ formData . systemPrompt , generatePrompt ] ) ;
166+
167+ const handleConfirmOverwrite = useCallback ( ( ) => {
168+ setShowOverwriteDialog ( false ) ;
169+ setFormData ( ( prev ) => ( { ...prev , systemPrompt : '' } ) ) ;
170+ generatePrompt ( ) ;
171+ } , [ generatePrompt ] ) ;
172+
173+ const handleCancelGeneration = useCallback ( ( ) => {
174+ cancelGeneration ( ) ;
175+ } , [ cancelGeneration ] ) ;
176+
177+ // Check if generate button should be disabled
178+ const isGenerateDisabled =
179+ ! formData . name . trim ( ) || ! formData . description . trim ( ) || loading ;
180+
123181 const isFormValid =
124182 formData . name && formData . systemPrompt && formData . modelId ;
125183
@@ -202,10 +260,33 @@ const AgentForm: React.FC<AgentFormProps> = ({
202260
203261 { /* System Prompt */ }
204262 < div className = "rounded-lg border bg-white p-6" >
205- { /* eslint-disable-next-line @shopify/jsx-no-hardcoded-content */ }
206- < h2 className = "mb-4 text-lg font-semibold" >
207- { t ( 'agent_builder.system_prompt' ) } { '*' }
208- </ h2 >
263+ < div className = "mb-4 flex items-center justify-between" >
264+ { /* eslint-disable-next-line @shopify/jsx-no-hardcoded-content */ }
265+ < h2 className = "text-lg font-semibold" >
266+ { t ( 'agent_builder.system_prompt' ) } { '*' }
267+ </ h2 >
268+ < div className = "flex items-center gap-2" >
269+ { isGenerating ? (
270+ < ButtonIcon onClick = { handleCancelGeneration } >
271+ < PiStop className = "text-red-500" />
272+ </ ButtonIcon >
273+ ) : (
274+ < Button
275+ onClick = { handleGenerateClick }
276+ outlined
277+ disabled = { isGenerateDisabled || isGenerating }
278+ className = "flex items-center gap-1 text-sm" >
279+ < PiSparkle />
280+ < span className = "hidden sm:inline" >
281+ { t ( 'agent_builder.generate_with_ai' ) }
282+ </ span >
283+ < span className = "sm:hidden" >
284+ { t ( 'agent_builder.generate_short' ) }
285+ </ span >
286+ </ Button >
287+ ) }
288+ </ div >
289+ </ div >
209290
210291 < Textarea
211292 value = { formData . systemPrompt }
@@ -214,9 +295,35 @@ const AgentForm: React.FC<AgentFormProps> = ({
214295 }
215296 placeholder = { t ( 'agent_builder.enter_system_prompt' ) }
216297 rows = { 12 }
298+ disabled = { isGenerating || loading }
217299 />
300+ { isGenerating && (
301+ < p className = "mt-2 text-sm text-gray-500" >
302+ { t ( 'agent_builder.generating_prompt' ) }
303+ </ p >
304+ ) }
218305 </ div >
219306
307+ { /* Overwrite Confirmation Dialog */ }
308+ < ModalDialog
309+ isOpen = { showOverwriteDialog }
310+ title = { t ( 'agent_builder.overwrite_prompt_title' ) }
311+ onClose = { ( ) => setShowOverwriteDialog ( false ) } >
312+ < div className = "space-y-4" >
313+ < p className = "text-gray-700" >
314+ { t ( 'agent_builder.overwrite_prompt_message' ) }
315+ </ p >
316+ < div className = "flex justify-end gap-3" >
317+ < Button outlined onClick = { ( ) => setShowOverwriteDialog ( false ) } >
318+ { t ( 'common.cancel' ) }
319+ </ Button >
320+ < Button onClick = { handleConfirmOverwrite } >
321+ { t ( 'agent_builder.overwrite_confirm' ) }
322+ </ Button >
323+ </ div >
324+ </ div >
325+ </ ModalDialog >
326+
220327 { /* MCP Server Configuration */ }
221328 < div className = "rounded-lg border bg-white p-6" >
222329 < MCPServerManager
@@ -288,10 +395,12 @@ const AgentForm: React.FC<AgentFormProps> = ({
288395
289396 { /* Form Actions */ }
290397 < div className = "flex justify-end gap-3" >
291- < Button outlined onClick = { onCancel } >
398+ < Button outlined onClick = { onCancel } disabled = { isGenerating } >
292399 { t ( 'common.cancel' ) }
293400 </ Button >
294- < Button onClick = { handleSave } disabled = { loading || ! isFormValid } >
401+ < Button
402+ onClick = { handleSave }
403+ disabled = { loading || ! isFormValid || isGenerating } >
295404 { isEditMode ? t ( 'common.update' ) : t ( 'common.create' ) }
296405 </ Button >
297406 </ div >
0 commit comments