@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/greatagents-ui",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Shared agents UI components for Great platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -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, AlertTriangle } from "lucide-react";
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(version: PromptVersion) {
147
- if (isLegacyVersion(version)) {
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
- Dialog,
31
- DialogContent,
32
- DialogHeader,
33
- DialogTitle,
34
- DialogFooter,
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 dialog for custom_instructions */}
295
- <Dialog
294
+ {/* Config sheet for custom_instructions */}
295
+ <Sheet
296
296
  open={!!configTarget}
297
297
  onOpenChange={(open) => !open && setConfigTarget(null)}
298
298
  >
299
- <DialogContent className="sm:max-w-lg">
300
- <DialogHeader>
301
- <DialogTitle>
299
+ <SheetContent className="sm:max-w-lg">
300
+ <SheetHeader>
301
+ <SheetTitle>
302
302
  Instruções da Ferramenta
303
- </DialogTitle>
304
- </DialogHeader>
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
- <DialogFooter>
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
- </DialogFooter>
361
- </DialogContent>
362
- </Dialog>
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
- Dialog,
7
- DialogContent,
8
- DialogHeader,
9
- DialogTitle,
10
- DialogFooter,
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
- <Dialog open={open} onOpenChange={onOpenChange}>
181
- <DialogContent className="sm:max-w-lg">
182
- <DialogHeader>
183
- <DialogTitle>
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
- </DialogTitle>
186
- </DialogHeader>
187
- <form onSubmit={handleSubmit} className="space-y-4">
188
- <div className="space-y-2">
189
- <Label htmlFor="tool-name">Nome *</Label>
190
- <Input
191
- id="tool-name"
192
- name="name"
193
- value={form.name}
194
- onChange={(e) => {
195
- const name = e.target.value;
196
- setForm((prev) => ({
197
- ...prev,
198
- name,
199
- nameError: name.trim() ? false : prev.nameError,
200
- ...(!slugManuallyEdited && !isEditing
201
- ? { slug: slugify(name), slugError: false }
202
- : {}),
203
- }));
204
- }}
205
- placeholder="Ex: Google Calendar"
206
- disabled={isPending}
207
- />
208
- {form.nameError && (
209
- <p className="text-sm text-destructive">Nome é obrigatório</p>
210
- )}
211
- </div>
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
- <div className="space-y-2">
214
- <Label htmlFor="tool-slug">Slug (identificador único) *</Label>
215
- <Input
216
- id="tool-slug"
217
- name="slug"
218
- value={form.slug}
219
- onChange={(e) => {
220
- setSlugManuallyEdited(true);
221
- setForm((prev) => ({
222
- ...prev,
223
- slug: e.target.value,
224
- slugError: e.target.value.trim() ? false : prev.slugError,
225
- }));
226
- }}
227
- placeholder="Ex: google-calendar"
228
- disabled={isPending}
229
- />
230
- <p className="text-xs text-muted-foreground">
231
- Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta.
232
- </p>
233
- {form.slugError && (
234
- <p className="text-sm text-destructive">Slug é obrigatório</p>
235
- )}
236
- </div>
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
- <div className="space-y-2">
239
- <Label htmlFor="tool-type">Tipo de Autenticação *</Label>
240
- <Select
241
- value={form.type}
242
- onValueChange={(value) => {
243
- setForm((prev) => ({
244
- ...prev,
245
- type: value,
246
- typeError: false,
247
- }));
248
- }}
249
- disabled={isPending}
250
- >
251
- <SelectTrigger id="tool-type">
252
- <SelectValue placeholder="Selecione o tipo" />
253
- </SelectTrigger>
254
- <SelectContent>
255
- {TOOL_AUTH_TYPES.map((t) => (
256
- <SelectItem key={t.value} value={t.value}>
257
- {t.label}
258
- </SelectItem>
259
- ))}
260
- </SelectContent>
261
- </Select>
262
- <p className="text-xs text-muted-foreground">
263
- Define se a ferramenta requer credenciais para funcionar.
264
- </p>
265
- {form.typeError && (
266
- <p className="text-sm text-destructive">Tipo é obrigatório</p>
267
- )}
268
- </div>
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
- <div className="space-y-2">
271
- <Label htmlFor="tool-description">Descrição</Label>
272
- <Textarea
273
- id="tool-description"
274
- name="description"
275
- value={form.description}
276
- onChange={(e) =>
277
- setForm((prev) => ({ ...prev, description: e.target.value }))
278
- }
279
- placeholder="Descri\u00e7\u00e3o da ferramenta\u2026"
280
- rows={3}
281
- disabled={isPending}
282
- />
283
- </div>
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
- <div className="space-y-2">
286
- <Label htmlFor="tool-function-defs">
287
- Definições de Função (JSON)
288
- </Label>
289
- <Textarea
290
- id="tool-function-defs"
291
- name="functionDefs"
292
- value={form.functionDefinitions}
293
- onChange={(e) => {
294
- setForm((prev) => ({
295
- ...prev,
296
- functionDefinitions: e.target.value,
297
- jsonError: false,
298
- }));
299
- }}
300
- placeholder={`[
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
- rows={10}
315
- className="font-mono text-sm"
316
- disabled={isPending}
317
- />
318
- <p className="text-xs text-muted-foreground">
319
- Array de definições no formato OpenAI Function Calling.
320
- </p>
321
- {form.jsonError && (
322
- <p className="text-sm text-destructive">JSON inválido</p>
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
- <DialogFooter>
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
- </DialogFooter>
343
+ </SheetFooter>
342
344
  </form>
343
- </DialogContent>
344
- </Dialog>
345
+ </SheetContent>
346
+ </Sheet>
345
347
  );
346
348
  }