@greatapps/greatagents-ui 0.3.14 → 0.3.15

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.js CHANGED
@@ -1975,29 +1975,55 @@ function computeDiff(oldText, newText) {
1975
1975
  function buildPreview(promptText, objectives, agentTools, allTools) {
1976
1976
  let preview = promptText;
1977
1977
  const activeObjectives = objectives.filter((o) => o.active);
1978
- if (activeObjectives.length > 0) {
1979
- preview += "\n\n[SKILLS DISPON\xCDVEIS]\n";
1980
- for (const obj of activeObjectives) {
1981
- preview += `- ${obj.title}`;
1982
- if (obj.prompt) preview += `: ${obj.prompt}`;
1983
- preview += "\n";
1978
+ const enabledAgentTools = agentTools.filter((at) => at.enabled);
1979
+ const toolMap = new Map(allTools.map((t) => [t.id, t]));
1980
+ const capabilityTools = [];
1981
+ const integrationTools = [];
1982
+ for (const at of enabledAgentTools) {
1983
+ const tool = toolMap.get(at.id_tool);
1984
+ if (!tool) continue;
1985
+ if (tool.type === "integration") {
1986
+ integrationTools.push({ at, tool });
1987
+ } else {
1988
+ capabilityTools.push({ at, tool });
1984
1989
  }
1985
1990
  }
1986
- const enabledAgentTools = agentTools.filter((at) => at.enabled);
1987
- if (enabledAgentTools.length > 0) {
1988
- const toolMap = new Map(allTools.map((t) => [t.id, t]));
1989
- preview += "\n[TOOLS DISPON\xCDVEIS]\n";
1990
- for (const at of enabledAgentTools) {
1991
- const tool = toolMap.get(at.id_tool);
1992
- const name = tool?.name || `Tool #${at.id_tool}`;
1993
- const desc = tool?.description ? `: ${tool.description}` : "";
1994
- preview += `- ${name}${desc}`;
1995
- if (at.custom_instructions) {
1991
+ const hasContent = activeObjectives.length > 0 || capabilityTools.length > 0 || integrationTools.length > 0;
1992
+ if (hasContent) {
1993
+ preview += "\n\n[CAPACIDADES E INTEGRA\xC7\xD5ES]";
1994
+ if (activeObjectives.length > 0 || capabilityTools.length > 0) {
1995
+ preview += "\n\n## Capacidades Internas (GClinic)";
1996
+ for (const obj of activeObjectives) {
1996
1997
  preview += `
1997
- Instru\xE7\xF5es: ${at.custom_instructions}`;
1998
+
1999
+ ### ${obj.title} (${obj.slug})`;
2000
+ if (obj.prompt) preview += `
2001
+ ${obj.prompt}`;
2002
+ }
2003
+ for (const { at, tool } of capabilityTools) {
2004
+ preview += `
2005
+
2006
+ ### ${tool.name} (${tool.slug})`;
2007
+ if (tool.description) preview += `
2008
+ ${tool.description}`;
2009
+ if (at.custom_instructions) preview += `
2010
+ ${at.custom_instructions}`;
1998
2011
  }
1999
- preview += "\n";
2000
2012
  }
2013
+ if (integrationTools.length > 0) {
2014
+ preview += "\n\n## Integra\xE7\xF5es Externas";
2015
+ for (const { at, tool } of integrationTools) {
2016
+ preview += `
2017
+
2018
+ ### ${tool.name} (${tool.slug})`;
2019
+ if (at.custom_instructions) preview += `
2020
+ ${at.custom_instructions}`;
2021
+ }
2022
+ }
2023
+ preview += "\n\n## Regras";
2024
+ preview += "\n- Sempre confirme com o usu\xE1rio antes de criar ou alterar registros.";
2025
+ preview += "\n- Nunca invente dados \u2014 sempre consulte primeiro.";
2026
+ preview += "\n- Use EXATAMENTE os nomes de fun\xE7\xE3o listados acima.";
2001
2027
  }
2002
2028
  return preview;
2003
2029
  }
@@ -2160,11 +2186,14 @@ function AgentPromptEditor({ config, agent }) {
2160
2186
  }
2161
2187
  ),
2162
2188
  showPreview && /* @__PURE__ */ jsx6("div", { className: "border-t px-4 py-3", children: /* @__PURE__ */ jsx6("pre", { className: "max-h-96 overflow-auto whitespace-pre-wrap font-mono text-sm leading-relaxed", children: previewText.split("\n").map((line, i) => {
2163
- const isSection = line.startsWith("[SKILLS DISPON\xCDVEIS]") || line.startsWith("[TOOLS DISPON\xCDVEIS]");
2189
+ const isTopSection = line.startsWith("[CAPACIDADES E INTEGRA\xC7\xD5ES]");
2190
+ const isH2 = line.startsWith("## ");
2191
+ const isH3 = line.startsWith("### ");
2192
+ const cls = isTopSection ? "font-bold text-foreground" : isH2 ? "font-semibold text-muted-foreground" : isH3 ? "font-medium text-muted-foreground" : "";
2164
2193
  return /* @__PURE__ */ jsxs5(
2165
2194
  "span",
2166
2195
  {
2167
- className: isSection ? "font-semibold text-muted-foreground" : "",
2196
+ className: cls,
2168
2197
  children: [
2169
2198
  line,
2170
2199
  "\n"
@@ -2829,33 +2858,81 @@ var ICON_MAP = {
2829
2858
  function resolveIcon(name) {
2830
2859
  return ICON_MAP[name] ?? Plug;
2831
2860
  }
2861
+ var INTEGRATION_INSTRUCTIONS = {
2862
+ "google-calendar": `Voc\xEA tem acesso ao Google Calendar atrav\xE9s da integra\xE7\xE3o google-calendar.
2863
+ Fun\xE7\xF5es dispon\xEDveis:
2864
+ - google_calendar_setup_oauth: Configurar conex\xE3o OAuth
2865
+ - google_calendar_check_status: Verificar status da conex\xE3o
2866
+ - google_calendar_list_events: Listar eventos do calend\xE1rio
2867
+ - google_calendar_create_event: Criar novo evento
2868
+ - google_calendar_update_event: Atualizar evento existente
2869
+ - google_calendar_delete_event: Cancelar/remover evento
2870
+
2871
+ Use EXATAMENTE os nomes de fun\xE7\xE3o listados acima.`
2872
+ };
2832
2873
  function IntegrationsTab({
2833
2874
  config,
2834
2875
  agentId
2835
2876
  }) {
2836
2877
  const { cards, isLoading } = useIntegrationState(config, agentId);
2837
2878
  const { data: agentToolsData, isLoading: agentToolsLoading } = useAgentTools(config, agentId);
2879
+ const { data: toolsData } = useTools(config);
2838
2880
  const addAgentTool = useAddAgentTool(config);
2839
2881
  const removeAgentTool = useRemoveAgentTool(config);
2882
+ const createTool = useCreateTool(config);
2840
2883
  const agentTools = agentToolsData?.data ?? [];
2884
+ const allTools = toolsData?.data ?? [];
2841
2885
  const connectedCards = cards.filter(
2842
2886
  (c) => !c.isAddNew && (c.state === "connected" || c.state === "expired")
2843
2887
  );
2844
2888
  const handleToggle = useCallback5(
2845
- (toolId, checked) => {
2889
+ async (card, checked) => {
2846
2890
  if (checked) {
2891
+ let toolId = card.tool?.id;
2892
+ if (!toolId) {
2893
+ const existingTool = allTools.find((t) => t.slug === card.definition.slug);
2894
+ if (existingTool) {
2895
+ toolId = existingTool.id;
2896
+ } else {
2897
+ try {
2898
+ const result = await createTool.mutateAsync({
2899
+ name: card.definition.name,
2900
+ slug: card.definition.slug,
2901
+ type: "integration",
2902
+ description: card.definition.description
2903
+ });
2904
+ const d = result?.data;
2905
+ toolId = (Array.isArray(d) ? d[0]?.id : d?.id) ?? void 0;
2906
+ if (!toolId) {
2907
+ console.error("[IntegrationsTab] Failed to create tool \u2014 no ID returned");
2908
+ return;
2909
+ }
2910
+ } catch (err) {
2911
+ console.error("[IntegrationsTab] Error creating tool:", err);
2912
+ return;
2913
+ }
2914
+ }
2915
+ }
2916
+ const customInstructions = INTEGRATION_INSTRUCTIONS[card.definition.slug];
2847
2917
  addAgentTool.mutate({
2848
2918
  idAgent: agentId,
2849
- body: { id_tool: toolId, enabled: true }
2919
+ body: {
2920
+ id_tool: toolId,
2921
+ enabled: true,
2922
+ ...customInstructions ? { custom_instructions: customInstructions } : {}
2923
+ }
2850
2924
  });
2851
2925
  } else {
2852
- const agentTool = agentTools.find((at) => at.id_tool === toolId);
2853
- if (agentTool) {
2854
- removeAgentTool.mutate({ idAgent: agentId, id: agentTool.id });
2926
+ const toolId = card.tool?.id;
2927
+ if (toolId) {
2928
+ const agentTool = agentTools.find((at) => at.id_tool === toolId);
2929
+ if (agentTool) {
2930
+ removeAgentTool.mutate({ idAgent: agentId, id: agentTool.id });
2931
+ }
2855
2932
  }
2856
2933
  }
2857
2934
  },
2858
- [agentTools, agentId, addAgentTool, removeAgentTool]
2935
+ [agentTools, allTools, agentId, addAgentTool, removeAgentTool, createTool]
2859
2936
  );
2860
2937
  if (isLoading || agentToolsLoading) {
2861
2938
  return /* @__PURE__ */ jsx11("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx11(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
@@ -2872,7 +2949,7 @@ function IntegrationsTab({
2872
2949
  /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => {
2873
2950
  const Icon = resolveIcon(card.definition.icon);
2874
2951
  const isLinked = card.linkedToAgent;
2875
- const isMutating = addAgentTool.isPending || removeAgentTool.isPending;
2952
+ const isMutating = addAgentTool.isPending || removeAgentTool.isPending || createTool.isPending;
2876
2953
  return /* @__PURE__ */ jsxs9(
2877
2954
  "div",
2878
2955
  {
@@ -2894,8 +2971,8 @@ function IntegrationsTab({
2894
2971
  Switch5,
2895
2972
  {
2896
2973
  checked: isLinked,
2897
- disabled: isMutating || !card.tool,
2898
- onCheckedChange: (checked) => card.tool && handleToggle(card.tool.id, checked),
2974
+ disabled: isMutating,
2975
+ onCheckedChange: (checked) => handleToggle(card, checked),
2899
2976
  "aria-label": `${isLinked ? "Desativar" : "Ativar"} ${card.definition.name} para este agente`
2900
2977
  }
2901
2978
  )
@@ -3940,16 +4017,34 @@ function ToolCredentialsForm({
3940
4017
  }
3941
4018
 
3942
4019
  // src/components/capabilities/integration-card.tsx
3943
- import { Badge as Badge9, Button as Button12 } from "@greatapps/greatauth-ui/ui";
4020
+ import { useState as useState13 } from "react";
4021
+ import {
4022
+ Badge as Badge9,
4023
+ Button as Button12,
4024
+ DropdownMenu,
4025
+ DropdownMenuContent,
4026
+ DropdownMenuItem,
4027
+ DropdownMenuTrigger,
4028
+ AlertDialog as AlertDialog6,
4029
+ AlertDialogAction as AlertDialogAction6,
4030
+ AlertDialogCancel as AlertDialogCancel6,
4031
+ AlertDialogContent as AlertDialogContent6,
4032
+ AlertDialogDescription as AlertDialogDescription6,
4033
+ AlertDialogFooter as AlertDialogFooter6,
4034
+ AlertDialogHeader as AlertDialogHeader6,
4035
+ AlertDialogTitle as AlertDialogTitle6
4036
+ } from "@greatapps/greatauth-ui/ui";
3944
4037
  import {
3945
4038
  CalendarSync as CalendarSync2,
3946
4039
  Plug as Plug3,
3947
4040
  Settings as Settings3,
3948
4041
  RefreshCw,
3949
4042
  Clock,
3950
- Plus as Plus3
4043
+ Plus as Plus3,
4044
+ Unplug,
4045
+ Trash2 as Trash26
3951
4046
  } from "lucide-react";
3952
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4047
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3953
4048
  var ICON_MAP2 = {
3954
4049
  CalendarSync: CalendarSync2,
3955
4050
  Plug: Plug3,
@@ -3979,35 +4074,29 @@ var STATE_BADGES = {
3979
4074
  className: "bg-muted text-muted-foreground"
3980
4075
  }
3981
4076
  };
3982
- function getActionLabel(card) {
3983
- if (card.isAddNew) return "Conectar";
3984
- switch (card.state) {
3985
- case "available":
3986
- return "Conectar";
3987
- case "connected":
3988
- return "Configurar";
3989
- case "expired":
3990
- return "Reconectar";
3991
- default:
3992
- return "";
3993
- }
3994
- }
3995
- function IntegrationCard({ card, onConnect }) {
4077
+ function IntegrationCard({
4078
+ card,
4079
+ onConnect,
4080
+ onReconnect,
4081
+ onDisconnect,
4082
+ onDelete
4083
+ }) {
3996
4084
  const { definition, state, isAddNew, accountLabel } = card;
3997
4085
  const Icon = resolveIcon2(definition.icon);
3998
4086
  const isComingSoon = state === "coming_soon";
3999
- const actionLabel = getActionLabel(card);
4087
+ const isConnected = state === "connected" || state === "expired";
4088
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState13(false);
4000
4089
  if (isAddNew) {
4001
4090
  return /* @__PURE__ */ jsxs15(
4002
4091
  "div",
4003
4092
  {
4004
4093
  className: cn(
4005
- "group relative flex flex-col gap-3 rounded-xl border border-dashed bg-card/50 p-5 transition-shadow",
4006
- "hover:shadow-md hover:border-solid hover:bg-card cursor-pointer"
4094
+ "group relative flex flex-col gap-3 rounded-xl border bg-card/50 p-5 transition-all",
4095
+ "hover:shadow-md hover:bg-card cursor-pointer"
4007
4096
  ),
4008
4097
  role: "button",
4009
4098
  tabIndex: 0,
4010
- "aria-label": `Adicionar conta ${definition.name}`,
4099
+ "aria-label": `Conectar ${definition.name}`,
4011
4100
  onClick: () => onConnect(card),
4012
4101
  onKeyDown: (e) => {
4013
4102
  if (e.key === "Enter" || e.key === " ") {
@@ -4016,15 +4105,11 @@ function IntegrationCard({ card, onConnect }) {
4016
4105
  }
4017
4106
  },
4018
4107
  children: [
4019
- /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4108
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-3", children: [
4020
4109
  /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/5 text-primary/60", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4021
- /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: "text-xs bg-muted text-muted-foreground", children: "Adicionar" })
4022
- ] }),
4023
- /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
4024
- /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight text-muted-foreground", children: definition.name }),
4025
- /* @__PURE__ */ jsxs15("p", { className: "text-xs text-muted-foreground/70 leading-relaxed flex items-center gap-1", children: [
4026
- /* @__PURE__ */ jsx17(Plus3, { className: "h-3 w-3" }),
4027
- "Adicionar conta"
4110
+ /* @__PURE__ */ jsxs15("div", { className: "flex-1 min-w-0 space-y-0.5", children: [
4111
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight text-foreground", children: definition.name }),
4112
+ /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed", children: "Conectar nova conta" })
4028
4113
  ] })
4029
4114
  ] }),
4030
4115
  /* @__PURE__ */ jsx17("div", { className: "mt-auto flex items-center justify-end pt-1", children: /* @__PURE__ */ jsx17(
@@ -4037,66 +4122,138 @@ function IntegrationCard({ card, onConnect }) {
4037
4122
  e.stopPropagation();
4038
4123
  onConnect(card);
4039
4124
  },
4040
- children: actionLabel
4125
+ children: "Conectar"
4041
4126
  }
4042
4127
  ) })
4043
4128
  ]
4044
4129
  }
4045
4130
  );
4046
4131
  }
4132
+ if (isComingSoon) {
4133
+ const badge2 = STATE_BADGES[state];
4134
+ return /* @__PURE__ */ jsxs15(
4135
+ "div",
4136
+ {
4137
+ className: "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 opacity-60 cursor-default",
4138
+ "aria-disabled": true,
4139
+ children: [
4140
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4141
+ /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4142
+ /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: cn("text-xs", badge2.className), children: badge2.label })
4143
+ ] }),
4144
+ /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
4145
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
4146
+ /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
4147
+ ] })
4148
+ ]
4149
+ }
4150
+ );
4151
+ }
4047
4152
  const badge = STATE_BADGES[state];
4048
- return /* @__PURE__ */ jsxs15(
4049
- "div",
4050
- {
4051
- className: cn(
4052
- "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
4053
- isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
4054
- ),
4055
- role: "button",
4056
- tabIndex: isComingSoon ? -1 : 0,
4057
- "aria-label": `${definition.name}${accountLabel ? ` \u2014 ${accountLabel}` : ""} \u2014 ${badge.label}`,
4058
- "aria-disabled": isComingSoon,
4059
- onClick: () => !isComingSoon && onConnect(card),
4060
- onKeyDown: (e) => {
4061
- if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
4062
- e.preventDefault();
4063
- onConnect(card);
4064
- }
4065
- },
4066
- children: [
4067
- /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4068
- /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4069
- /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
4070
- ] }),
4071
- /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
4072
- /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
4073
- accountLabel ? /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed truncate", title: accountLabel, children: accountLabel }) : /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
4074
- ] }),
4075
- /* @__PURE__ */ jsx17("div", { className: "mt-auto flex items-center justify-end gap-2 pt-1", children: !isComingSoon && /* @__PURE__ */ jsx17(
4076
- Button12,
4153
+ return /* @__PURE__ */ jsxs15(Fragment3, { children: [
4154
+ /* @__PURE__ */ jsxs15(
4155
+ "div",
4156
+ {
4157
+ className: "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow hover:shadow-md",
4158
+ children: [
4159
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4160
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-3 min-w-0 flex-1", children: [
4161
+ /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4162
+ /* @__PURE__ */ jsxs15("div", { className: "flex-1 min-w-0 space-y-0.5", children: [
4163
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
4164
+ accountLabel && /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed truncate", title: accountLabel, children: accountLabel })
4165
+ ] })
4166
+ ] }),
4167
+ /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: cn("text-xs shrink-0", badge.className), children: badge.label })
4168
+ ] }),
4169
+ /* @__PURE__ */ jsx17("div", { className: "mt-auto flex items-center justify-end gap-2 pt-1", children: /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
4170
+ /* @__PURE__ */ jsx17(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(
4171
+ Button12,
4172
+ {
4173
+ variant: "outline",
4174
+ size: "sm",
4175
+ className: "text-xs gap-1.5",
4176
+ children: [
4177
+ /* @__PURE__ */ jsx17(Settings3, { className: "h-3.5 w-3.5" }),
4178
+ "Configurar"
4179
+ ]
4180
+ }
4181
+ ) }),
4182
+ /* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
4183
+ /* @__PURE__ */ jsxs15(
4184
+ DropdownMenuItem,
4185
+ {
4186
+ onClick: () => onReconnect?.(card),
4187
+ className: "gap-2",
4188
+ children: [
4189
+ /* @__PURE__ */ jsx17(RefreshCw, { className: "h-4 w-4" }),
4190
+ "Reconectar"
4191
+ ]
4192
+ }
4193
+ ),
4194
+ /* @__PURE__ */ jsxs15(
4195
+ DropdownMenuItem,
4196
+ {
4197
+ onClick: () => onDisconnect?.(card),
4198
+ className: "gap-2",
4199
+ children: [
4200
+ /* @__PURE__ */ jsx17(Unplug, { className: "h-4 w-4" }),
4201
+ "Desconectar"
4202
+ ]
4203
+ }
4204
+ ),
4205
+ /* @__PURE__ */ jsxs15(
4206
+ DropdownMenuItem,
4207
+ {
4208
+ onClick: () => setDeleteDialogOpen(true),
4209
+ className: "gap-2 text-destructive focus:text-destructive",
4210
+ children: [
4211
+ /* @__PURE__ */ jsx17(Trash26, { className: "h-4 w-4" }),
4212
+ "Remover"
4213
+ ]
4214
+ }
4215
+ )
4216
+ ] })
4217
+ ] }) })
4218
+ ]
4219
+ }
4220
+ ),
4221
+ /* @__PURE__ */ jsx17(AlertDialog6, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ jsxs15(AlertDialogContent6, { children: [
4222
+ /* @__PURE__ */ jsxs15(AlertDialogHeader6, { children: [
4223
+ /* @__PURE__ */ jsx17(AlertDialogTitle6, { children: "Remover integra\xE7\xE3o?" }),
4224
+ /* @__PURE__ */ jsxs15(AlertDialogDescription6, { children: [
4225
+ "Esta a\xE7\xE3o vai remover a credencial",
4226
+ accountLabel ? ` (${accountLabel})` : "",
4227
+ " de ",
4228
+ definition.name,
4229
+ ". Esta a\xE7\xE3o n\xE3o pode ser desfeita."
4230
+ ] })
4231
+ ] }),
4232
+ /* @__PURE__ */ jsxs15(AlertDialogFooter6, { children: [
4233
+ /* @__PURE__ */ jsx17(AlertDialogCancel6, { children: "Cancelar" }),
4234
+ /* @__PURE__ */ jsx17(
4235
+ AlertDialogAction6,
4077
4236
  {
4078
- variant: state === "expired" ? "destructive" : "outline",
4079
- size: "sm",
4080
- className: "text-xs",
4081
- onClick: (e) => {
4082
- e.stopPropagation();
4083
- onConnect(card);
4237
+ onClick: () => {
4238
+ onDelete?.(card);
4239
+ setDeleteDialogOpen(false);
4084
4240
  },
4085
- children: actionLabel
4241
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
4242
+ children: "Remover"
4086
4243
  }
4087
- ) })
4088
- ]
4089
- }
4090
- );
4244
+ )
4245
+ ] })
4246
+ ] }) })
4247
+ ] });
4091
4248
  }
4092
4249
 
4093
4250
  // src/components/capabilities/advanced-tab.tsx
4094
- import { useState as useState13 } from "react";
4251
+ import { useState as useState14 } from "react";
4095
4252
  import { Info } from "lucide-react";
4096
4253
  import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
4097
4254
  function AdvancedTab({ config, agentId, gagentsApiUrl }) {
4098
- const [editingTool, setEditingTool] = useState13(null);
4099
- const [showToolForm, setShowToolForm] = useState13(false);
4255
+ const [editingTool, setEditingTool] = useState14(null);
4256
+ const [showToolForm, setShowToolForm] = useState14(false);
4100
4257
  function handleEditTool(tool) {
4101
4258
  setEditingTool(tool);
4102
4259
  setShowToolForm(true);
@@ -4133,7 +4290,7 @@ function AdvancedTab({ config, agentId, gagentsApiUrl }) {
4133
4290
  }
4134
4291
 
4135
4292
  // src/components/capabilities/integration-wizard.tsx
4136
- import { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef2, useState as useState14 } from "react";
4293
+ import { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef2, useState as useState15 } from "react";
4137
4294
  import {
4138
4295
  Dialog as Dialog6,
4139
4296
  DialogContent as DialogContent6,
@@ -4535,18 +4692,18 @@ function IntegrationWizard({
4535
4692
  existingConfigValue
4536
4693
  }) {
4537
4694
  const isReconnect = !!existingCredentialId;
4538
- const [currentStep, setCurrentStep] = useState14("info");
4695
+ const [currentStep, setCurrentStep] = useState15("info");
4539
4696
  const currentIndex = STEPS.indexOf(currentStep);
4540
- const [oauthStatus, setOauthStatus] = useState14("idle");
4541
- const [oauthResult, setOauthResult] = useState14(null);
4697
+ const [oauthStatus, setOauthStatus] = useState15("idle");
4698
+ const [oauthResult, setOauthResult] = useState15(null);
4542
4699
  const popupRef = useRef2(null);
4543
4700
  const popupPollRef = useRef2(null);
4544
- const [apiKey, setApiKey] = useState14("");
4545
- const [configOptions, setConfigOptions] = useState14([]);
4546
- const [configLoading, setConfigLoading] = useState14(false);
4547
- const [selectedConfigValue, setSelectedConfigValue] = useState14("");
4548
- const [enableOnComplete, setEnableOnComplete] = useState14(true);
4549
- const [isSubmitting, setIsSubmitting] = useState14(false);
4701
+ const [apiKey, setApiKey] = useState15("");
4702
+ const [configOptions, setConfigOptions] = useState15([]);
4703
+ const [configLoading, setConfigLoading] = useState15(false);
4704
+ const [selectedConfigValue, setSelectedConfigValue] = useState15("");
4705
+ const [enableOnComplete, setEnableOnComplete] = useState15(true);
4706
+ const [isSubmitting, setIsSubmitting] = useState15(false);
4550
4707
  useEffect5(() => {
4551
4708
  return () => {
4552
4709
  if (popupPollRef.current) {
@@ -4715,7 +4872,6 @@ function IntegrationWizard({
4715
4872
  setIsSubmitting(true);
4716
4873
  try {
4717
4874
  onComplete();
4718
- onOpenChange(false);
4719
4875
  toast11.success(
4720
4876
  `${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
4721
4877
  );
@@ -4883,7 +5039,7 @@ function StepIndicator({
4883
5039
  }
4884
5040
 
4885
5041
  // src/pages/agents-page.tsx
4886
- import { useState as useState15 } from "react";
5042
+ import { useState as useState16 } from "react";
4887
5043
  import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
4888
5044
  import { Plus as Plus4 } from "lucide-react";
4889
5045
  import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
@@ -4893,7 +5049,7 @@ function AgentsPage({
4893
5049
  title = "Agentes AI",
4894
5050
  subtitle = "Gerencie seus agentes de atendimento inteligente"
4895
5051
  }) {
4896
- const [createOpen, setCreateOpen] = useState15(false);
5052
+ const [createOpen, setCreateOpen] = useState16(false);
4897
5053
  return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
4898
5054
  /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
4899
5055
  /* @__PURE__ */ jsxs22("div", { children: [
@@ -4918,7 +5074,7 @@ function AgentsPage({
4918
5074
  }
4919
5075
 
4920
5076
  // src/pages/agent-detail-page.tsx
4921
- import { useState as useState16 } from "react";
5077
+ import { useState as useState17 } from "react";
4922
5078
  import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
4923
5079
  import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
4924
5080
  import { ArrowLeft, Pencil as Pencil4 } from "lucide-react";
@@ -4930,7 +5086,7 @@ function AgentDetailPage({
4930
5086
  renderChatLink
4931
5087
  }) {
4932
5088
  const { data: agent, isLoading } = useAgent(config, agentId);
4933
- const [editOpen, setEditOpen] = useState16(false);
5089
+ const [editOpen, setEditOpen] = useState17(false);
4934
5090
  if (isLoading) {
4935
5091
  return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4", children: [
4936
5092
  /* @__PURE__ */ jsx25(Skeleton7, { className: "h-4 w-32" }),
@@ -5059,7 +5215,7 @@ function AgentCapabilitiesPage({
5059
5215
  }
5060
5216
 
5061
5217
  // src/pages/tools-page.tsx
5062
- import { useState as useState17 } from "react";
5218
+ import { useState as useState18 } from "react";
5063
5219
  import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
5064
5220
  import { Plus as Plus5 } from "lucide-react";
5065
5221
  import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
@@ -5068,8 +5224,8 @@ function ToolsPage({
5068
5224
  title = "Ferramentas",
5069
5225
  subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
5070
5226
  }) {
5071
- const [createOpen, setCreateOpen] = useState17(false);
5072
- const [editTool, setEditTool] = useState17(void 0);
5227
+ const [createOpen, setCreateOpen] = useState18(false);
5228
+ const [editTool, setEditTool] = useState18(void 0);
5073
5229
  return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5074
5230
  /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
5075
5231
  /* @__PURE__ */ jsxs25("div", { children: [
@@ -5130,55 +5286,44 @@ function CredentialsPage({
5130
5286
  }
5131
5287
 
5132
5288
  // src/pages/integrations-management-page.tsx
5133
- import { useMemo as useMemo8, useCallback as useCallback7, useState as useState18 } from "react";
5134
- import {
5135
- Badge as Badge11,
5136
- Tabs as Tabs3,
5137
- TabsContent as TabsContent3,
5138
- TabsList as TabsList3,
5139
- TabsTrigger as TabsTrigger3
5140
- } from "@greatapps/greatauth-ui/ui";
5141
- import { Plug as Plug5, KeyRound, Info as Info3, Loader2 as Loader210 } from "lucide-react";
5289
+ import { useCallback as useCallback7, useState as useState19 } from "react";
5290
+ import { useQueryClient as useQueryClient7 } from "@tanstack/react-query";
5291
+ import { Plug as Plug5, Loader2 as Loader210 } from "lucide-react";
5142
5292
  import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5143
- function useCredentialAgentSummary(credentials, tools, agents) {
5144
- return useMemo8(() => {
5145
- const toolIdsWithCredentials = new Set(
5146
- credentials.map((c) => c.id_tool).filter(Boolean)
5147
- );
5148
- const linkedCount = credentials.filter(
5149
- (c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool)
5150
- ).length;
5151
- return {
5152
- totalCredentials: credentials.length,
5153
- linkedToTools: linkedCount,
5154
- totalAgents: agents.length,
5155
- totalTools: tools.length
5156
- };
5157
- }, [credentials, tools, agents]);
5158
- }
5159
5293
  function IntegrationsManagementPage({
5160
5294
  config,
5161
5295
  gagentsApiUrl,
5162
5296
  resolveWizardMeta,
5163
5297
  loadConfigOptions,
5164
5298
  onWizardComplete,
5165
- title = "Integra\xE7\xF5es e Credenciais",
5166
- subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
5299
+ title = "Integra\xE7\xF5es",
5300
+ subtitle = "Gerencie as integra\xE7\xF5es da conta."
5167
5301
  }) {
5168
- const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
5169
- const { data: agentsData } = useAgents(config);
5170
- const { data: toolsData } = useTools(config);
5302
+ const queryClient = useQueryClient7();
5171
5303
  const { cards, isLoading: cardsLoading } = useIntegrationState(config, null);
5172
- const [wizardOpen, setWizardOpen] = useState18(false);
5173
- const [activeCard, setActiveCard] = useState18(null);
5174
- const credentials = credentialsData?.data || [];
5175
- const agents = agentsData?.data || [];
5176
- const tools = toolsData?.data || [];
5177
- const summary = useCredentialAgentSummary(credentials, tools, agents);
5304
+ const [wizardOpen, setWizardOpen] = useState19(false);
5305
+ const [activeCard, setActiveCard] = useState19(null);
5306
+ const deleteCredential = useDeleteToolCredential(config);
5307
+ const updateCredential = useUpdateToolCredential(config);
5178
5308
  const handleConnect = useCallback7((card) => {
5179
5309
  setActiveCard(card);
5180
5310
  setWizardOpen(true);
5181
5311
  }, []);
5312
+ const handleReconnect = useCallback7((card) => {
5313
+ setActiveCard(card);
5314
+ setWizardOpen(true);
5315
+ }, []);
5316
+ const handleDisconnect = useCallback7((card) => {
5317
+ if (!card.credentialId) return;
5318
+ updateCredential.mutate({
5319
+ id: card.credentialId,
5320
+ body: { status: "inactive" }
5321
+ });
5322
+ }, [updateCredential]);
5323
+ const handleDelete = useCallback7((card) => {
5324
+ if (!card.credentialId) return;
5325
+ deleteCredential.mutate(card.credentialId);
5326
+ }, [deleteCredential]);
5182
5327
  const handleWizardClose = useCallback7((open) => {
5183
5328
  if (!open) {
5184
5329
  setActiveCard(null);
@@ -5186,10 +5331,13 @@ function IntegrationsManagementPage({
5186
5331
  setWizardOpen(open);
5187
5332
  }, []);
5188
5333
  const handleWizardComplete = useCallback7(() => {
5334
+ queryClient.invalidateQueries({ queryKey: ["greatagents", "tool-credentials"] });
5335
+ queryClient.invalidateQueries({ queryKey: ["greatagents", "tools"] });
5336
+ queryClient.invalidateQueries({ queryKey: ["greatagents", "agent-tools"] });
5189
5337
  setWizardOpen(false);
5190
5338
  setActiveCard(null);
5191
5339
  onWizardComplete?.();
5192
- }, [onWizardComplete]);
5340
+ }, [onWizardComplete, queryClient]);
5193
5341
  const wizardMeta = activeCard ? resolveWizardMeta?.(activeCard) ?? {
5194
5342
  capabilities: [],
5195
5343
  requirements: [],
@@ -5206,76 +5354,37 @@ function IntegrationsManagementPage({
5206
5354
  /* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
5207
5355
  /* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: subtitle })
5208
5356
  ] }) }),
5209
- /* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
5210
- /* @__PURE__ */ jsxs27(TabsList3, { children: [
5211
- /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
5212
- /* @__PURE__ */ jsx29(Plug5, { className: "h-4 w-4" }),
5213
- "Integra\xE7\xF5es"
5214
- ] }),
5215
- /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
5216
- /* @__PURE__ */ jsx29(KeyRound, { className: "h-4 w-4" }),
5217
- "Credenciais"
5218
- ] })
5357
+ cardsLoading ? /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx29(Loader210, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : cards.length === 0 ? /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
5358
+ /* @__PURE__ */ jsx29(Plug5, { className: "h-10 w-10" }),
5359
+ /* @__PURE__ */ jsx29("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
5360
+ ] }) : /* @__PURE__ */ jsxs27("div", { className: "space-y-6", children: [
5361
+ connectedCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5362
+ /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Contas conectadas" }),
5363
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => /* @__PURE__ */ jsx29(
5364
+ IntegrationCard,
5365
+ {
5366
+ card,
5367
+ onConnect: handleConnect,
5368
+ onReconnect: handleReconnect,
5369
+ onDisconnect: handleDisconnect,
5370
+ onDelete: handleDelete
5371
+ },
5372
+ `${card.definition.slug}-cred-${card.credentialId}`
5373
+ )) })
5219
5374
  ] }),
5220
- /* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: cardsLoading ? /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx29(Loader210, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : cards.length === 0 ? /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
5221
- /* @__PURE__ */ jsx29(Plug5, { className: "h-10 w-10" }),
5222
- /* @__PURE__ */ jsx29("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
5223
- ] }) : /* @__PURE__ */ jsxs27("div", { className: "space-y-6", children: [
5224
- connectedCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5225
- /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Contas conectadas" }),
5226
- /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => /* @__PURE__ */ jsx29(
5375
+ otherCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5376
+ connectedCards.length > 0 && /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Adicionar integra\xE7\xE3o" }),
5377
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: otherCards.map((card) => {
5378
+ const key = card.isAddNew ? `${card.definition.slug}-add-new` : card.definition.slug;
5379
+ return /* @__PURE__ */ jsx29(
5227
5380
  IntegrationCard,
5228
5381
  {
5229
5382
  card,
5230
5383
  onConnect: handleConnect
5231
5384
  },
5232
- `${card.definition.slug}-cred-${card.credentialId}`
5233
- )) })
5234
- ] }),
5235
- otherCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5236
- connectedCards.length > 0 && /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Adicionar integra\xE7\xE3o" }),
5237
- /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: otherCards.map((card) => {
5238
- const key = card.isAddNew ? `${card.definition.slug}-add-new` : card.definition.slug;
5239
- return /* @__PURE__ */ jsx29(
5240
- IntegrationCard,
5241
- {
5242
- card,
5243
- onConnect: handleConnect
5244
- },
5245
- key
5246
- );
5247
- }) })
5248
- ] })
5249
- ] }) }),
5250
- /* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
5251
- !credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
5252
- /* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
5253
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
5254
- /* @__PURE__ */ jsxs27("span", { children: [
5255
- /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalCredentials }),
5256
- summary.totalCredentials === 1 ? "credencial configurada" : "credenciais configuradas"
5257
- ] }),
5258
- /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
5259
- /* @__PURE__ */ jsxs27("span", { children: [
5260
- /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.linkedToTools }),
5261
- summary.linkedToTools === 1 ? "vinculada a ferramentas" : "vinculadas a ferramentas"
5262
- ] }),
5263
- /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
5264
- /* @__PURE__ */ jsxs27("span", { children: [
5265
- /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalAgents }),
5266
- summary.totalAgents === 1 ? "agente na conta" : "agentes na conta"
5267
- ] })
5268
- ] })
5269
- ] }),
5270
- /* @__PURE__ */ jsx29(
5271
- ToolCredentialsForm,
5272
- {
5273
- config,
5274
- gagentsApiUrl,
5275
- credentials,
5276
- isLoading: credentialsLoading
5277
- }
5278
- )
5385
+ key
5386
+ );
5387
+ }) })
5279
5388
  ] })
5280
5389
  ] }),
5281
5390
  activeCard && wizardMeta && /* @__PURE__ */ jsx29(