@@ -9,38 +9,25 @@ import {
9
9
DialogTrigger ,
10
10
} from "@/components/ui/dialog"
11
11
import { Drawer , DrawerContent , DrawerTrigger } from "@/components/ui/drawer"
12
- import {
13
- Popover ,
14
- PopoverTrigger ,
15
- } from "@/components/ui/popover"
12
+ import { Popover , PopoverTrigger } from "@/components/ui/popover"
16
13
import { toast } from "@/components/ui/toast"
14
+ import { useAgent } from "@/lib/agent-store/provider"
17
15
import { fetchClient } from "@/lib/fetch"
18
16
import { API_ROUTE_CREATE_AGENT } from "@/lib/routes"
19
17
import { useUser } from "@/lib/user-store/provider"
20
18
import { useRouter } from "next/navigation"
21
19
import type React from "react"
22
20
import { useState } from "react"
23
21
import { useBreakpoint } from "../../../hooks/use-breakpoint"
24
- import { CreateAgentForm } from "./create-agent-form"
25
-
26
- type AgentFormData = {
27
- name : string
28
- description : string
29
- systemPrompt : string
30
- mcp : "none" | "git-mcp"
31
- repository ?: string
32
- tools : string [ ]
33
- }
22
+ import { AgentFormData , CreateAgentForm } from "./create-agent-form"
34
23
35
- type DialogCreateAgentTrigger = {
36
- trigger : React . ReactNode
37
- }
38
-
39
- // @todo : add drawer
40
24
export function DialogCreateAgentTrigger ( {
41
25
trigger,
42
- } : DialogCreateAgentTrigger ) {
26
+ } : {
27
+ trigger : React . ReactNode
28
+ } ) {
43
29
const { user } = useUser ( )
30
+ const { refetchUserAgents } = useAgent ( )
44
31
const isAuthenticated = ! ! user ?. id
45
32
const [ open , setOpen ] = useState ( false )
46
33
const [ formData , setFormData ] = useState < AgentFormData > ( {
@@ -58,142 +45,52 @@ export function DialogCreateAgentTrigger({
58
45
59
46
const generateSystemPrompt = ( owner : string , repo : string ) => {
60
47
return `You are a helpful GitHub assistant focused on the repository: ${ owner } /${ repo } .
61
-
48
+
62
49
Use the available tools below to answer any questions. Always prefer using tools over guessing.
63
-
50
+
64
51
Tools available for this repository:
65
- - \`fetch_${ repo } _documentation\`: Fetch the entire documentation file. Use this first when asked about general concepts in ${ owner } / ${ repo } .
66
- - \`search_${ repo } _documentation\`: Semantically search the documentation. Use this for specific questions.
67
- - \`search_${ repo } _code\`: Search code with exact matches using the GitHub API. Use when asked about file contents or code examples.
52
+ - \`fetch_${ repo } _documentation\`: Fetch the entire documentation file.
53
+ - \`search_${ repo } _documentation\`: Semantically search the documentation.
54
+ - \`search_${ repo } _code\`: Search code with exact matches using the GitHub API.
68
55
- \`fetch_generic_url_content\`: Fetch absolute URLs when referenced in the docs or needed for context.
69
-
70
- Never invent answers. Use tools and return what you find.`
71
- }
72
-
73
- const handleInputChange = (
74
- e : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement >
75
- ) => {
76
- const { name, value } = e . target
77
- setFormData ( { ...formData , [ name ] : value } )
78
-
79
- // Clear error for this field if it exists
80
- if ( error [ name ] ) {
81
- setError ( { ...error , [ name ] : "" } )
82
- }
83
- }
84
-
85
- const handleRepositoryChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
86
- const repoValue = e . target . value
87
- setRepository ( repoValue )
88
-
89
- // Clear repository error if it exists
90
- if ( error . repository ) {
91
- setError ( { ...error , repository : "" } )
92
- }
93
-
94
- // Update system prompt if git-mcp is selected and repository format is valid
95
- if ( formData . mcp === "git-mcp" && validateRepository ( repoValue ) ) {
96
- const [ owner , repo ] = repoValue . split ( "/" )
97
- setFormData ( ( prev ) => ( {
98
- ...prev ,
99
- systemPrompt : generateSystemPrompt ( owner , repo ) ,
100
- } ) )
101
- }
102
- }
103
-
104
- const handleSelectChange = ( value : string ) => {
105
- setFormData ( { ...formData , mcp : value as "none" | "git-mcp" } )
106
-
107
- // Clear repository error if switching away from git-mcp
108
- if ( value !== "git-mcp" && error . repository ) {
109
- setError ( { ...error , repository : "" } )
110
- }
111
-
112
- // If switching to git-mcp and repository is already valid, update system prompt
113
- if ( value === "git-mcp" && validateRepository ( repository ) ) {
114
- const [ owner , repo ] = repository . split ( "/" )
115
- setFormData ( ( prev ) => ( {
116
- ...prev ,
117
- systemPrompt : generateSystemPrompt ( owner , repo ) ,
118
- } ) )
119
- }
120
- }
121
56
122
- const handleToolsChange = ( selectedTools : string [ ] ) => {
123
- setFormData ( { ...formData , tools : selectedTools } )
124
- }
125
-
126
- const validateRepository = ( repo : string ) => {
127
- // Simple validation for owner/repo format
128
- const regex = / ^ [ a - z A - Z 0 - 9 _ . - ] + \/ [ a - z A - Z 0 - 9 _ . - ] + $ /
129
- return regex . test ( repo )
57
+ Never invent answers. Use tools and return what you find.`
130
58
}
131
59
132
- const validateForm = ( ) => {
60
+ const handleSubmit = async ( e : React . FormEvent ) => {
61
+ e . preventDefault ( )
133
62
const newErrors : { [ key : string ] : string } = { }
134
-
135
- if ( ! formData . name . trim ( ) ) {
136
- newErrors . name = "Agent name is required"
137
- }
138
-
139
- if ( ! formData . description . trim ( ) ) {
63
+ if ( ! formData . name . trim ( ) ) newErrors . name = "Agent name is required"
64
+ if ( ! formData . description . trim ( ) )
140
65
newErrors . description = "Description is required"
141
- }
142
-
143
- if ( ! formData . systemPrompt . trim ( ) ) {
66
+ if ( ! formData . systemPrompt . trim ( ) )
144
67
newErrors . systemPrompt = "System prompt is required"
145
- }
146
-
147
- if ( formData . mcp === "git-mcp" && ! validateRepository ( repository ) ) {
68
+ if (
69
+ formData . mcp === "git-mcp" &&
70
+ ! / ^ [ a - z A - Z 0 - 9 _ . - ] + \/ [ a - z A - Z 0 - 9 _ . - ] + $ / . test ( repository )
71
+ ) {
148
72
newErrors . repository =
149
73
'Please enter a valid repository in the format "owner/repo"'
150
74
}
151
-
152
- setError ( newErrors )
153
- return Object . keys ( newErrors ) . length === 0
154
- }
155
-
156
- const handleSubmit = async ( e : React . FormEvent ) => {
157
- e . preventDefault ( )
158
-
159
- if ( ! validateForm ( ) ) {
160
- return
161
- }
75
+ if ( Object . keys ( newErrors ) . length ) return setError ( newErrors )
162
76
163
77
setIsLoading ( true )
164
-
165
78
try {
166
- // If git-mcp is selected, validate the repository
167
79
if ( formData . mcp === "git-mcp" ) {
168
80
const response = await fetch (
169
81
`https://api.github.com/repos/${ repository } `
170
82
)
171
-
172
83
if ( ! response . ok ) {
173
- if ( response . status === 404 ) {
174
- setError ( {
175
- ...error ,
176
- repository :
177
- "Repository not found. Please check the repository name and try again." ,
178
- } )
179
- } else {
180
- setError ( {
181
- ...error ,
182
- repository : `GitHub API error: ${ response . statusText } ` ,
183
- } )
184
- }
84
+ setError ( { repository : "Repository not found." } )
185
85
setIsLoading ( false )
186
86
return
187
87
}
188
-
189
- // Add repository to form data
190
88
formData . repository = repository
191
89
}
192
90
193
- const owner = repository ? repository . split ( "/" ) [ 0 ] : null
194
- const repo = repository ? repository . split ( "/" ) [ 1 ] : null
91
+ const [ owner , repo ] = repository . split ( "/" )
195
92
196
- const apiResponse = await fetchClient ( API_ROUTE_CREATE_AGENT , {
93
+ const res = await fetchClient ( API_ROUTE_CREATE_AGENT , {
197
94
method : "POST" ,
198
95
headers : { "Content-Type" : "application/json" } ,
199
96
body : JSON . stringify ( {
@@ -202,10 +99,7 @@ Never invent answers. Use tools and return what you find.`
202
99
systemPrompt : formData . systemPrompt ,
203
100
avatar_url : repository ? `https://github.com/${ owner } .png` : null ,
204
101
mcp_config : repository
205
- ? {
206
- server : `https://gitmcp.io/${ owner } /${ repo } ` ,
207
- variables : [ ] ,
208
- }
102
+ ? { server : `https://gitmcp.io/${ owner } /${ repo } ` , variables : [ ] }
209
103
: null ,
210
104
example_inputs : repository
211
105
? [
@@ -222,24 +116,17 @@ Never invent answers. Use tools and return what you find.`
222
116
} ) ,
223
117
} )
224
118
225
- if ( ! apiResponse . ok ) {
226
- const errorData = await apiResponse . json ( )
227
- throw new Error ( errorData . error || "Failed to create agent" )
228
- }
229
-
230
- const { agent } = await apiResponse . json ( )
231
-
232
- // Close the dialog and redirect
119
+ if ( ! res . ok ) throw new Error ( "Failed to create agent" )
120
+ const { agent } = await res . json ( )
121
+ refetchUserAgents ( )
233
122
setOpen ( false )
234
123
router . push ( `/?agent=${ agent . slug } ` )
235
- } catch ( error : unknown ) {
236
- console . error ( "Agent creation error:" , error )
124
+ } catch ( err ) {
125
+ console . error ( err )
237
126
toast ( {
238
- title : "Error creating agent" ,
239
- description :
240
- ( error as Error ) . message || "Failed to create agent. Please try again." ,
127
+ title : "Error" ,
128
+ description : "Could not create agent. Try again." ,
241
129
} )
242
- setError ( { form : "Failed to create agent. Please try again." } )
243
130
} finally {
244
131
setIsLoading ( false )
245
132
}
@@ -249,12 +136,26 @@ Never invent answers. Use tools and return what you find.`
249
136
< CreateAgentForm
250
137
formData = { formData }
251
138
repository = { repository }
252
- setRepository = { handleRepositoryChange }
139
+ setRepository = { ( e ) => setRepository ( e . target . value ) }
253
140
error = { error }
254
141
isLoading = { isLoading }
255
- handleInputChange = { handleInputChange }
256
- handleSelectChange = { handleSelectChange }
257
- handleToolsChange = { handleToolsChange }
142
+ handleInputChange = { ( e ) => {
143
+ const { name, value } = e . target
144
+ setFormData ( ( f ) => ( { ...f , [ name ] : value } ) )
145
+ if ( error [ name ] ) setError ( ( err ) => ( { ...err , [ name ] : "" } ) )
146
+ } }
147
+ handleSelectChange = { ( value ) => {
148
+ setFormData ( ( f ) => ( { ...f , mcp : value as "none" | "git-mcp" } ) )
149
+ if ( value !== "git-mcp" ) setError ( ( e ) => ( { ...e , repository : "" } ) )
150
+ if ( value === "git-mcp" && / ^ [ ^ / ] + \/ [ ^ / ] + $ / . test ( repository ) ) {
151
+ const [ owner , repo ] = repository . split ( "/" )
152
+ setFormData ( ( f ) => ( {
153
+ ...f ,
154
+ systemPrompt : generateSystemPrompt ( owner , repo ) ,
155
+ } ) )
156
+ }
157
+ } }
158
+ handleToolsChange = { ( tools ) => setFormData ( ( f ) => ( { ...f , tools } ) ) }
258
159
handleSubmit = { handleSubmit }
259
160
onClose = { ( ) => setOpen ( false ) }
260
161
isDrawer = { isMobile }
@@ -285,7 +186,6 @@ Never invent answers. Use tools and return what you find.`
285
186
< DialogContent className = "max-h-[90vh] gap-0 overflow-y-auto p-0 sm:max-w-xl" >
286
187
< div
287
188
className = "h-full w-full"
288
- // Prevent the dialog from closing when clicking on the content, needed because of the agent-command component
289
189
onClick = { ( e ) => e . stopPropagation ( ) }
290
190
onMouseDown = { ( e ) => e . stopPropagation ( ) }
291
191
>
0 commit comments