@agentforge-ai/cli 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/.env.example +46 -6
- package/dist/default/README.md +89 -9
- package/dist/default/convex/schema.ts +248 -4
- package/dist/default/dashboard/app/components/DashboardLayout.tsx +245 -0
- package/dist/default/dashboard/app/components/ui/badge.tsx +26 -0
- package/dist/default/dashboard/app/components/ui/button.tsx +41 -0
- package/dist/default/dashboard/app/components/ui/card.tsx +44 -0
- package/dist/default/dashboard/app/components/ui/dialog.tsx +66 -0
- package/dist/default/dashboard/app/components/ui/input.tsx +21 -0
- package/dist/default/dashboard/app/components/ui/label.tsx +18 -0
- package/dist/default/dashboard/app/components/ui/select.tsx +75 -0
- package/dist/default/dashboard/app/components/ui/sheet.tsx +73 -0
- package/dist/default/dashboard/app/components/ui/switch.tsx +34 -0
- package/dist/default/dashboard/app/components/ui/table.tsx +60 -0
- package/dist/default/dashboard/app/components/ui/tabs.tsx +50 -0
- package/dist/default/dashboard/app/components/ui/tooltip.tsx +23 -0
- package/dist/default/dashboard/app/lib/utils.ts +6 -0
- package/dist/default/dashboard/app/main.tsx +35 -0
- package/dist/default/dashboard/app/routeTree.gen.ts +352 -0
- package/dist/default/dashboard/app/routes/__root.tsx +10 -0
- package/dist/default/dashboard/app/routes/agents.tsx +255 -0
- package/dist/default/dashboard/app/routes/chat.tsx +427 -0
- package/dist/default/dashboard/app/routes/connections.tsx +413 -0
- package/dist/default/dashboard/app/routes/cron.tsx +322 -0
- package/dist/default/dashboard/app/routes/files.tsx +203 -0
- package/dist/default/dashboard/app/routes/index.tsx +141 -0
- package/dist/default/dashboard/app/routes/projects.tsx +254 -0
- package/dist/default/dashboard/app/routes/sessions.tsx +272 -0
- package/dist/default/dashboard/app/routes/settings.tsx +583 -0
- package/dist/default/dashboard/app/routes/skills.tsx +252 -0
- package/dist/default/dashboard/app/routes/usage.tsx +181 -0
- package/dist/default/dashboard/app/styles/globals.css +93 -0
- package/dist/default/dashboard/index.html +13 -0
- package/dist/default/dashboard/package.json +36 -0
- package/dist/default/dashboard/postcss.config.js +6 -0
- package/dist/default/dashboard/tailwind.config.js +50 -0
- package/dist/default/dashboard/tsconfig.json +24 -0
- package/dist/default/dashboard/vite.config.ts +16 -0
- package/dist/default/package.json +8 -3
- package/dist/default/skills/skill-creator/SKILL.md +270 -0
- package/dist/default/skills/skill-creator/config.json +11 -0
- package/dist/default/skills/skill-creator/index.ts +392 -0
- package/dist/default/src/agent.ts +85 -5
- package/dist/index.js +1574 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/templates/default/.env.example +46 -6
- package/templates/default/README.md +89 -9
- package/templates/default/convex/schema.ts +248 -4
- package/templates/default/dashboard/app/components/DashboardLayout.tsx +245 -0
- package/templates/default/dashboard/app/components/ui/badge.tsx +26 -0
- package/templates/default/dashboard/app/components/ui/button.tsx +41 -0
- package/templates/default/dashboard/app/components/ui/card.tsx +44 -0
- package/templates/default/dashboard/app/components/ui/dialog.tsx +66 -0
- package/templates/default/dashboard/app/components/ui/input.tsx +21 -0
- package/templates/default/dashboard/app/components/ui/label.tsx +18 -0
- package/templates/default/dashboard/app/components/ui/select.tsx +75 -0
- package/templates/default/dashboard/app/components/ui/sheet.tsx +73 -0
- package/templates/default/dashboard/app/components/ui/switch.tsx +34 -0
- package/templates/default/dashboard/app/components/ui/table.tsx +60 -0
- package/templates/default/dashboard/app/components/ui/tabs.tsx +50 -0
- package/templates/default/dashboard/app/components/ui/tooltip.tsx +23 -0
- package/templates/default/dashboard/app/lib/utils.ts +6 -0
- package/templates/default/dashboard/app/main.tsx +35 -0
- package/templates/default/dashboard/app/routeTree.gen.ts +352 -0
- package/templates/default/dashboard/app/routes/__root.tsx +10 -0
- package/templates/default/dashboard/app/routes/agents.tsx +255 -0
- package/templates/default/dashboard/app/routes/chat.tsx +427 -0
- package/templates/default/dashboard/app/routes/connections.tsx +413 -0
- package/templates/default/dashboard/app/routes/cron.tsx +322 -0
- package/templates/default/dashboard/app/routes/files.tsx +203 -0
- package/templates/default/dashboard/app/routes/index.tsx +141 -0
- package/templates/default/dashboard/app/routes/projects.tsx +254 -0
- package/templates/default/dashboard/app/routes/sessions.tsx +272 -0
- package/templates/default/dashboard/app/routes/settings.tsx +583 -0
- package/templates/default/dashboard/app/routes/skills.tsx +252 -0
- package/templates/default/dashboard/app/routes/usage.tsx +181 -0
- package/templates/default/dashboard/app/styles/globals.css +93 -0
- package/templates/default/dashboard/index.html +13 -0
- package/templates/default/dashboard/package.json +36 -0
- package/templates/default/dashboard/postcss.config.js +6 -0
- package/templates/default/dashboard/tailwind.config.js +50 -0
- package/templates/default/dashboard/tsconfig.json +24 -0
- package/templates/default/dashboard/vite.config.ts +16 -0
- package/templates/default/package.json +8 -3
- package/templates/default/skills/skill-creator/SKILL.md +270 -0
- package/templates/default/skills/skill-creator/config.json +11 -0
- package/templates/default/skills/skill-creator/index.ts +392 -0
- package/templates/default/src/agent.ts +85 -5
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
6
|
+
|
|
7
|
+
// This file was automatically generated by TanStack Router.
|
|
8
|
+
// You should NOT make any changes in this file as it will be overwritten.
|
|
9
|
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
|
+
|
|
11
|
+
// Import Routes
|
|
12
|
+
|
|
13
|
+
import { Route as rootRoute } from './routes/__root'
|
|
14
|
+
import { Route as UsageImport } from './routes/usage'
|
|
15
|
+
import { Route as SkillsImport } from './routes/skills'
|
|
16
|
+
import { Route as SettingsImport } from './routes/settings'
|
|
17
|
+
import { Route as SessionsImport } from './routes/sessions'
|
|
18
|
+
import { Route as ProjectsImport } from './routes/projects'
|
|
19
|
+
import { Route as FilesImport } from './routes/files'
|
|
20
|
+
import { Route as CronImport } from './routes/cron'
|
|
21
|
+
import { Route as ConnectionsImport } from './routes/connections'
|
|
22
|
+
import { Route as ChatImport } from './routes/chat'
|
|
23
|
+
import { Route as AgentsImport } from './routes/agents'
|
|
24
|
+
import { Route as IndexImport } from './routes/index'
|
|
25
|
+
|
|
26
|
+
// Create/Update Routes
|
|
27
|
+
|
|
28
|
+
const UsageRoute = UsageImport.update({
|
|
29
|
+
id: '/usage',
|
|
30
|
+
path: '/usage',
|
|
31
|
+
getParentRoute: () => rootRoute,
|
|
32
|
+
} as any)
|
|
33
|
+
|
|
34
|
+
const SkillsRoute = SkillsImport.update({
|
|
35
|
+
id: '/skills',
|
|
36
|
+
path: '/skills',
|
|
37
|
+
getParentRoute: () => rootRoute,
|
|
38
|
+
} as any)
|
|
39
|
+
|
|
40
|
+
const SettingsRoute = SettingsImport.update({
|
|
41
|
+
id: '/settings',
|
|
42
|
+
path: '/settings',
|
|
43
|
+
getParentRoute: () => rootRoute,
|
|
44
|
+
} as any)
|
|
45
|
+
|
|
46
|
+
const SessionsRoute = SessionsImport.update({
|
|
47
|
+
id: '/sessions',
|
|
48
|
+
path: '/sessions',
|
|
49
|
+
getParentRoute: () => rootRoute,
|
|
50
|
+
} as any)
|
|
51
|
+
|
|
52
|
+
const ProjectsRoute = ProjectsImport.update({
|
|
53
|
+
id: '/projects',
|
|
54
|
+
path: '/projects',
|
|
55
|
+
getParentRoute: () => rootRoute,
|
|
56
|
+
} as any)
|
|
57
|
+
|
|
58
|
+
const FilesRoute = FilesImport.update({
|
|
59
|
+
id: '/files',
|
|
60
|
+
path: '/files',
|
|
61
|
+
getParentRoute: () => rootRoute,
|
|
62
|
+
} as any)
|
|
63
|
+
|
|
64
|
+
const CronRoute = CronImport.update({
|
|
65
|
+
id: '/cron',
|
|
66
|
+
path: '/cron',
|
|
67
|
+
getParentRoute: () => rootRoute,
|
|
68
|
+
} as any)
|
|
69
|
+
|
|
70
|
+
const ConnectionsRoute = ConnectionsImport.update({
|
|
71
|
+
id: '/connections',
|
|
72
|
+
path: '/connections',
|
|
73
|
+
getParentRoute: () => rootRoute,
|
|
74
|
+
} as any)
|
|
75
|
+
|
|
76
|
+
const ChatRoute = ChatImport.update({
|
|
77
|
+
id: '/chat',
|
|
78
|
+
path: '/chat',
|
|
79
|
+
getParentRoute: () => rootRoute,
|
|
80
|
+
} as any)
|
|
81
|
+
|
|
82
|
+
const AgentsRoute = AgentsImport.update({
|
|
83
|
+
id: '/agents',
|
|
84
|
+
path: '/agents',
|
|
85
|
+
getParentRoute: () => rootRoute,
|
|
86
|
+
} as any)
|
|
87
|
+
|
|
88
|
+
const IndexRoute = IndexImport.update({
|
|
89
|
+
id: '/',
|
|
90
|
+
path: '/',
|
|
91
|
+
getParentRoute: () => rootRoute,
|
|
92
|
+
} as any)
|
|
93
|
+
|
|
94
|
+
// Populate the FileRoutesByPath interface
|
|
95
|
+
|
|
96
|
+
declare module '@tanstack/react-router' {
|
|
97
|
+
interface FileRoutesByPath {
|
|
98
|
+
'/': {
|
|
99
|
+
id: '/'
|
|
100
|
+
path: '/'
|
|
101
|
+
fullPath: '/'
|
|
102
|
+
preLoaderRoute: typeof IndexImport
|
|
103
|
+
parentRoute: typeof rootRoute
|
|
104
|
+
}
|
|
105
|
+
'/agents': {
|
|
106
|
+
id: '/agents'
|
|
107
|
+
path: '/agents'
|
|
108
|
+
fullPath: '/agents'
|
|
109
|
+
preLoaderRoute: typeof AgentsImport
|
|
110
|
+
parentRoute: typeof rootRoute
|
|
111
|
+
}
|
|
112
|
+
'/chat': {
|
|
113
|
+
id: '/chat'
|
|
114
|
+
path: '/chat'
|
|
115
|
+
fullPath: '/chat'
|
|
116
|
+
preLoaderRoute: typeof ChatImport
|
|
117
|
+
parentRoute: typeof rootRoute
|
|
118
|
+
}
|
|
119
|
+
'/connections': {
|
|
120
|
+
id: '/connections'
|
|
121
|
+
path: '/connections'
|
|
122
|
+
fullPath: '/connections'
|
|
123
|
+
preLoaderRoute: typeof ConnectionsImport
|
|
124
|
+
parentRoute: typeof rootRoute
|
|
125
|
+
}
|
|
126
|
+
'/cron': {
|
|
127
|
+
id: '/cron'
|
|
128
|
+
path: '/cron'
|
|
129
|
+
fullPath: '/cron'
|
|
130
|
+
preLoaderRoute: typeof CronImport
|
|
131
|
+
parentRoute: typeof rootRoute
|
|
132
|
+
}
|
|
133
|
+
'/files': {
|
|
134
|
+
id: '/files'
|
|
135
|
+
path: '/files'
|
|
136
|
+
fullPath: '/files'
|
|
137
|
+
preLoaderRoute: typeof FilesImport
|
|
138
|
+
parentRoute: typeof rootRoute
|
|
139
|
+
}
|
|
140
|
+
'/projects': {
|
|
141
|
+
id: '/projects'
|
|
142
|
+
path: '/projects'
|
|
143
|
+
fullPath: '/projects'
|
|
144
|
+
preLoaderRoute: typeof ProjectsImport
|
|
145
|
+
parentRoute: typeof rootRoute
|
|
146
|
+
}
|
|
147
|
+
'/sessions': {
|
|
148
|
+
id: '/sessions'
|
|
149
|
+
path: '/sessions'
|
|
150
|
+
fullPath: '/sessions'
|
|
151
|
+
preLoaderRoute: typeof SessionsImport
|
|
152
|
+
parentRoute: typeof rootRoute
|
|
153
|
+
}
|
|
154
|
+
'/settings': {
|
|
155
|
+
id: '/settings'
|
|
156
|
+
path: '/settings'
|
|
157
|
+
fullPath: '/settings'
|
|
158
|
+
preLoaderRoute: typeof SettingsImport
|
|
159
|
+
parentRoute: typeof rootRoute
|
|
160
|
+
}
|
|
161
|
+
'/skills': {
|
|
162
|
+
id: '/skills'
|
|
163
|
+
path: '/skills'
|
|
164
|
+
fullPath: '/skills'
|
|
165
|
+
preLoaderRoute: typeof SkillsImport
|
|
166
|
+
parentRoute: typeof rootRoute
|
|
167
|
+
}
|
|
168
|
+
'/usage': {
|
|
169
|
+
id: '/usage'
|
|
170
|
+
path: '/usage'
|
|
171
|
+
fullPath: '/usage'
|
|
172
|
+
preLoaderRoute: typeof UsageImport
|
|
173
|
+
parentRoute: typeof rootRoute
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Create and export the route tree
|
|
179
|
+
|
|
180
|
+
export interface FileRoutesByFullPath {
|
|
181
|
+
'/': typeof IndexRoute
|
|
182
|
+
'/agents': typeof AgentsRoute
|
|
183
|
+
'/chat': typeof ChatRoute
|
|
184
|
+
'/connections': typeof ConnectionsRoute
|
|
185
|
+
'/cron': typeof CronRoute
|
|
186
|
+
'/files': typeof FilesRoute
|
|
187
|
+
'/projects': typeof ProjectsRoute
|
|
188
|
+
'/sessions': typeof SessionsRoute
|
|
189
|
+
'/settings': typeof SettingsRoute
|
|
190
|
+
'/skills': typeof SkillsRoute
|
|
191
|
+
'/usage': typeof UsageRoute
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface FileRoutesByTo {
|
|
195
|
+
'/': typeof IndexRoute
|
|
196
|
+
'/agents': typeof AgentsRoute
|
|
197
|
+
'/chat': typeof ChatRoute
|
|
198
|
+
'/connections': typeof ConnectionsRoute
|
|
199
|
+
'/cron': typeof CronRoute
|
|
200
|
+
'/files': typeof FilesRoute
|
|
201
|
+
'/projects': typeof ProjectsRoute
|
|
202
|
+
'/sessions': typeof SessionsRoute
|
|
203
|
+
'/settings': typeof SettingsRoute
|
|
204
|
+
'/skills': typeof SkillsRoute
|
|
205
|
+
'/usage': typeof UsageRoute
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface FileRoutesById {
|
|
209
|
+
__root__: typeof rootRoute
|
|
210
|
+
'/': typeof IndexRoute
|
|
211
|
+
'/agents': typeof AgentsRoute
|
|
212
|
+
'/chat': typeof ChatRoute
|
|
213
|
+
'/connections': typeof ConnectionsRoute
|
|
214
|
+
'/cron': typeof CronRoute
|
|
215
|
+
'/files': typeof FilesRoute
|
|
216
|
+
'/projects': typeof ProjectsRoute
|
|
217
|
+
'/sessions': typeof SessionsRoute
|
|
218
|
+
'/settings': typeof SettingsRoute
|
|
219
|
+
'/skills': typeof SkillsRoute
|
|
220
|
+
'/usage': typeof UsageRoute
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface FileRouteTypes {
|
|
224
|
+
fileRoutesByFullPath: FileRoutesByFullPath
|
|
225
|
+
fullPaths:
|
|
226
|
+
| '/'
|
|
227
|
+
| '/agents'
|
|
228
|
+
| '/chat'
|
|
229
|
+
| '/connections'
|
|
230
|
+
| '/cron'
|
|
231
|
+
| '/files'
|
|
232
|
+
| '/projects'
|
|
233
|
+
| '/sessions'
|
|
234
|
+
| '/settings'
|
|
235
|
+
| '/skills'
|
|
236
|
+
| '/usage'
|
|
237
|
+
fileRoutesByTo: FileRoutesByTo
|
|
238
|
+
to:
|
|
239
|
+
| '/'
|
|
240
|
+
| '/agents'
|
|
241
|
+
| '/chat'
|
|
242
|
+
| '/connections'
|
|
243
|
+
| '/cron'
|
|
244
|
+
| '/files'
|
|
245
|
+
| '/projects'
|
|
246
|
+
| '/sessions'
|
|
247
|
+
| '/settings'
|
|
248
|
+
| '/skills'
|
|
249
|
+
| '/usage'
|
|
250
|
+
id:
|
|
251
|
+
| '__root__'
|
|
252
|
+
| '/'
|
|
253
|
+
| '/agents'
|
|
254
|
+
| '/chat'
|
|
255
|
+
| '/connections'
|
|
256
|
+
| '/cron'
|
|
257
|
+
| '/files'
|
|
258
|
+
| '/projects'
|
|
259
|
+
| '/sessions'
|
|
260
|
+
| '/settings'
|
|
261
|
+
| '/skills'
|
|
262
|
+
| '/usage'
|
|
263
|
+
fileRoutesById: FileRoutesById
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface RootRouteChildren {
|
|
267
|
+
IndexRoute: typeof IndexRoute
|
|
268
|
+
AgentsRoute: typeof AgentsRoute
|
|
269
|
+
ChatRoute: typeof ChatRoute
|
|
270
|
+
ConnectionsRoute: typeof ConnectionsRoute
|
|
271
|
+
CronRoute: typeof CronRoute
|
|
272
|
+
FilesRoute: typeof FilesRoute
|
|
273
|
+
ProjectsRoute: typeof ProjectsRoute
|
|
274
|
+
SessionsRoute: typeof SessionsRoute
|
|
275
|
+
SettingsRoute: typeof SettingsRoute
|
|
276
|
+
SkillsRoute: typeof SkillsRoute
|
|
277
|
+
UsageRoute: typeof UsageRoute
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const rootRouteChildren: RootRouteChildren = {
|
|
281
|
+
IndexRoute: IndexRoute,
|
|
282
|
+
AgentsRoute: AgentsRoute,
|
|
283
|
+
ChatRoute: ChatRoute,
|
|
284
|
+
ConnectionsRoute: ConnectionsRoute,
|
|
285
|
+
CronRoute: CronRoute,
|
|
286
|
+
FilesRoute: FilesRoute,
|
|
287
|
+
ProjectsRoute: ProjectsRoute,
|
|
288
|
+
SessionsRoute: SessionsRoute,
|
|
289
|
+
SettingsRoute: SettingsRoute,
|
|
290
|
+
SkillsRoute: SkillsRoute,
|
|
291
|
+
UsageRoute: UsageRoute,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export const routeTree = rootRoute
|
|
295
|
+
._addFileChildren(rootRouteChildren)
|
|
296
|
+
._addFileTypes<FileRouteTypes>()
|
|
297
|
+
|
|
298
|
+
/* ROUTE_MANIFEST_START
|
|
299
|
+
{
|
|
300
|
+
"routes": {
|
|
301
|
+
"__root__": {
|
|
302
|
+
"filePath": "__root.tsx",
|
|
303
|
+
"children": [
|
|
304
|
+
"/",
|
|
305
|
+
"/agents",
|
|
306
|
+
"/chat",
|
|
307
|
+
"/connections",
|
|
308
|
+
"/cron",
|
|
309
|
+
"/files",
|
|
310
|
+
"/projects",
|
|
311
|
+
"/sessions",
|
|
312
|
+
"/settings",
|
|
313
|
+
"/skills",
|
|
314
|
+
"/usage"
|
|
315
|
+
]
|
|
316
|
+
},
|
|
317
|
+
"/": {
|
|
318
|
+
"filePath": "index.tsx"
|
|
319
|
+
},
|
|
320
|
+
"/agents": {
|
|
321
|
+
"filePath": "agents.tsx"
|
|
322
|
+
},
|
|
323
|
+
"/chat": {
|
|
324
|
+
"filePath": "chat.tsx"
|
|
325
|
+
},
|
|
326
|
+
"/connections": {
|
|
327
|
+
"filePath": "connections.tsx"
|
|
328
|
+
},
|
|
329
|
+
"/cron": {
|
|
330
|
+
"filePath": "cron.tsx"
|
|
331
|
+
},
|
|
332
|
+
"/files": {
|
|
333
|
+
"filePath": "files.tsx"
|
|
334
|
+
},
|
|
335
|
+
"/projects": {
|
|
336
|
+
"filePath": "projects.tsx"
|
|
337
|
+
},
|
|
338
|
+
"/sessions": {
|
|
339
|
+
"filePath": "sessions.tsx"
|
|
340
|
+
},
|
|
341
|
+
"/settings": {
|
|
342
|
+
"filePath": "settings.tsx"
|
|
343
|
+
},
|
|
344
|
+
"/skills": {
|
|
345
|
+
"filePath": "skills.tsx"
|
|
346
|
+
},
|
|
347
|
+
"/usage": {
|
|
348
|
+
"filePath": "usage.tsx"
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
ROUTE_MANIFEST_END */
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3
|
+
import { DashboardLayout } from '../components/DashboardLayout';
|
|
4
|
+
import { useState, useMemo } from 'react';
|
|
5
|
+
import { Bot, Plus, Edit, Trash2, Search, Settings, Zap, X, ChevronDown, Star } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
// MOCK DATA (to be replaced by Convex)
|
|
8
|
+
const initialAgents = [
|
|
9
|
+
{
|
|
10
|
+
id: 'agent-1',
|
|
11
|
+
name: 'Research Assistant',
|
|
12
|
+
description: 'An agent specialized in gathering and summarizing information from the web.',
|
|
13
|
+
instructions: 'You are a research assistant. Your goal is to find the most relevant and up-to-date information on any given topic. Use search tools and summarize your findings clearly.',
|
|
14
|
+
model: 'gpt-4.1-mini',
|
|
15
|
+
provider: 'OpenAI',
|
|
16
|
+
temperature: 0.7,
|
|
17
|
+
maxTokens: 4096,
|
|
18
|
+
status: 'active',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'agent-2',
|
|
22
|
+
name: 'Code Generator',
|
|
23
|
+
description: 'Generates code in various programming languages based on user requirements.',
|
|
24
|
+
instructions: 'You are a senior software engineer. Write clean, efficient, and well-documented code. Always ask for clarification if the requirements are ambiguous.',
|
|
25
|
+
model: 'gemini-2.5-flash',
|
|
26
|
+
provider: 'Google',
|
|
27
|
+
temperature: 0.5,
|
|
28
|
+
maxTokens: 8192,
|
|
29
|
+
status: 'inactive',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'agent-3',
|
|
33
|
+
name: 'Creative Writer',
|
|
34
|
+
description: 'A creative partner for brainstorming and writing stories, scripts, and more.',
|
|
35
|
+
instructions: 'You are a creative writer. Help users brainstorm ideas, develop characters, and write compelling narratives. Be imaginative and inspiring.',
|
|
36
|
+
model: 'grok-4',
|
|
37
|
+
provider: 'xAI',
|
|
38
|
+
temperature: 0.9,
|
|
39
|
+
maxTokens: 2048,
|
|
40
|
+
status: 'active',
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// CONVEX PLACEHOLDERS
|
|
45
|
+
// import { useQuery, useMutation } from 'convex/react';
|
|
46
|
+
// import { api } from '../../convex/_generated/api';
|
|
47
|
+
|
|
48
|
+
export const Route = createFileRoute('/agents')({ component: AgentsPage });
|
|
49
|
+
|
|
50
|
+
function AgentsPage() {
|
|
51
|
+
// const agents = useQuery(api.agents.list) || [];
|
|
52
|
+
// const createAgent = useMutation(api.agents.create);
|
|
53
|
+
// const updateAgent = useMutation(api.agents.update);
|
|
54
|
+
// const deleteAgent = useMutation(api.agents.delete);
|
|
55
|
+
|
|
56
|
+
const [agents, setAgents] = useState(initialAgents);
|
|
57
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
58
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
59
|
+
const [editingAgent, setEditingAgent] = useState(null);
|
|
60
|
+
|
|
61
|
+
const filteredAgents = useMemo(() =>
|
|
62
|
+
agents.filter(agent =>
|
|
63
|
+
agent.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
64
|
+
agent.description.toLowerCase().includes(searchQuery.toLowerCase())
|
|
65
|
+
),
|
|
66
|
+
[agents, searchQuery]
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const openModal = (agent = null) => {
|
|
70
|
+
setEditingAgent(agent);
|
|
71
|
+
setIsModalOpen(true);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const closeModal = () => {
|
|
75
|
+
setEditingAgent(null);
|
|
76
|
+
setIsModalOpen(false);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const handleSaveAgent = (agentData) => {
|
|
80
|
+
if (editingAgent) {
|
|
81
|
+
// updateAgent({ id: editingAgent.id, ...agentData });
|
|
82
|
+
setAgents(agents.map(a => a.id === editingAgent.id ? { ...a, ...agentData } : a));
|
|
83
|
+
} else {
|
|
84
|
+
// createAgent(agentData);
|
|
85
|
+
setAgents([...agents, { id: `agent-${Date.now()}`, status: 'active', ...agentData }]);
|
|
86
|
+
}
|
|
87
|
+
closeModal();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const handleDeleteAgent = (agentId) => {
|
|
91
|
+
if (window.confirm('Are you sure you want to delete this agent?')) {
|
|
92
|
+
// deleteAgent({ id: agentId });
|
|
93
|
+
setAgents(agents.filter(a => a.id !== agentId));
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<DashboardLayout>
|
|
99
|
+
<div className="p-6 bg-background text-foreground">
|
|
100
|
+
<div className="flex justify-between items-center mb-6">
|
|
101
|
+
<h1 className="text-2xl font-bold flex items-center"><Bot className="mr-2" /> Agents</h1>
|
|
102
|
+
<button onClick={() => openModal()} className="bg-primary text-primary-foreground px-4 py-2 rounded-lg flex items-center hover:bg-primary/90">
|
|
103
|
+
<Plus className="mr-2 h-4 w-4" /> Create Agent
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div className="mb-6">
|
|
108
|
+
<div className="relative">
|
|
109
|
+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground h-5 w-5" />
|
|
110
|
+
<input
|
|
111
|
+
type="text"
|
|
112
|
+
placeholder="Search agents..."
|
|
113
|
+
value={searchQuery}
|
|
114
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
115
|
+
className="w-full bg-card border border-border rounded-lg pl-10 pr-4 py-2 focus:outline-none focus:ring-2 focus:ring-primary"
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
{filteredAgents.length > 0 ? (
|
|
121
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
122
|
+
{filteredAgents.map(agent => (
|
|
123
|
+
<AgentCard key={agent.id} agent={agent} onEdit={openModal} onDelete={handleDeleteAgent} />
|
|
124
|
+
))}
|
|
125
|
+
</div>
|
|
126
|
+
) : (
|
|
127
|
+
<div className="text-center py-16 border-2 border-dashed border-border rounded-lg">
|
|
128
|
+
<Bot className="mx-auto h-12 w-12 text-muted-foreground" />
|
|
129
|
+
<h3 className="mt-4 text-lg font-medium">No agents found</h3>
|
|
130
|
+
<p className="mt-1 text-sm text-muted-foreground">Create a new agent to get started.</p>
|
|
131
|
+
</div>
|
|
132
|
+
)}
|
|
133
|
+
</div>
|
|
134
|
+
{isModalOpen && <AgentModal agent={editingAgent} onSave={handleSaveAgent} onClose={closeModal} />}
|
|
135
|
+
</DashboardLayout>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function AgentCard({ agent, onEdit, onDelete }) {
|
|
140
|
+
return (
|
|
141
|
+
<div className="bg-card border border-border rounded-lg p-4 flex flex-col justify-between hover:shadow-lg transition-shadow">
|
|
142
|
+
<div>
|
|
143
|
+
<div className="flex justify-between items-start">
|
|
144
|
+
<div className="flex items-center mb-2">
|
|
145
|
+
<Bot className="h-8 w-8 text-primary mr-3" />
|
|
146
|
+
<div>
|
|
147
|
+
<h2 className="text-lg font-bold">{agent.name}</h2>
|
|
148
|
+
<span className={`text-xs px-2 py-0.5 rounded-full ${agent.status === 'active' ? 'bg-green-500/20 text-green-400' : 'bg-yellow-500/20 text-yellow-400'}`}>
|
|
149
|
+
{agent.status}
|
|
150
|
+
</span>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
<div className="flex items-center space-x-2">
|
|
154
|
+
<button onClick={() => onEdit(agent)} className="text-muted-foreground hover:text-foreground"><Edit className="h-4 w-4" /></button>
|
|
155
|
+
<button onClick={() => onDelete(agent.id)} className="text-muted-foreground hover:text-destructive"><Trash2 className="h-4 w-4" /></button>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
<p className="text-sm text-muted-foreground mb-4 h-10 overflow-hidden">{agent.description}</p>
|
|
159
|
+
<div className="flex items-center text-xs text-muted-foreground space-x-4 mb-4">
|
|
160
|
+
<div className="flex items-center"><Settings className="h-3 w-3 mr-1" /> {agent.model}</div>
|
|
161
|
+
<div className="flex items-center"><Zap className="h-3 w-3 mr-1" /> {agent.provider}</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
<button className="w-full bg-background border border-border text-center py-2 rounded-lg hover:bg-primary/10 text-sm">View Details</button>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function AgentModal({ agent, onSave, onClose }) {
|
|
170
|
+
const [formData, setFormData] = useState({
|
|
171
|
+
name: agent?.name || '',
|
|
172
|
+
description: agent?.description || '',
|
|
173
|
+
instructions: agent?.instructions || '',
|
|
174
|
+
model: agent?.model || 'gpt-4.1-mini',
|
|
175
|
+
provider: agent?.provider || 'OpenAI',
|
|
176
|
+
temperature: agent?.temperature || 0.7,
|
|
177
|
+
maxTokens: agent?.maxTokens || 4096,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const handleChange = (e) => {
|
|
181
|
+
const { name, value } = e.target;
|
|
182
|
+
setFormData(prev => ({ ...prev, [name]: value }));
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const handleSliderChange = (e) => {
|
|
186
|
+
setFormData(prev => ({ ...prev, temperature: parseFloat(e.target.value) }));
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const handleSubmit = (e) => {
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
onSave(formData);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const providers = ['OpenAI', 'Anthropic', 'OpenRouter', 'Google', 'xAI'];
|
|
195
|
+
const models = {
|
|
196
|
+
OpenAI: ['gpt-4.1-mini', 'gpt-4o', 'gpt-3.5-turbo'],
|
|
197
|
+
Google: ['gemini-2.5-flash', 'gemini-1.5-pro', 'gemini-1.0-pro'],
|
|
198
|
+
Anthropic: ['claude-3-opus', 'claude-3-sonnet', 'claude-3-haiku'],
|
|
199
|
+
OpenRouter: ['openrouter/auto'],
|
|
200
|
+
xAI: ['grok-4', 'grok-4-314b'],
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<div className="fixed inset-0 bg-black/60 z-50 flex justify-center items-center">
|
|
205
|
+
<div className="bg-card border border-border rounded-lg shadow-xl w-full max-w-2xl max-h-[90vh] flex flex-col">
|
|
206
|
+
<div className="flex justify-between items-center p-4 border-b border-border">
|
|
207
|
+
<h2 className="text-lg font-bold">{agent ? 'Edit Agent' : 'Create Agent'}</h2>
|
|
208
|
+
<button onClick={onClose} className="text-muted-foreground hover:text-foreground"><X className="h-5 w-5" /></button>
|
|
209
|
+
</div>
|
|
210
|
+
<form onSubmit={handleSubmit} className="flex-grow overflow-y-auto p-6 space-y-4">
|
|
211
|
+
<div>
|
|
212
|
+
<label className="block text-sm font-medium mb-1">Name</label>
|
|
213
|
+
<input type="text" name="name" value={formData.name} onChange={handleChange} className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary" required />
|
|
214
|
+
</div>
|
|
215
|
+
<div>
|
|
216
|
+
<label className="block text-sm font-medium mb-1">Description</label>
|
|
217
|
+
<input type="text" name="description" value={formData.description} onChange={handleChange} className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary" required />
|
|
218
|
+
</div>
|
|
219
|
+
<div>
|
|
220
|
+
<label className="block text-sm font-medium mb-1">Instructions</label>
|
|
221
|
+
<textarea name="instructions" value={formData.instructions} onChange={handleChange} rows="6" className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary" required />
|
|
222
|
+
</div>
|
|
223
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
224
|
+
<div>
|
|
225
|
+
<label className="block text-sm font-medium mb-1">Provider</label>
|
|
226
|
+
<select name="provider" value={formData.provider} onChange={handleChange} className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary">
|
|
227
|
+
{providers.map(p => <option key={p} value={p}>{p}</option>)}
|
|
228
|
+
</select>
|
|
229
|
+
</div>
|
|
230
|
+
<div>
|
|
231
|
+
<label className="block text-sm font-medium mb-1">Model</label>
|
|
232
|
+
<select name="model" value={formData.model} onChange={handleChange} className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary">
|
|
233
|
+
{(models[formData.provider] || []).map(m => <option key={m} value={m}>{m}</option>)}
|
|
234
|
+
</select>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
238
|
+
<div>
|
|
239
|
+
<label className="block text-sm font-medium mb-1">Temperature: {formData.temperature}</label>
|
|
240
|
+
<input type="range" min="0" max="1" step="0.1" value={formData.temperature} onChange={handleSliderChange} className="w-full h-2 bg-background rounded-lg appearance-none cursor-pointer" />
|
|
241
|
+
</div>
|
|
242
|
+
<div>
|
|
243
|
+
<label className="block text-sm font-medium mb-1">Max Tokens</label>
|
|
244
|
+
<input type="number" name="maxTokens" value={formData.maxTokens} onChange={handleChange} className="w-full bg-background border border-border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary" />
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
</form>
|
|
248
|
+
<div className="flex justify-end p-4 border-t border-border">
|
|
249
|
+
<button onClick={onClose} className="bg-background border border-border px-4 py-2 rounded-lg mr-2 hover:bg-primary/10">Cancel</button>
|
|
250
|
+
<button onClick={handleSubmit} className="bg-primary text-primary-foreground px-4 py-2 rounded-lg hover:bg-primary/90">Save Agent</button>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|