@greatapps/greatagents-ui 0.3.12 → 0.3.14
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 +50 -68
- package/dist/index.js +1956 -2315
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/agents/agent-tabs.tsx +41 -104
- package/src/components/capabilities/capabilities-tab.tsx +2 -2
- package/src/components/capabilities/integration-card.tsx +3 -21
- package/src/components/capabilities/integrations-tab.tsx +112 -68
- package/src/components/tools/tool-credentials-form.tsx +1 -374
- package/src/pages/agent-capabilities-page.tsx +2 -83
- package/src/pages/credentials-page.tsx +0 -10
- package/src/pages/integrations-management-page.tsx +129 -31
package/package.json
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { useState, useCallback } from "react";
|
|
2
1
|
import type { Agent } from "../../types";
|
|
3
2
|
import type { GagentsHookConfig } from "../../hooks/types";
|
|
4
|
-
import type { IntegrationCardData } from "../../hooks/use-integrations";
|
|
5
|
-
import type { WizardIntegrationMeta } from "../capabilities/types";
|
|
6
|
-
import type { ConfigOption } from "../capabilities/wizard-steps/config-step";
|
|
7
3
|
import { AgentObjectivesList } from "./agent-objectives-list";
|
|
8
4
|
import { AgentPromptEditor } from "./agent-prompt-editor";
|
|
9
5
|
import { AgentConversationsPanel } from "../conversations/agent-conversations-panel";
|
|
10
6
|
import { CapabilitiesTab } from "../capabilities/capabilities-tab";
|
|
11
7
|
import { IntegrationsTab } from "../capabilities/integrations-tab";
|
|
12
|
-
import { IntegrationWizard } from "../capabilities/integration-wizard";
|
|
13
8
|
import {
|
|
14
9
|
Tabs,
|
|
15
10
|
TabsList,
|
|
@@ -22,119 +17,61 @@ interface AgentTabsProps {
|
|
|
22
17
|
agent: Agent;
|
|
23
18
|
config: GagentsHookConfig;
|
|
24
19
|
renderChatLink?: (inboxId: number) => React.ReactNode;
|
|
25
|
-
gagentsApiUrl?: string;
|
|
26
|
-
resolveWizardMeta?: (card: IntegrationCardData) => WizardIntegrationMeta;
|
|
27
|
-
loadConfigOptions?: (credentialId: number) => Promise<ConfigOption[]>;
|
|
28
|
-
onWizardComplete?: () => void;
|
|
29
20
|
}
|
|
30
21
|
|
|
31
22
|
export function AgentTabs({
|
|
32
23
|
agent,
|
|
33
24
|
config,
|
|
34
25
|
renderChatLink,
|
|
35
|
-
gagentsApiUrl,
|
|
36
|
-
resolveWizardMeta,
|
|
37
|
-
loadConfigOptions,
|
|
38
|
-
onWizardComplete,
|
|
39
26
|
}: AgentTabsProps) {
|
|
40
|
-
const apiUrl = gagentsApiUrl || config.baseUrl;
|
|
41
|
-
|
|
42
|
-
// Wizard state for Integrações tab
|
|
43
|
-
const [wizardOpen, setWizardOpen] = useState(false);
|
|
44
|
-
const [activeCard, setActiveCard] = useState<IntegrationCardData | null>(null);
|
|
45
|
-
|
|
46
|
-
const handleConnect = useCallback((card: IntegrationCardData) => {
|
|
47
|
-
setActiveCard(card);
|
|
48
|
-
setWizardOpen(true);
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
const handleWizardClose = useCallback((open: boolean) => {
|
|
52
|
-
if (!open) {
|
|
53
|
-
setActiveCard(null);
|
|
54
|
-
}
|
|
55
|
-
setWizardOpen(open);
|
|
56
|
-
}, []);
|
|
57
|
-
|
|
58
|
-
const handleWizardComplete = useCallback(() => {
|
|
59
|
-
setWizardOpen(false);
|
|
60
|
-
setActiveCard(null);
|
|
61
|
-
onWizardComplete?.();
|
|
62
|
-
}, [onWizardComplete]);
|
|
63
|
-
|
|
64
|
-
// Resolve wizard meta with sensible defaults
|
|
65
|
-
const wizardMeta: WizardIntegrationMeta | null = activeCard
|
|
66
|
-
? (resolveWizardMeta?.(activeCard) ?? {
|
|
67
|
-
capabilities: [],
|
|
68
|
-
requirements: [],
|
|
69
|
-
hasConfigStep: false,
|
|
70
|
-
})
|
|
71
|
-
: null;
|
|
72
|
-
|
|
73
27
|
return (
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
<
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</TabsList>
|
|
98
|
-
|
|
99
|
-
<TabsContent value="prompt" className="mt-4">
|
|
100
|
-
<AgentPromptEditor agent={agent} config={config} />
|
|
101
|
-
</TabsContent>
|
|
28
|
+
<Tabs defaultValue="prompt">
|
|
29
|
+
<TabsList>
|
|
30
|
+
<TabsTrigger value="prompt" className="flex items-center gap-1.5">
|
|
31
|
+
<FileText aria-hidden="true" className="h-3.5 w-3.5" />
|
|
32
|
+
Prompt
|
|
33
|
+
</TabsTrigger>
|
|
34
|
+
<TabsTrigger value="objetivos" className="flex items-center gap-1.5">
|
|
35
|
+
<Target aria-hidden="true" className="h-3.5 w-3.5" />
|
|
36
|
+
Objetivos
|
|
37
|
+
</TabsTrigger>
|
|
38
|
+
<TabsTrigger value="capacidades" className="flex items-center gap-1.5">
|
|
39
|
+
<Blocks aria-hidden="true" className="h-3.5 w-3.5" />
|
|
40
|
+
Capacidades
|
|
41
|
+
</TabsTrigger>
|
|
42
|
+
<TabsTrigger value="integracoes" className="flex items-center gap-1.5">
|
|
43
|
+
<Plug aria-hidden="true" className="h-3.5 w-3.5" />
|
|
44
|
+
Integrações
|
|
45
|
+
</TabsTrigger>
|
|
46
|
+
<TabsTrigger value="conversas" className="flex items-center gap-1.5">
|
|
47
|
+
<MessageCircle aria-hidden="true" className="h-3.5 w-3.5" />
|
|
48
|
+
Conversas
|
|
49
|
+
</TabsTrigger>
|
|
50
|
+
</TabsList>
|
|
102
51
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
52
|
+
<TabsContent value="prompt" className="mt-4">
|
|
53
|
+
<AgentPromptEditor agent={agent} config={config} />
|
|
54
|
+
</TabsContent>
|
|
106
55
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
56
|
+
<TabsContent value="objetivos" className="mt-4">
|
|
57
|
+
<AgentObjectivesList agent={agent} config={config} />
|
|
58
|
+
</TabsContent>
|
|
110
59
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
60
|
+
<TabsContent value="capacidades" className="mt-4">
|
|
61
|
+
<CapabilitiesTab config={config} agentId={agent.id} />
|
|
62
|
+
</TabsContent>
|
|
114
63
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
config={config}
|
|
119
|
-
renderChatLink={renderChatLink}
|
|
120
|
-
/>
|
|
121
|
-
</TabsContent>
|
|
122
|
-
</Tabs>
|
|
64
|
+
<TabsContent value="integracoes" className="mt-4">
|
|
65
|
+
<IntegrationsTab config={config} agentId={agent.id} />
|
|
66
|
+
</TabsContent>
|
|
123
67
|
|
|
124
|
-
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
onOpenChange={handleWizardClose}
|
|
128
|
-
integration={activeCard.definition}
|
|
129
|
-
meta={wizardMeta}
|
|
130
|
-
agentId={agent.id}
|
|
68
|
+
<TabsContent value="conversas" className="mt-4">
|
|
69
|
+
<AgentConversationsPanel
|
|
70
|
+
agent={agent}
|
|
131
71
|
config={config}
|
|
132
|
-
|
|
133
|
-
existingCredentialId={activeCard.credentialId}
|
|
134
|
-
onComplete={handleWizardComplete}
|
|
135
|
-
loadConfigOptions={loadConfigOptions}
|
|
72
|
+
renderChatLink={renderChatLink}
|
|
136
73
|
/>
|
|
137
|
-
|
|
138
|
-
|
|
74
|
+
</TabsContent>
|
|
75
|
+
</Tabs>
|
|
139
76
|
);
|
|
140
77
|
}
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
Skeleton,
|
|
26
26
|
} from "@greatapps/greatauth-ui/ui";
|
|
27
27
|
import {
|
|
28
|
-
|
|
28
|
+
CalendarCheck,
|
|
29
29
|
Users,
|
|
30
30
|
Settings,
|
|
31
31
|
HeartHandshake,
|
|
@@ -55,7 +55,7 @@ function getOperationLabel(slug: string): string {
|
|
|
55
55
|
// ---------------------------------------------------------------------------
|
|
56
56
|
|
|
57
57
|
const CATEGORY_ICONS: Record<string, React.ElementType> = {
|
|
58
|
-
agenda:
|
|
58
|
+
agenda: CalendarCheck,
|
|
59
59
|
cadastros: Users,
|
|
60
60
|
infraestrutura: Settings,
|
|
61
61
|
relacionamentos: HeartHandshake,
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import type { IntegrationCardData, IntegrationCardState } from "../../hooks/use-integrations";
|
|
4
|
-
import { Badge, Button
|
|
4
|
+
import { Badge, Button } from "@greatapps/greatauth-ui/ui";
|
|
5
5
|
import {
|
|
6
6
|
CalendarSync,
|
|
7
7
|
Plug,
|
|
8
8
|
Settings,
|
|
9
9
|
RefreshCw,
|
|
10
|
-
Users,
|
|
11
10
|
Clock,
|
|
12
11
|
Plus,
|
|
13
12
|
} from "lucide-react";
|
|
@@ -23,7 +22,6 @@ const ICON_MAP: Record<string, LucideIcon> = {
|
|
|
23
22
|
Plug,
|
|
24
23
|
Settings,
|
|
25
24
|
RefreshCw,
|
|
26
|
-
Users,
|
|
27
25
|
Clock,
|
|
28
26
|
Plus,
|
|
29
27
|
};
|
|
@@ -84,7 +82,7 @@ export interface IntegrationCardProps {
|
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
export function IntegrationCard({ card, onConnect }: IntegrationCardProps) {
|
|
87
|
-
const { definition, state,
|
|
85
|
+
const { definition, state, isAddNew, accountLabel } = card;
|
|
88
86
|
const Icon = resolveIcon(definition.icon);
|
|
89
87
|
const isComingSoon = state === "coming_soon";
|
|
90
88
|
const actionLabel = getActionLabel(card);
|
|
@@ -195,23 +193,7 @@ export function IntegrationCard({ card, onConnect }: IntegrationCardProps) {
|
|
|
195
193
|
</div>
|
|
196
194
|
|
|
197
195
|
{/* Footer */}
|
|
198
|
-
<div className="mt-auto flex items-center justify-
|
|
199
|
-
{sharedByAgentsCount > 0 ? (
|
|
200
|
-
<Tooltip>
|
|
201
|
-
<TooltipTrigger asChild>
|
|
202
|
-
<span className="inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400">
|
|
203
|
-
<Users className="h-3.5 w-3.5" />
|
|
204
|
-
Compartilhada
|
|
205
|
-
</span>
|
|
206
|
-
</TooltipTrigger>
|
|
207
|
-
<TooltipContent>
|
|
208
|
-
Esta credencial está disponível para todos os agentes da conta
|
|
209
|
-
</TooltipContent>
|
|
210
|
-
</Tooltip>
|
|
211
|
-
) : (
|
|
212
|
-
<span />
|
|
213
|
-
)}
|
|
214
|
-
|
|
196
|
+
<div className="mt-auto flex items-center justify-end gap-2 pt-1">
|
|
215
197
|
{!isComingSoon && (
|
|
216
198
|
<Button
|
|
217
199
|
variant={state === "expired" ? "destructive" : "outline"}
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { useCallback } from "react";
|
|
3
4
|
import type { GagentsHookConfig } from "../../hooks/types";
|
|
4
|
-
import { useIntegrationState
|
|
5
|
-
import {
|
|
5
|
+
import { useIntegrationState } from "../../hooks/use-integrations";
|
|
6
|
+
import { useAgentTools, useAddAgentTool, useRemoveAgentTool } from "../../hooks/use-agent-tools";
|
|
7
|
+
import { Switch, Tooltip, TooltipContent, TooltipTrigger } from "@greatapps/greatauth-ui/ui";
|
|
6
8
|
import { Plug, Loader2 } from "lucide-react";
|
|
9
|
+
import type { LucideIcon } from "lucide-react";
|
|
10
|
+
import { CalendarSync } from "lucide-react";
|
|
11
|
+
import { cn } from "../../lib";
|
|
7
12
|
|
|
8
13
|
// ---------------------------------------------------------------------------
|
|
9
|
-
//
|
|
14
|
+
// Icon mapping
|
|
10
15
|
// ---------------------------------------------------------------------------
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const ICON_MAP: Record<string, LucideIcon> = {
|
|
18
|
+
CalendarSync,
|
|
19
|
+
Plug,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function resolveIcon(name: string): LucideIcon {
|
|
23
|
+
return ICON_MAP[name] ?? Plug;
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
// ---------------------------------------------------------------------------
|
|
21
|
-
//
|
|
27
|
+
// Props
|
|
22
28
|
// ---------------------------------------------------------------------------
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
if (card.isAddNew) {
|
|
29
|
-
return `${card.definition.slug}-add-new`;
|
|
30
|
-
}
|
|
31
|
-
return card.definition.slug;
|
|
30
|
+
export interface IntegrationsTabProps {
|
|
31
|
+
config: GagentsHookConfig;
|
|
32
|
+
agentId: number;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
// ---------------------------------------------------------------------------
|
|
@@ -38,12 +39,40 @@ function getCardKey(card: IntegrationCardData): string {
|
|
|
38
39
|
export function IntegrationsTab({
|
|
39
40
|
config,
|
|
40
41
|
agentId,
|
|
41
|
-
onConnect,
|
|
42
42
|
}: IntegrationsTabProps) {
|
|
43
43
|
const { cards, isLoading } = useIntegrationState(config, agentId);
|
|
44
|
+
const { data: agentToolsData, isLoading: agentToolsLoading } = useAgentTools(config, agentId);
|
|
45
|
+
const addAgentTool = useAddAgentTool(config);
|
|
46
|
+
const removeAgentTool = useRemoveAgentTool(config);
|
|
47
|
+
|
|
48
|
+
const agentTools = agentToolsData?.data ?? [];
|
|
49
|
+
|
|
50
|
+
// Only show connected credentials (account-level)
|
|
51
|
+
const connectedCards = cards.filter(
|
|
52
|
+
(c) => !c.isAddNew && (c.state === "connected" || c.state === "expired"),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const handleToggle = useCallback(
|
|
56
|
+
(toolId: number, checked: boolean) => {
|
|
57
|
+
if (checked) {
|
|
58
|
+
// Add agent_tool linking this agent to this tool
|
|
59
|
+
addAgentTool.mutate({
|
|
60
|
+
idAgent: agentId,
|
|
61
|
+
body: { id_tool: toolId, enabled: true },
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
// Find the agent_tool to remove
|
|
65
|
+
const agentTool = agentTools.find((at) => at.id_tool === toolId);
|
|
66
|
+
if (agentTool) {
|
|
67
|
+
removeAgentTool.mutate({ idAgent: agentId, id: agentTool.id });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
[agentTools, agentId, addAgentTool, removeAgentTool],
|
|
72
|
+
);
|
|
44
73
|
|
|
45
74
|
// Loading state
|
|
46
|
-
if (isLoading) {
|
|
75
|
+
if (isLoading || agentToolsLoading) {
|
|
47
76
|
return (
|
|
48
77
|
<div className="flex items-center justify-center py-16">
|
|
49
78
|
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
|
@@ -51,63 +80,78 @@ export function IntegrationsTab({
|
|
|
51
80
|
);
|
|
52
81
|
}
|
|
53
82
|
|
|
54
|
-
// Empty state
|
|
55
|
-
if (
|
|
83
|
+
// Empty state — no integrations connected at account level
|
|
84
|
+
if (connectedCards.length === 0) {
|
|
56
85
|
return (
|
|
57
86
|
<div className="flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground">
|
|
58
87
|
<Plug className="h-10 w-10" />
|
|
59
|
-
<p className="text-sm">Nenhuma integração
|
|
88
|
+
<p className="text-sm font-medium">Nenhuma integração conectada</p>
|
|
89
|
+
<p className="text-xs text-center max-w-sm">
|
|
90
|
+
Conecte integrações na página de Integrações da conta para que possam
|
|
91
|
+
ser ativadas neste agente.
|
|
92
|
+
</p>
|
|
60
93
|
</div>
|
|
61
94
|
);
|
|
62
95
|
}
|
|
63
96
|
|
|
64
|
-
// Split into connected/expired cards and add-new/coming-soon cards
|
|
65
|
-
const connectedCards = cards.filter(
|
|
66
|
-
(c) => !c.isAddNew && (c.state === "connected" || c.state === "expired"),
|
|
67
|
-
);
|
|
68
|
-
const otherCards = cards.filter(
|
|
69
|
-
(c) => c.isAddNew || c.state === "coming_soon",
|
|
70
|
-
);
|
|
71
|
-
|
|
72
97
|
return (
|
|
73
|
-
<div className="space-y-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
<div className="space-y-4">
|
|
99
|
+
<p className="text-xs text-muted-foreground">
|
|
100
|
+
Ative ou desative as integrações conectadas na conta para este agente.
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
104
|
+
{connectedCards.map((card) => {
|
|
105
|
+
const Icon = resolveIcon(card.definition.icon);
|
|
106
|
+
const isLinked = card.linkedToAgent;
|
|
107
|
+
const isMutating = addAgentTool.isPending || removeAgentTool.isPending;
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div
|
|
111
|
+
key={`${card.definition.slug}-cred-${card.credentialId}`}
|
|
112
|
+
className={cn(
|
|
113
|
+
"flex items-center gap-3 rounded-xl border bg-card p-4 transition-shadow",
|
|
114
|
+
isLinked ? "border-primary/30 shadow-sm" : "opacity-75",
|
|
115
|
+
)}
|
|
116
|
+
>
|
|
117
|
+
{/* Icon */}
|
|
118
|
+
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
|
119
|
+
<Icon className="h-4.5 w-4.5" />
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
{/* Info */}
|
|
123
|
+
<div className="flex-1 min-w-0">
|
|
124
|
+
<h4 className="text-sm font-medium leading-tight truncate">
|
|
125
|
+
{card.definition.name}
|
|
126
|
+
</h4>
|
|
127
|
+
{card.accountLabel && (
|
|
128
|
+
<Tooltip>
|
|
129
|
+
<TooltipTrigger asChild>
|
|
130
|
+
<p className="text-xs text-muted-foreground truncate" title={card.accountLabel}>
|
|
131
|
+
{card.accountLabel}
|
|
132
|
+
</p>
|
|
133
|
+
</TooltipTrigger>
|
|
134
|
+
<TooltipContent>{card.accountLabel}</TooltipContent>
|
|
135
|
+
</Tooltip>
|
|
136
|
+
)}
|
|
137
|
+
{card.state === "expired" && (
|
|
138
|
+
<p className="text-xs text-amber-600 dark:text-amber-400">Expirado</p>
|
|
139
|
+
)}
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
{/* Toggle */}
|
|
143
|
+
<Switch
|
|
144
|
+
checked={isLinked}
|
|
145
|
+
disabled={isMutating || !card.tool}
|
|
146
|
+
onCheckedChange={(checked) =>
|
|
147
|
+
card.tool && handleToggle(card.tool.id, checked)
|
|
148
|
+
}
|
|
149
|
+
aria-label={`${isLinked ? "Desativar" : "Ativar"} ${card.definition.name} para este agente`}
|
|
106
150
|
/>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
})}
|
|
154
|
+
</div>
|
|
111
155
|
</div>
|
|
112
156
|
);
|
|
113
157
|
}
|