@greatapps/greatagents-ui 0.3.25 → 0.3.27
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 +13 -1
- package/dist/index.js +143 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +20 -0
- package/src/components/agents/agent-revision-tab.tsx +3 -62
- package/src/hooks/index.ts +1 -1
- package/src/hooks/use-agents.ts +20 -0
- package/src/pages/agent-detail-page.tsx +90 -12
package/package.json
CHANGED
package/src/client/index.ts
CHANGED
|
@@ -250,6 +250,26 @@ export function createGagentsClient(config: GagentsClientConfig) {
|
|
|
250
250
|
{ provider },
|
|
251
251
|
),
|
|
252
252
|
|
|
253
|
+
// --- Publish ---
|
|
254
|
+
publishAgent: async (
|
|
255
|
+
idAccount: number,
|
|
256
|
+
agentId: number,
|
|
257
|
+
changeNotes?: string,
|
|
258
|
+
): Promise<ApiResponse<{ version: number }>> => {
|
|
259
|
+
const url = buildUrl(idAccount, `agents/${agentId}/publish`);
|
|
260
|
+
const res = await fetch(url, {
|
|
261
|
+
method: "POST",
|
|
262
|
+
headers: {
|
|
263
|
+
Authorization: `Bearer ${token}`,
|
|
264
|
+
"Content-Type": "application/json",
|
|
265
|
+
},
|
|
266
|
+
body: JSON.stringify({ change_notes: changeNotes || "" }),
|
|
267
|
+
});
|
|
268
|
+
const json = (await res.json()) as ApiResponse<{ version: number }>;
|
|
269
|
+
if (json.status === 0 && !res.ok) throw new Error(json.message || "Erro ao publicar");
|
|
270
|
+
return json;
|
|
271
|
+
},
|
|
272
|
+
|
|
253
273
|
// --- Capabilities ---
|
|
254
274
|
getCapabilities: (idAccount: number) =>
|
|
255
275
|
request<CapabilitiesResponse>("GET", idAccount, "capabilities"),
|
|
@@ -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
|
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export { type GagentsHookConfig, useGagentsClient } from "./types";
|
|
3
3
|
|
|
4
4
|
// Agents
|
|
5
|
-
export { useAgents, useAgent, useCreateAgent, useUpdateAgent, useDeleteAgent } from "./use-agents";
|
|
5
|
+
export { useAgents, useAgent, useCreateAgent, useUpdateAgent, usePublishAgent, useDeleteAgent } from "./use-agents";
|
|
6
6
|
|
|
7
7
|
// Tools
|
|
8
8
|
export { useTools, useTool, useCreateTool, useUpdateTool, useDeleteTool } from "./use-tools";
|
package/src/hooks/use-agents.ts
CHANGED
|
@@ -81,6 +81,26 @@ export function useUpdateAgent(config: GagentsHookConfig) {
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
export function usePublishAgent(config: GagentsHookConfig) {
|
|
85
|
+
const queryClient = useQueryClient();
|
|
86
|
+
const client = useGagentsClient(config);
|
|
87
|
+
|
|
88
|
+
return useMutation({
|
|
89
|
+
mutationFn: async (variables: { id: number; changeNotes?: string }) => {
|
|
90
|
+
return client.publishAgent(Number(config.accountId), variables.id, variables.changeNotes);
|
|
91
|
+
},
|
|
92
|
+
onSuccess: (_data, variables) => {
|
|
93
|
+
queryClient.invalidateQueries({ queryKey: ["greatagents", "agents"] });
|
|
94
|
+
queryClient.invalidateQueries({
|
|
95
|
+
queryKey: ["greatagents", "agent", config.accountId, variables.id],
|
|
96
|
+
});
|
|
97
|
+
queryClient.invalidateQueries({
|
|
98
|
+
queryKey: ["greatagents", "prompt-versions", config.accountId, variables.id],
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
84
104
|
export function useDeleteAgent(config: GagentsHookConfig) {
|
|
85
105
|
const client = useGagentsClient(config);
|
|
86
106
|
const queryClient = useQueryClient();
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { useAgent } from "../hooks";
|
|
2
|
+
import { useAgent, usePublishAgent } from "../hooks";
|
|
3
3
|
import { AgentTabs } from "../components/agents/agent-tabs";
|
|
4
4
|
import { AgentEditForm } from "../components/agents/agent-edit-form";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AlertDialog,
|
|
7
|
+
AlertDialogAction,
|
|
8
|
+
AlertDialogCancel,
|
|
9
|
+
AlertDialogContent,
|
|
10
|
+
AlertDialogDescription,
|
|
11
|
+
AlertDialogFooter,
|
|
12
|
+
AlertDialogHeader,
|
|
13
|
+
AlertDialogTitle,
|
|
14
|
+
Badge,
|
|
15
|
+
Button,
|
|
16
|
+
Input,
|
|
17
|
+
Skeleton,
|
|
18
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
6
19
|
import { EntityAvatar } from "@greatapps/greatauth-ui";
|
|
7
|
-
import { ArrowLeft, Pencil } from "lucide-react";
|
|
20
|
+
import { ArrowLeft, Loader2, Pencil, Upload } from "lucide-react";
|
|
21
|
+
import { toast } from "sonner";
|
|
8
22
|
import type { GagentsHookConfig } from "../hooks/types";
|
|
9
23
|
|
|
10
24
|
export interface AgentDetailPageProps {
|
|
@@ -21,7 +35,26 @@ export function AgentDetailPage({
|
|
|
21
35
|
renderChatLink,
|
|
22
36
|
}: AgentDetailPageProps) {
|
|
23
37
|
const { data: agent, isLoading } = useAgent(config, agentId);
|
|
38
|
+
const publishAgent = usePublishAgent(config);
|
|
24
39
|
const [editOpen, setEditOpen] = useState(false);
|
|
40
|
+
const [publishOpen, setPublishOpen] = useState(false);
|
|
41
|
+
const [publishNotes, setPublishNotes] = useState("");
|
|
42
|
+
|
|
43
|
+
async function handlePublish() {
|
|
44
|
+
if (!agent) return;
|
|
45
|
+
try {
|
|
46
|
+
const result = await publishAgent.mutateAsync({ id: agent.id, changeNotes: publishNotes.trim() });
|
|
47
|
+
setPublishOpen(false);
|
|
48
|
+
setPublishNotes("");
|
|
49
|
+
if (result.message?.includes("Sem alterações")) {
|
|
50
|
+
toast.info(result.message);
|
|
51
|
+
} else {
|
|
52
|
+
toast.success(result.message || "Agente publicado");
|
|
53
|
+
}
|
|
54
|
+
} catch (err) {
|
|
55
|
+
toast.error(err instanceof Error ? err.message : "Erro ao publicar agente");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
25
58
|
|
|
26
59
|
if (isLoading) {
|
|
27
60
|
return (
|
|
@@ -80,15 +113,29 @@ export function AgentDetailPage({
|
|
|
80
113
|
</div>
|
|
81
114
|
</div>
|
|
82
115
|
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
116
|
+
<div className="flex gap-2 shrink-0 self-start">
|
|
117
|
+
<Button
|
|
118
|
+
variant="default"
|
|
119
|
+
size="sm"
|
|
120
|
+
onClick={() => setPublishOpen(true)}
|
|
121
|
+
disabled={publishAgent.isPending}
|
|
122
|
+
>
|
|
123
|
+
{publishAgent.isPending ? (
|
|
124
|
+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
125
|
+
) : (
|
|
126
|
+
<Upload className="mr-2 h-4 w-4" />
|
|
127
|
+
)}
|
|
128
|
+
Publicar
|
|
129
|
+
</Button>
|
|
130
|
+
<Button
|
|
131
|
+
variant="outline"
|
|
132
|
+
size="sm"
|
|
133
|
+
onClick={() => setEditOpen(true)}
|
|
134
|
+
>
|
|
135
|
+
<Pencil className="mr-2 h-4 w-4" />
|
|
136
|
+
Editar
|
|
137
|
+
</Button>
|
|
138
|
+
</div>
|
|
92
139
|
</div>
|
|
93
140
|
</div>
|
|
94
141
|
|
|
@@ -107,6 +154,37 @@ export function AgentDetailPage({
|
|
|
107
154
|
onOpenChange={setEditOpen}
|
|
108
155
|
/>
|
|
109
156
|
)}
|
|
157
|
+
|
|
158
|
+
<AlertDialog open={publishOpen} onOpenChange={setPublishOpen}>
|
|
159
|
+
<AlertDialogContent>
|
|
160
|
+
<AlertDialogHeader>
|
|
161
|
+
<AlertDialogTitle>Publicar nova versão do agente?</AlertDialogTitle>
|
|
162
|
+
<AlertDialogDescription>
|
|
163
|
+
O prompt será actualizado com todas as configurações actuais e uma nova versão será criada.
|
|
164
|
+
</AlertDialogDescription>
|
|
165
|
+
</AlertDialogHeader>
|
|
166
|
+
<div className="py-2">
|
|
167
|
+
<Input
|
|
168
|
+
value={publishNotes}
|
|
169
|
+
onChange={(e) => setPublishNotes(e.target.value)}
|
|
170
|
+
placeholder="O que mudou? (opcional)"
|
|
171
|
+
onKeyDown={(e) => {
|
|
172
|
+
if (e.key === "Enter") {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
handlePublish();
|
|
175
|
+
}
|
|
176
|
+
}}
|
|
177
|
+
/>
|
|
178
|
+
</div>
|
|
179
|
+
<AlertDialogFooter>
|
|
180
|
+
<AlertDialogCancel onClick={() => { setPublishNotes(""); }}>Cancelar</AlertDialogCancel>
|
|
181
|
+
<AlertDialogAction onClick={handlePublish} disabled={publishAgent.isPending}>
|
|
182
|
+
{publishAgent.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
|
183
|
+
Publicar
|
|
184
|
+
</AlertDialogAction>
|
|
185
|
+
</AlertDialogFooter>
|
|
186
|
+
</AlertDialogContent>
|
|
187
|
+
</AlertDialog>
|
|
110
188
|
</div>
|
|
111
189
|
);
|
|
112
190
|
}
|