@greatapps/greatagents-ui 0.3.2 → 0.3.4
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/index.d.ts +204 -1
- package/dist/index.js +1797 -125
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +14 -0
- package/src/components/agents/agent-edit-form.tsx +4 -1
- package/src/components/agents/agent-form-dialog.tsx +5 -1
- package/src/components/agents/agent-objectives-list.tsx +15 -6
- package/src/components/agents/agent-prompt-editor.tsx +9 -5
- package/src/components/agents/agent-tabs.tsx +4 -4
- package/src/components/agents/agent-tools-list.tsx +12 -5
- package/src/components/agents/agents-table.tsx +7 -2
- package/src/components/capabilities/advanced-tab.tsx +82 -0
- package/src/components/capabilities/capabilities-tab.tsx +475 -0
- package/src/components/capabilities/integration-card.tsx +162 -0
- package/src/components/capabilities/integration-wizard.tsx +537 -0
- package/src/components/capabilities/integrations-tab.tsx +61 -0
- package/src/components/capabilities/types.ts +48 -0
- package/src/components/capabilities/wizard-steps/config-step.tsx +117 -0
- package/src/components/capabilities/wizard-steps/confirm-step.tsx +123 -0
- package/src/components/capabilities/wizard-steps/credentials-step.tsx +205 -0
- package/src/components/capabilities/wizard-steps/info-step.tsx +78 -0
- package/src/components/conversations/agent-conversations-table.tsx +13 -2
- package/src/components/conversations/conversation-view.tsx +2 -2
- package/src/components/tools/tool-credentials-form.tsx +34 -14
- package/src/components/tools/tool-form-dialog.tsx +9 -5
- package/src/components/tools/tools-table.tsx +8 -3
- package/src/data/integrations-registry.ts +23 -0
- package/src/hooks/index.ts +10 -0
- package/src/hooks/use-capabilities.ts +50 -0
- package/src/hooks/use-integrations.ts +114 -0
- package/src/index.ts +34 -0
- package/src/pages/agent-capabilities-page.tsx +159 -0
- package/src/pages/agent-detail-page.tsx +1 -0
- package/src/pages/index.ts +2 -0
- package/src/pages/integrations-management-page.tsx +166 -0
- package/src/types/capabilities.ts +32 -0
- package/src/types/index.ts +10 -0
package/package.json
CHANGED
package/src/client/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
Tool,
|
|
13
13
|
ToolCredential,
|
|
14
14
|
} from "../types";
|
|
15
|
+
import type { AgentCapability, AgentCapabilitiesPayload, CapabilitiesResponse } from "../types/capabilities";
|
|
15
16
|
|
|
16
17
|
export interface GagentsClientConfig {
|
|
17
18
|
baseUrl: string;
|
|
@@ -248,6 +249,19 @@ export function createGagentsClient(config: GagentsClientConfig) {
|
|
|
248
249
|
undefined,
|
|
249
250
|
{ provider },
|
|
250
251
|
),
|
|
252
|
+
|
|
253
|
+
// --- Capabilities ---
|
|
254
|
+
getCapabilities: (idAccount: number) =>
|
|
255
|
+
request<CapabilitiesResponse>("GET", idAccount, "capabilities"),
|
|
256
|
+
|
|
257
|
+
getAgentCapabilities: (idAccount: number, idAgent: number) =>
|
|
258
|
+
request<AgentCapability[]>("GET", idAccount, `agents/${idAgent}/capabilities`),
|
|
259
|
+
|
|
260
|
+
updateAgentCapabilities: (
|
|
261
|
+
idAccount: number,
|
|
262
|
+
idAgent: number,
|
|
263
|
+
body: AgentCapabilitiesPayload,
|
|
264
|
+
) => request<AgentCapability[]>("PUT", idAccount, `agents/${idAgent}/capabilities`, body),
|
|
251
265
|
};
|
|
252
266
|
}
|
|
253
267
|
|
|
@@ -119,6 +119,7 @@ export function AgentEditForm({ config, agent, idAccount, open, onOpenChange }:
|
|
|
119
119
|
<Label htmlFor="edit-title">Nome do Agente *</Label>
|
|
120
120
|
<Input
|
|
121
121
|
id="edit-title"
|
|
122
|
+
name="title"
|
|
122
123
|
value={form.title}
|
|
123
124
|
onChange={(e) => {
|
|
124
125
|
setForm((prev) => ({
|
|
@@ -152,6 +153,7 @@ export function AgentEditForm({ config, agent, idAccount, open, onOpenChange }:
|
|
|
152
153
|
<Label htmlFor="edit-delay">Delay de Digitação (s)</Label>
|
|
153
154
|
<Input
|
|
154
155
|
id="edit-delay"
|
|
156
|
+
name="delay"
|
|
155
157
|
type="number"
|
|
156
158
|
value={form.delayTyping}
|
|
157
159
|
onChange={(e) => updateField("delayTyping", e.target.value)}
|
|
@@ -168,6 +170,7 @@ export function AgentEditForm({ config, agent, idAccount, open, onOpenChange }:
|
|
|
168
170
|
<Label htmlFor="edit-waiting">Tempo de Espera (s)</Label>
|
|
169
171
|
<Input
|
|
170
172
|
id="edit-waiting"
|
|
173
|
+
name="waiting"
|
|
171
174
|
type="number"
|
|
172
175
|
value={form.waitingTime}
|
|
173
176
|
onChange={(e) => updateField("waitingTime", e.target.value)}
|
|
@@ -193,7 +196,7 @@ export function AgentEditForm({ config, agent, idAccount, open, onOpenChange }:
|
|
|
193
196
|
</Button>
|
|
194
197
|
<Button type="submit" disabled={updateAgent.isPending}>
|
|
195
198
|
{updateAgent.isPending && (
|
|
196
|
-
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
199
|
+
<Loader2 aria-hidden="true" className="mr-2 h-4 w-4 animate-spin" />
|
|
197
200
|
)}
|
|
198
201
|
Salvar
|
|
199
202
|
</Button>
|
|
@@ -96,6 +96,7 @@ export function AgentFormDialog({
|
|
|
96
96
|
<Label htmlFor="agent-photo">Foto (URL)</Label>
|
|
97
97
|
<Input
|
|
98
98
|
id="agent-photo"
|
|
99
|
+
name="photo"
|
|
99
100
|
value={photo}
|
|
100
101
|
onChange={(e) => setPhoto(e.target.value)}
|
|
101
102
|
placeholder="https://exemplo.com/foto.jpg"
|
|
@@ -106,6 +107,7 @@ export function AgentFormDialog({
|
|
|
106
107
|
<Label htmlFor="agent-title">Nome do Agente *</Label>
|
|
107
108
|
<Input
|
|
108
109
|
id="agent-title"
|
|
110
|
+
name="title"
|
|
109
111
|
value={title}
|
|
110
112
|
onChange={(e) => setTitle(e.target.value)}
|
|
111
113
|
placeholder="Ex: Assistente de Agendamento"
|
|
@@ -118,6 +120,7 @@ export function AgentFormDialog({
|
|
|
118
120
|
<Label htmlFor="agent-delay">Delay de Digitação (ms)</Label>
|
|
119
121
|
<Input
|
|
120
122
|
id="agent-delay"
|
|
123
|
+
name="delay"
|
|
121
124
|
type="number"
|
|
122
125
|
value={delayTyping}
|
|
123
126
|
onChange={(e) => setDelayTyping(e.target.value)}
|
|
@@ -130,6 +133,7 @@ export function AgentFormDialog({
|
|
|
130
133
|
<Label htmlFor="agent-waiting">Tempo de Espera (ms)</Label>
|
|
131
134
|
<Input
|
|
132
135
|
id="agent-waiting"
|
|
136
|
+
name="waiting"
|
|
133
137
|
type="number"
|
|
134
138
|
value={waitingTime}
|
|
135
139
|
onChange={(e) => setWaitingTime(e.target.value)}
|
|
@@ -150,7 +154,7 @@ export function AgentFormDialog({
|
|
|
150
154
|
</Button>
|
|
151
155
|
<Button type="submit" disabled={isPending || !title.trim()}>
|
|
152
156
|
{isPending ? (
|
|
153
|
-
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
157
|
+
<Loader2 aria-hidden="true" className="mr-2 h-4 w-4 animate-spin" />
|
|
154
158
|
) : null}
|
|
155
159
|
{isEditing ? "Salvar" : "Criar"}
|
|
156
160
|
</Button>
|
|
@@ -238,7 +238,7 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
238
238
|
className="flex items-center gap-3 rounded-lg border bg-card p-3"
|
|
239
239
|
>
|
|
240
240
|
<SortableItemHandle className="shrink-0 text-muted-foreground hover:text-foreground">
|
|
241
|
-
<GripVertical className="h-5 w-5" />
|
|
241
|
+
<GripVertical aria-hidden="true" className="h-5 w-5" />
|
|
242
242
|
</SortableItemHandle>
|
|
243
243
|
|
|
244
244
|
<div className="flex flex-1 flex-col gap-1 min-w-0">
|
|
@@ -260,6 +260,7 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
260
260
|
</div>
|
|
261
261
|
|
|
262
262
|
<Switch
|
|
263
|
+
aria-label="Ativar/Desativar"
|
|
263
264
|
checked={objective.active}
|
|
264
265
|
onCheckedChange={(checked) =>
|
|
265
266
|
handleToggleActive(objective, checked)
|
|
@@ -270,6 +271,7 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
270
271
|
<Button
|
|
271
272
|
variant="ghost"
|
|
272
273
|
size="icon"
|
|
274
|
+
aria-label="Editar"
|
|
273
275
|
className="shrink-0 text-muted-foreground hover:text-foreground"
|
|
274
276
|
onClick={() => openEdit(objective)}
|
|
275
277
|
>
|
|
@@ -279,6 +281,7 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
279
281
|
<Button
|
|
280
282
|
variant="ghost"
|
|
281
283
|
size="icon"
|
|
284
|
+
aria-label="Excluir"
|
|
282
285
|
className="shrink-0 text-muted-foreground hover:text-destructive"
|
|
283
286
|
onClick={() => setRemoveTarget(objective)}
|
|
284
287
|
>
|
|
@@ -292,7 +295,7 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
292
295
|
const obj = sortedObjectives.find((o) => o.id === value);
|
|
293
296
|
return (
|
|
294
297
|
<div className="flex items-center gap-3 rounded-lg border bg-card p-3 shadow-lg">
|
|
295
|
-
<GripVertical className="h-5 w-5 text-muted-foreground" />
|
|
298
|
+
<GripVertical aria-hidden="true" className="h-5 w-5 text-muted-foreground" />
|
|
296
299
|
<span className="font-medium">{obj?.title}</span>
|
|
297
300
|
</div>
|
|
298
301
|
);
|
|
@@ -311,8 +314,10 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
311
314
|
</DialogHeader>
|
|
312
315
|
<div className="space-y-4">
|
|
313
316
|
<div className="space-y-2">
|
|
314
|
-
<Label>Título *</Label>
|
|
317
|
+
<Label htmlFor="objective-title">Título *</Label>
|
|
315
318
|
<Input
|
|
319
|
+
id="objective-title"
|
|
320
|
+
name="title"
|
|
316
321
|
value={form.title}
|
|
317
322
|
onChange={(e) => {
|
|
318
323
|
const title = e.target.value;
|
|
@@ -327,8 +332,10 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
327
332
|
</div>
|
|
328
333
|
|
|
329
334
|
<div className="space-y-2">
|
|
330
|
-
<Label>Slug (identificador) *</Label>
|
|
335
|
+
<Label htmlFor="objective-slug">Slug (identificador) *</Label>
|
|
331
336
|
<Input
|
|
337
|
+
id="objective-slug"
|
|
338
|
+
name="slug"
|
|
332
339
|
value={form.slug}
|
|
333
340
|
onChange={(e) => {
|
|
334
341
|
setSlugManual(true);
|
|
@@ -343,13 +350,15 @@ export function AgentObjectivesList({ agent, config }: AgentObjectivesListProps)
|
|
|
343
350
|
</div>
|
|
344
351
|
|
|
345
352
|
<div className="space-y-2">
|
|
346
|
-
<Label>Instruções do Objetivo</Label>
|
|
353
|
+
<Label htmlFor="objective-prompt">Instruções do Objetivo</Label>
|
|
347
354
|
<Textarea
|
|
355
|
+
id="objective-prompt"
|
|
356
|
+
name="prompt"
|
|
348
357
|
value={form.prompt}
|
|
349
358
|
onChange={(e) =>
|
|
350
359
|
setForm((f) => ({ ...f, prompt: e.target.value }))
|
|
351
360
|
}
|
|
352
|
-
placeholder="
|
|
361
|
+
placeholder="Instru\u00e7\u00f5es detalhadas que o agente seguir\u00e1 quando este objetivo for ativado\u2026"
|
|
353
362
|
rows={8}
|
|
354
363
|
/>
|
|
355
364
|
<p className="text-xs text-muted-foreground">
|
|
@@ -214,24 +214,28 @@ export function AgentPromptEditor({ config, agent }: AgentPromptEditorProps) {
|
|
|
214
214
|
<div className="space-y-2">
|
|
215
215
|
<textarea
|
|
216
216
|
ref={textareaRef}
|
|
217
|
+
aria-label="Prompt do sistema"
|
|
218
|
+
name="prompt"
|
|
217
219
|
value={promptText}
|
|
218
220
|
onChange={(e) => setPromptText(e.target.value)}
|
|
219
221
|
onKeyDown={handleKeyDown}
|
|
220
|
-
placeholder="Escreva o prompt do sistema aqui
|
|
222
|
+
placeholder="Escreva o prompt do sistema aqui\u2026"
|
|
221
223
|
disabled={updateAgent.isPending}
|
|
222
224
|
className="w-full resize-none rounded-lg border bg-background p-3 font-mono text-sm leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
|
|
223
225
|
style={{ minHeight: "300px" }}
|
|
224
226
|
/>
|
|
225
227
|
<div className="flex items-center gap-3 text-xs text-muted-foreground">
|
|
226
|
-
<span>{charCount.toLocaleString("pt-BR")} caracteres</span>
|
|
228
|
+
<span className="tabular-nums">{charCount.toLocaleString("pt-BR")} caracteres</span>
|
|
227
229
|
<span>·</span>
|
|
228
|
-
<span>~{tokenEstimate.toLocaleString("pt-BR")} tokens</span>
|
|
230
|
+
<span className="tabular-nums">~{tokenEstimate.toLocaleString("pt-BR")} tokens</span>
|
|
229
231
|
</div>
|
|
230
232
|
</div>
|
|
231
233
|
|
|
232
234
|
{/* Save row */}
|
|
233
235
|
<div className="flex items-center gap-3">
|
|
234
236
|
<Input
|
|
237
|
+
aria-label="Notas da alteração"
|
|
238
|
+
name="changeNotes"
|
|
235
239
|
value={changeNotes}
|
|
236
240
|
onChange={(e) => setChangeNotes(e.target.value)}
|
|
237
241
|
placeholder="O que mudou? (opcional)"
|
|
@@ -390,7 +394,7 @@ export function AgentPromptEditor({ config, agent }: AgentPromptEditorProps) {
|
|
|
390
394
|
onClick={() => setCompareVersionId(isComparing ? null : version.id)}
|
|
391
395
|
className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
|
|
392
396
|
>
|
|
393
|
-
<FileText className="h-3 w-3" />
|
|
397
|
+
<FileText aria-hidden="true" className="h-3 w-3" />
|
|
394
398
|
{isComparing ? "Ocultar diff" : "Comparar"}
|
|
395
399
|
</button>
|
|
396
400
|
<button
|
|
@@ -398,7 +402,7 @@ export function AgentPromptEditor({ config, agent }: AgentPromptEditorProps) {
|
|
|
398
402
|
onClick={() => handleRestore(version)}
|
|
399
403
|
className="flex items-center gap-1 text-xs text-primary hover:underline"
|
|
400
404
|
>
|
|
401
|
-
<RotateCcw className="h-3 w-3" />
|
|
405
|
+
<RotateCcw aria-hidden="true" className="h-3 w-3" />
|
|
402
406
|
Restaurar
|
|
403
407
|
</button>
|
|
404
408
|
</div>
|
|
@@ -23,19 +23,19 @@ export function AgentTabs({ agent, config, renderChatLink }: AgentTabsProps) {
|
|
|
23
23
|
<Tabs defaultValue="prompt">
|
|
24
24
|
<TabsList>
|
|
25
25
|
<TabsTrigger value="prompt" className="flex items-center gap-1.5">
|
|
26
|
-
<FileText className="h-3.5 w-3.5" />
|
|
26
|
+
<FileText aria-hidden="true" className="h-3.5 w-3.5" />
|
|
27
27
|
Prompt
|
|
28
28
|
</TabsTrigger>
|
|
29
29
|
<TabsTrigger value="objetivos" className="flex items-center gap-1.5">
|
|
30
|
-
<Target className="h-3.5 w-3.5" />
|
|
30
|
+
<Target aria-hidden="true" className="h-3.5 w-3.5" />
|
|
31
31
|
Objetivos
|
|
32
32
|
</TabsTrigger>
|
|
33
33
|
<TabsTrigger value="ferramentas" className="flex items-center gap-1.5">
|
|
34
|
-
<Wrench className="h-3.5 w-3.5" />
|
|
34
|
+
<Wrench aria-hidden="true" className="h-3.5 w-3.5" />
|
|
35
35
|
Ferramentas
|
|
36
36
|
</TabsTrigger>
|
|
37
37
|
<TabsTrigger value="conversas" className="flex items-center gap-1.5">
|
|
38
|
-
<MessageCircle className="h-3.5 w-3.5" />
|
|
38
|
+
<MessageCircle aria-hidden="true" className="h-3.5 w-3.5" />
|
|
39
39
|
Conversas
|
|
40
40
|
</TabsTrigger>
|
|
41
41
|
</TabsList>
|
|
@@ -182,7 +182,9 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
182
182
|
<PopoverContent className="w-72 p-0" align="end">
|
|
183
183
|
<div className="p-2">
|
|
184
184
|
<Input
|
|
185
|
-
placeholder="Buscar ferramenta
|
|
185
|
+
placeholder="Buscar ferramenta\u2026"
|
|
186
|
+
aria-label="Buscar ferramenta"
|
|
187
|
+
name="search"
|
|
186
188
|
value={search}
|
|
187
189
|
onChange={(e) => setSearch(e.target.value)}
|
|
188
190
|
className="h-8"
|
|
@@ -250,6 +252,7 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
250
252
|
</div>
|
|
251
253
|
|
|
252
254
|
<Switch
|
|
255
|
+
aria-label="Ativar/Desativar"
|
|
253
256
|
checked={agentTool.enabled}
|
|
254
257
|
onCheckedChange={(checked) =>
|
|
255
258
|
handleToggleEnabled(agentTool, checked)
|
|
@@ -260,6 +263,7 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
260
263
|
<Button
|
|
261
264
|
variant="ghost"
|
|
262
265
|
size="icon"
|
|
266
|
+
aria-label="Configurar"
|
|
263
267
|
className="shrink-0 text-muted-foreground hover:text-foreground"
|
|
264
268
|
onClick={() => openConfig(agentTool)}
|
|
265
269
|
title="Configurar instruções"
|
|
@@ -270,6 +274,7 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
270
274
|
<Button
|
|
271
275
|
variant="ghost"
|
|
272
276
|
size="icon"
|
|
277
|
+
aria-label="Remover"
|
|
273
278
|
className="shrink-0 text-muted-foreground hover:text-destructive"
|
|
274
279
|
onClick={() => setRemoveTarget(agentTool)}
|
|
275
280
|
>
|
|
@@ -295,12 +300,12 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
295
300
|
<div className="space-y-4">
|
|
296
301
|
{configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && (
|
|
297
302
|
<div className="space-y-2">
|
|
298
|
-
<Label>Credencial</Label>
|
|
303
|
+
<Label htmlFor="tool-credential">Credencial</Label>
|
|
299
304
|
<Select
|
|
300
305
|
value={configCredentialId || undefined}
|
|
301
306
|
onValueChange={(val) => setConfigCredentialId(val === "__none__" ? "" : val)}
|
|
302
307
|
>
|
|
303
|
-
<SelectTrigger>
|
|
308
|
+
<SelectTrigger id="tool-credential">
|
|
304
309
|
<SelectValue placeholder="Selecione uma credencial (opcional)" />
|
|
305
310
|
</SelectTrigger>
|
|
306
311
|
<SelectContent>
|
|
@@ -320,11 +325,13 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
320
325
|
</div>
|
|
321
326
|
)}
|
|
322
327
|
<div className="space-y-2">
|
|
323
|
-
<Label>Instruções Personalizadas</Label>
|
|
328
|
+
<Label htmlFor="tool-instructions">Instruções Personalizadas</Label>
|
|
324
329
|
<Textarea
|
|
330
|
+
id="tool-instructions"
|
|
331
|
+
name="instructions"
|
|
325
332
|
value={configInstructions}
|
|
326
333
|
onChange={(e) => setConfigInstructions(e.target.value)}
|
|
327
|
-
placeholder="
|
|
334
|
+
placeholder="Instru\u00e7\u00f5es sobre como e quando o agente deve usar esta ferramenta\u2026"
|
|
328
335
|
rows={6}
|
|
329
336
|
/>
|
|
330
337
|
<p className="text-xs text-muted-foreground">
|
|
@@ -78,6 +78,7 @@ function useColumns(
|
|
|
78
78
|
variant="ghost"
|
|
79
79
|
size="icon"
|
|
80
80
|
className="h-8 w-8"
|
|
81
|
+
aria-label="Editar"
|
|
81
82
|
onClick={() => onEdit(row.original)}
|
|
82
83
|
>
|
|
83
84
|
<Pencil className="h-4 w-4" />
|
|
@@ -91,6 +92,7 @@ function useColumns(
|
|
|
91
92
|
variant="ghost"
|
|
92
93
|
size="icon"
|
|
93
94
|
className="h-8 w-8 text-destructive hover:text-destructive"
|
|
95
|
+
aria-label="Excluir"
|
|
94
96
|
onClick={() => onDelete(row.original.id)}
|
|
95
97
|
>
|
|
96
98
|
<Trash2 className="h-4 w-4" />
|
|
@@ -151,9 +153,12 @@ export function AgentsTable({ config, onNavigateToAgent }: { config: GagentsHook
|
|
|
151
153
|
<>
|
|
152
154
|
<div className="flex items-center gap-3">
|
|
153
155
|
<div className="relative flex-1 max-w-md">
|
|
154
|
-
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
|
156
|
+
<Search aria-hidden="true" className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
|
155
157
|
<Input
|
|
156
|
-
placeholder="Buscar agentes
|
|
158
|
+
placeholder="Buscar agentes\u2026"
|
|
159
|
+
aria-label="Buscar agentes"
|
|
160
|
+
name="search"
|
|
161
|
+
autoComplete="off"
|
|
157
162
|
value={search}
|
|
158
163
|
onChange={(e) => handleSearchChange(e.target.value)}
|
|
159
164
|
className="pl-9"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import type { GagentsHookConfig } from "../../hooks/types";
|
|
5
|
+
import { useToolCredentials } from "../../hooks";
|
|
6
|
+
import { ToolsTable } from "../tools/tools-table";
|
|
7
|
+
import { ToolCredentialsForm } from "../tools/tool-credentials-form";
|
|
8
|
+
import { ToolFormDialog } from "../tools/tool-form-dialog";
|
|
9
|
+
import type { Tool } from "../../types";
|
|
10
|
+
import { Info } from "lucide-react";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Props
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
export interface AdvancedTabProps {
|
|
17
|
+
config: GagentsHookConfig;
|
|
18
|
+
agentId: number;
|
|
19
|
+
gagentsApiUrl: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Component
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
export function AdvancedTab({ config, agentId, gagentsApiUrl }: AdvancedTabProps) {
|
|
27
|
+
const { data: credentialsData, isLoading: isLoadingCredentials } =
|
|
28
|
+
useToolCredentials(config);
|
|
29
|
+
const credentials = credentialsData?.data ?? [];
|
|
30
|
+
|
|
31
|
+
const [editingTool, setEditingTool] = useState<Tool | null>(null);
|
|
32
|
+
const [showToolForm, setShowToolForm] = useState(false);
|
|
33
|
+
|
|
34
|
+
function handleEditTool(tool: Tool) {
|
|
35
|
+
setEditingTool(tool);
|
|
36
|
+
setShowToolForm(true);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function handleToolFormOpenChange(open: boolean) {
|
|
40
|
+
setShowToolForm(open);
|
|
41
|
+
if (!open) setEditingTool(null);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div className="space-y-8">
|
|
46
|
+
{/* Info banner */}
|
|
47
|
+
<div className="flex items-start gap-3 rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/30">
|
|
48
|
+
<Info className="mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" />
|
|
49
|
+
<p className="text-sm text-blue-800 dark:text-blue-300">
|
|
50
|
+
Use as abas <strong>Capacidades</strong> e <strong>Integrações</strong> para
|
|
51
|
+
configuração simplificada. Esta aba oferece controlo manual avançado sobre
|
|
52
|
+
ferramentas e credenciais.
|
|
53
|
+
</p>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
{/* Ferramentas section */}
|
|
57
|
+
<section className="space-y-3">
|
|
58
|
+
<h3 className="text-sm font-medium">Ferramentas</h3>
|
|
59
|
+
<ToolsTable onEdit={handleEditTool} config={config} />
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
{/* Credenciais section */}
|
|
63
|
+
<section className="space-y-3">
|
|
64
|
+
<h3 className="text-sm font-medium">Credenciais</h3>
|
|
65
|
+
<ToolCredentialsForm
|
|
66
|
+
credentials={credentials}
|
|
67
|
+
isLoading={isLoadingCredentials}
|
|
68
|
+
config={config}
|
|
69
|
+
gagentsApiUrl={gagentsApiUrl}
|
|
70
|
+
/>
|
|
71
|
+
</section>
|
|
72
|
+
|
|
73
|
+
{/* Tool edit dialog */}
|
|
74
|
+
<ToolFormDialog
|
|
75
|
+
open={showToolForm}
|
|
76
|
+
onOpenChange={handleToolFormOpenChange}
|
|
77
|
+
tool={editingTool ?? undefined}
|
|
78
|
+
config={config}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|