@greatapps/greatagents-ui 0.3.24 → 0.3.26
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/package.json
CHANGED
|
@@ -6,12 +6,8 @@ import {
|
|
|
6
6
|
Button,
|
|
7
7
|
Badge,
|
|
8
8
|
Skeleton,
|
|
9
|
-
Dialog,
|
|
10
|
-
DialogContent,
|
|
11
|
-
DialogHeader,
|
|
12
|
-
DialogTitle,
|
|
13
9
|
} from "@greatapps/greatauth-ui/ui";
|
|
14
|
-
import { FileText, RotateCcw, X
|
|
10
|
+
import { FileText, RotateCcw, X } from "lucide-react";
|
|
15
11
|
import { toast } from "sonner";
|
|
16
12
|
|
|
17
13
|
interface AgentRevisionTabProps {
|
|
@@ -19,7 +15,6 @@ interface AgentRevisionTabProps {
|
|
|
19
15
|
config: GagentsHookConfig;
|
|
20
16
|
}
|
|
21
17
|
|
|
22
|
-
const STRUCTURED_MARKERS = ["[IDENTIDADE]", "[MISSÃO]", "[TOM, ESTILO & FORMATO]"];
|
|
23
18
|
|
|
24
19
|
function formatDate(dateStr: string): string {
|
|
25
20
|
const date = new Date(dateStr);
|
|
@@ -107,16 +102,10 @@ function buildAssembledPrompt(agent: Agent): string {
|
|
|
107
102
|
return sections.join("\n\n");
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
function isLegacyVersion(version: PromptVersion): boolean {
|
|
111
|
-
const content = version.prompt_content ?? "";
|
|
112
|
-
return !STRUCTURED_MARKERS.some((marker) => content.includes(marker));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
105
|
export function AgentRevisionTab({ agent, config }: AgentRevisionTabProps) {
|
|
116
106
|
const { data: versionsData, isLoading } = usePromptVersions(config, agent.id);
|
|
117
107
|
|
|
118
108
|
const [compareVersionId, setCompareVersionId] = useState<number | null>(null);
|
|
119
|
-
const [legacyModalVersion, setLegacyModalVersion] = useState<PromptVersion | null>(null);
|
|
120
109
|
|
|
121
110
|
const versions = (versionsData?.data || []) as PromptVersion[];
|
|
122
111
|
const sortedVersions = [...versions].sort(
|
|
@@ -143,12 +132,8 @@ export function AgentRevisionTab({ agent, config }: AgentRevisionTabProps) {
|
|
|
143
132
|
? computeDiff(compareVersion.prompt_content ?? "", currentVersion.prompt_content ?? "")
|
|
144
133
|
: null;
|
|
145
134
|
|
|
146
|
-
function handleRestore(
|
|
147
|
-
|
|
148
|
-
setLegacyModalVersion(version);
|
|
149
|
-
} else {
|
|
150
|
-
toast.info("Restaurar versão estruturada — funcionalidade em desenvolvimento");
|
|
151
|
-
}
|
|
135
|
+
function handleRestore(_version: PromptVersion) {
|
|
136
|
+
toast.info("Restaurar versão — funcionalidade em desenvolvimento");
|
|
152
137
|
}
|
|
153
138
|
|
|
154
139
|
if (isLoading) {
|
|
@@ -319,50 +304,6 @@ export function AgentRevisionTab({ agent, config }: AgentRevisionTabProps) {
|
|
|
319
304
|
)}
|
|
320
305
|
</div>
|
|
321
306
|
|
|
322
|
-
{/* Legacy version modal */}
|
|
323
|
-
<Dialog
|
|
324
|
-
open={!!legacyModalVersion}
|
|
325
|
-
onOpenChange={(open) => {
|
|
326
|
-
if (!open) setLegacyModalVersion(null);
|
|
327
|
-
}}
|
|
328
|
-
>
|
|
329
|
-
<DialogContent className="max-w-2xl">
|
|
330
|
-
<DialogHeader>
|
|
331
|
-
<DialogTitle className="flex items-center gap-2">
|
|
332
|
-
<AlertTriangle className="h-5 w-5 text-amber-500" />
|
|
333
|
-
Versão Legada — v{legacyModalVersion?.version_number}
|
|
334
|
-
</DialogTitle>
|
|
335
|
-
</DialogHeader>
|
|
336
|
-
<div className="space-y-3">
|
|
337
|
-
<div className="rounded-lg border border-amber-500/30 bg-amber-500/5 p-3">
|
|
338
|
-
<p className="text-sm text-amber-700 dark:text-amber-400">
|
|
339
|
-
Esta versão foi criada antes da reestruturação e não pode ser restaurada nos campos estruturados.
|
|
340
|
-
</p>
|
|
341
|
-
</div>
|
|
342
|
-
<div className="max-h-96 overflow-auto rounded-lg border p-4">
|
|
343
|
-
<pre className="whitespace-pre-wrap font-mono text-sm leading-relaxed">
|
|
344
|
-
{legacyModalVersion?.prompt_content ?? ""}
|
|
345
|
-
</pre>
|
|
346
|
-
</div>
|
|
347
|
-
<div className="flex items-center gap-3 text-xs text-muted-foreground">
|
|
348
|
-
<span>
|
|
349
|
-
{(legacyModalVersion?.prompt_content ?? "").length.toLocaleString("pt-BR")} caracteres
|
|
350
|
-
</span>
|
|
351
|
-
{legacyModalVersion?.change_notes && (
|
|
352
|
-
<>
|
|
353
|
-
<span>·</span>
|
|
354
|
-
<span className="italic">{legacyModalVersion.change_notes}</span>
|
|
355
|
-
</>
|
|
356
|
-
)}
|
|
357
|
-
</div>
|
|
358
|
-
</div>
|
|
359
|
-
<div className="flex justify-end pt-2">
|
|
360
|
-
<Button variant="outline" onClick={() => setLegacyModalVersion(null)}>
|
|
361
|
-
Fechar
|
|
362
|
-
</Button>
|
|
363
|
-
</div>
|
|
364
|
-
</DialogContent>
|
|
365
|
-
</Dialog>
|
|
366
307
|
</div>
|
|
367
308
|
);
|
|
368
309
|
}
|
|
@@ -27,11 +27,11 @@ import {
|
|
|
27
27
|
PopoverTrigger,
|
|
28
28
|
Input,
|
|
29
29
|
Textarea,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
Sheet,
|
|
31
|
+
SheetContent,
|
|
32
|
+
SheetHeader,
|
|
33
|
+
SheetTitle,
|
|
34
|
+
SheetFooter,
|
|
35
35
|
Label,
|
|
36
36
|
Select,
|
|
37
37
|
SelectContent,
|
|
@@ -291,18 +291,18 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
291
291
|
</div>
|
|
292
292
|
)}
|
|
293
293
|
|
|
294
|
-
{/* Config
|
|
295
|
-
<
|
|
294
|
+
{/* Config sheet for custom_instructions */}
|
|
295
|
+
<Sheet
|
|
296
296
|
open={!!configTarget}
|
|
297
297
|
onOpenChange={(open) => !open && setConfigTarget(null)}
|
|
298
298
|
>
|
|
299
|
-
<
|
|
300
|
-
<
|
|
301
|
-
<
|
|
299
|
+
<SheetContent className="sm:max-w-lg">
|
|
300
|
+
<SheetHeader>
|
|
301
|
+
<SheetTitle>
|
|
302
302
|
Instruções da Ferramenta
|
|
303
|
-
</
|
|
304
|
-
</
|
|
305
|
-
<div className="space-y-4">
|
|
303
|
+
</SheetTitle>
|
|
304
|
+
</SheetHeader>
|
|
305
|
+
<div className="flex-1 overflow-y-auto px-4 space-y-4">
|
|
306
306
|
{configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && (
|
|
307
307
|
<div className="space-y-2">
|
|
308
308
|
<Label htmlFor="tool-credential">Credencial</Label>
|
|
@@ -344,7 +344,7 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
344
344
|
</p>
|
|
345
345
|
</div>
|
|
346
346
|
</div>
|
|
347
|
-
<
|
|
347
|
+
<SheetFooter className="flex-row justify-end border-t">
|
|
348
348
|
<Button
|
|
349
349
|
variant="outline"
|
|
350
350
|
onClick={() => setConfigTarget(null)}
|
|
@@ -357,9 +357,9 @@ export function AgentToolsList({ agent, config }: AgentToolsListProps) {
|
|
|
357
357
|
>
|
|
358
358
|
Salvar
|
|
359
359
|
</Button>
|
|
360
|
-
</
|
|
361
|
-
</
|
|
362
|
-
</
|
|
360
|
+
</SheetFooter>
|
|
361
|
+
</SheetContent>
|
|
362
|
+
</Sheet>
|
|
363
363
|
|
|
364
364
|
{/* Remove confirmation */}
|
|
365
365
|
<AlertDialog
|
|
@@ -3,11 +3,11 @@ import { useCreateTool, useUpdateTool } from "../../hooks";
|
|
|
3
3
|
import type { Tool } from "../../types";
|
|
4
4
|
import type { GagentsHookConfig } from "../../hooks/types";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
Sheet,
|
|
7
|
+
SheetContent,
|
|
8
|
+
SheetHeader,
|
|
9
|
+
SheetTitle,
|
|
10
|
+
SheetFooter,
|
|
11
11
|
Button,
|
|
12
12
|
Input,
|
|
13
13
|
Textarea,
|
|
@@ -177,127 +177,128 @@ export function ToolFormDialog({
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
return (
|
|
180
|
-
<
|
|
181
|
-
<
|
|
182
|
-
<
|
|
183
|
-
<
|
|
180
|
+
<Sheet open={open} onOpenChange={onOpenChange}>
|
|
181
|
+
<SheetContent className="sm:max-w-lg">
|
|
182
|
+
<SheetHeader>
|
|
183
|
+
<SheetTitle>
|
|
184
184
|
{isEditing ? "Editar Ferramenta" : "Nova Ferramenta"}
|
|
185
|
-
</
|
|
186
|
-
</
|
|
187
|
-
<form onSubmit={handleSubmit} className="
|
|
188
|
-
<div className="space-y-
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
185
|
+
</SheetTitle>
|
|
186
|
+
</SheetHeader>
|
|
187
|
+
<form onSubmit={handleSubmit} className="flex flex-1 flex-col overflow-hidden">
|
|
188
|
+
<div className="flex-1 overflow-y-auto px-4 space-y-4">
|
|
189
|
+
<div className="space-y-2">
|
|
190
|
+
<Label htmlFor="tool-name">Nome *</Label>
|
|
191
|
+
<Input
|
|
192
|
+
id="tool-name"
|
|
193
|
+
name="name"
|
|
194
|
+
value={form.name}
|
|
195
|
+
onChange={(e) => {
|
|
196
|
+
const name = e.target.value;
|
|
197
|
+
setForm((prev) => ({
|
|
198
|
+
...prev,
|
|
199
|
+
name,
|
|
200
|
+
nameError: name.trim() ? false : prev.nameError,
|
|
201
|
+
...(!slugManuallyEdited && !isEditing
|
|
202
|
+
? { slug: slugify(name), slugError: false }
|
|
203
|
+
: {}),
|
|
204
|
+
}));
|
|
205
|
+
}}
|
|
206
|
+
placeholder="Ex: Google Calendar"
|
|
207
|
+
disabled={isPending}
|
|
208
|
+
/>
|
|
209
|
+
{form.nameError && (
|
|
210
|
+
<p className="text-sm text-destructive">Nome é obrigatório</p>
|
|
211
|
+
)}
|
|
212
|
+
</div>
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
214
|
+
<div className="space-y-2">
|
|
215
|
+
<Label htmlFor="tool-slug">Slug (identificador único) *</Label>
|
|
216
|
+
<Input
|
|
217
|
+
id="tool-slug"
|
|
218
|
+
name="slug"
|
|
219
|
+
value={form.slug}
|
|
220
|
+
onChange={(e) => {
|
|
221
|
+
setSlugManuallyEdited(true);
|
|
222
|
+
setForm((prev) => ({
|
|
223
|
+
...prev,
|
|
224
|
+
slug: e.target.value,
|
|
225
|
+
slugError: e.target.value.trim() ? false : prev.slugError,
|
|
226
|
+
}));
|
|
227
|
+
}}
|
|
228
|
+
placeholder="Ex: google-calendar"
|
|
229
|
+
disabled={isPending}
|
|
230
|
+
/>
|
|
231
|
+
<p className="text-xs text-muted-foreground">
|
|
232
|
+
Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta.
|
|
233
|
+
</p>
|
|
234
|
+
{form.slugError && (
|
|
235
|
+
<p className="text-sm text-destructive">Slug é obrigatório</p>
|
|
236
|
+
)}
|
|
237
|
+
</div>
|
|
237
238
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
239
|
+
<div className="space-y-2">
|
|
240
|
+
<Label htmlFor="tool-type">Tipo de Autenticação *</Label>
|
|
241
|
+
<Select
|
|
242
|
+
value={form.type}
|
|
243
|
+
onValueChange={(value) => {
|
|
244
|
+
setForm((prev) => ({
|
|
245
|
+
...prev,
|
|
246
|
+
type: value,
|
|
247
|
+
typeError: false,
|
|
248
|
+
}));
|
|
249
|
+
}}
|
|
250
|
+
disabled={isPending}
|
|
251
|
+
>
|
|
252
|
+
<SelectTrigger id="tool-type">
|
|
253
|
+
<SelectValue placeholder="Selecione o tipo" />
|
|
254
|
+
</SelectTrigger>
|
|
255
|
+
<SelectContent>
|
|
256
|
+
{TOOL_AUTH_TYPES.map((t) => (
|
|
257
|
+
<SelectItem key={t.value} value={t.value}>
|
|
258
|
+
{t.label}
|
|
259
|
+
</SelectItem>
|
|
260
|
+
))}
|
|
261
|
+
</SelectContent>
|
|
262
|
+
</Select>
|
|
263
|
+
<p className="text-xs text-muted-foreground">
|
|
264
|
+
Define se a ferramenta requer credenciais para funcionar.
|
|
265
|
+
</p>
|
|
266
|
+
{form.typeError && (
|
|
267
|
+
<p className="text-sm text-destructive">Tipo é obrigatório</p>
|
|
268
|
+
)}
|
|
269
|
+
</div>
|
|
269
270
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
271
|
+
<div className="space-y-2">
|
|
272
|
+
<Label htmlFor="tool-description">Descrição</Label>
|
|
273
|
+
<Textarea
|
|
274
|
+
id="tool-description"
|
|
275
|
+
name="description"
|
|
276
|
+
value={form.description}
|
|
277
|
+
onChange={(e) =>
|
|
278
|
+
setForm((prev) => ({ ...prev, description: e.target.value }))
|
|
279
|
+
}
|
|
280
|
+
placeholder="Descri\u00e7\u00e3o da ferramenta\u2026"
|
|
281
|
+
rows={3}
|
|
282
|
+
disabled={isPending}
|
|
283
|
+
/>
|
|
284
|
+
</div>
|
|
284
285
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
286
|
+
<div className="space-y-2">
|
|
287
|
+
<Label htmlFor="tool-function-defs">
|
|
288
|
+
Definições de Função (JSON)
|
|
289
|
+
</Label>
|
|
290
|
+
<Textarea
|
|
291
|
+
id="tool-function-defs"
|
|
292
|
+
name="functionDefs"
|
|
293
|
+
value={form.functionDefinitions}
|
|
294
|
+
onChange={(e) => {
|
|
295
|
+
setForm((prev) => ({
|
|
296
|
+
...prev,
|
|
297
|
+
functionDefinitions: e.target.value,
|
|
298
|
+
jsonError: false,
|
|
299
|
+
}));
|
|
300
|
+
}}
|
|
301
|
+
placeholder={`[
|
|
301
302
|
{
|
|
302
303
|
"type": "function",
|
|
303
304
|
"function": {
|
|
@@ -311,19 +312,20 @@ export function ToolFormDialog({
|
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
]`}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
315
|
+
rows={10}
|
|
316
|
+
className="font-mono text-sm"
|
|
317
|
+
disabled={isPending}
|
|
318
|
+
/>
|
|
319
|
+
<p className="text-xs text-muted-foreground">
|
|
320
|
+
Array de definições no formato OpenAI Function Calling.
|
|
321
|
+
</p>
|
|
322
|
+
{form.jsonError && (
|
|
323
|
+
<p className="text-sm text-destructive">JSON inválido</p>
|
|
324
|
+
)}
|
|
325
|
+
</div>
|
|
324
326
|
</div>
|
|
325
327
|
|
|
326
|
-
<
|
|
328
|
+
<SheetFooter className="flex-row justify-end border-t">
|
|
327
329
|
<Button
|
|
328
330
|
type="button"
|
|
329
331
|
variant="outline"
|
|
@@ -338,9 +340,9 @@ export function ToolFormDialog({
|
|
|
338
340
|
) : null}
|
|
339
341
|
{isEditing ? "Salvar" : "Criar"}
|
|
340
342
|
</Button>
|
|
341
|
-
</
|
|
343
|
+
</SheetFooter>
|
|
342
344
|
</form>
|
|
343
|
-
</
|
|
344
|
-
</
|
|
345
|
+
</SheetContent>
|
|
346
|
+
</Sheet>
|
|
345
347
|
);
|
|
346
348
|
}
|