@greatapps/greatagents-ui 0.3.16 → 0.3.18
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 +99 -67
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/agents/agent-objectives-list.tsx +63 -13
- package/src/components/agents/agent-prompt-editor.tsx +24 -45
- package/src/components/capabilities/capabilities-tab.tsx +26 -9
- package/src/components/capabilities/integrations-tab.tsx +1 -1
- package/src/hooks/use-integrations.ts +15 -11
- package/src/pages/integrations-management-page.tsx +4 -1
package/dist/index.js
CHANGED
|
@@ -534,13 +534,16 @@ function useIntegrationState(config, agentId) {
|
|
|
534
534
|
const matchedTool = tools.find((t) => t.slug === def.slug) ?? null;
|
|
535
535
|
const matchedCredentials = matchedTool ? credentials.filter((c) => c.id_tool === matchedTool.id) : [];
|
|
536
536
|
const piCredentials = credentials.filter(
|
|
537
|
-
(c) => c.id_platform_integration != null && !c.id_tool
|
|
538
|
-
// platform_integrations data, but credentials with
|
|
539
|
-
// id_platform_integration are for calendar integrations
|
|
540
|
-
// which match by the registry slug
|
|
541
|
-
matchedTool == null
|
|
537
|
+
(c) => c.id_platform_integration != null && !c.id_tool
|
|
542
538
|
);
|
|
543
|
-
const
|
|
539
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
540
|
+
const allCredentials = [];
|
|
541
|
+
for (const cred of [...matchedCredentials, ...piCredentials]) {
|
|
542
|
+
if (!seenIds.has(cred.id)) {
|
|
543
|
+
seenIds.add(cred.id);
|
|
544
|
+
allCredentials.push(cred);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
544
547
|
const linkedToAgent = matchedTool ? agentTools.some((at) => at.id_tool === matchedTool.id) : false;
|
|
545
548
|
for (const cred of allCredentials) {
|
|
546
549
|
const state = cred.status === "expired" ? "expired" : "connected";
|
|
@@ -1634,7 +1637,22 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
1634
1637
|
function slugify(text) {
|
|
1635
1638
|
return text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1636
1639
|
}
|
|
1637
|
-
var EMPTY_FORM = { title: "", slug: "", prompt: "" };
|
|
1640
|
+
var EMPTY_FORM = { title: "", slug: "", instruction: "", prompt: "" };
|
|
1641
|
+
function splitPrompt(prompt) {
|
|
1642
|
+
if (!prompt) return { instruction: "", body: "" };
|
|
1643
|
+
const idx = prompt.indexOf("\n");
|
|
1644
|
+
if (idx === -1) return { instruction: prompt.trim(), body: "" };
|
|
1645
|
+
return { instruction: prompt.slice(0, idx).trim(), body: prompt.slice(idx + 1).trim() };
|
|
1646
|
+
}
|
|
1647
|
+
function mergePrompt(instruction, body) {
|
|
1648
|
+
const i = instruction.trim();
|
|
1649
|
+
const b = body.trim();
|
|
1650
|
+
if (!i && !b) return "";
|
|
1651
|
+
if (!b) return i;
|
|
1652
|
+
if (!i) return b;
|
|
1653
|
+
return `${i}
|
|
1654
|
+
${b}`;
|
|
1655
|
+
}
|
|
1638
1656
|
function AgentObjectivesList({ agent, config }) {
|
|
1639
1657
|
const { data: objectivesData, isLoading } = useObjectives(config, agent.id);
|
|
1640
1658
|
const createMutation = useCreateObjective(config);
|
|
@@ -1670,10 +1688,12 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1670
1688
|
}
|
|
1671
1689
|
function openEdit(objective) {
|
|
1672
1690
|
setEditTarget(objective);
|
|
1691
|
+
const { instruction, body } = splitPrompt(objective.prompt);
|
|
1673
1692
|
setForm({
|
|
1674
1693
|
title: objective.title,
|
|
1675
1694
|
slug: objective.slug || "",
|
|
1676
|
-
|
|
1695
|
+
instruction,
|
|
1696
|
+
prompt: body
|
|
1677
1697
|
});
|
|
1678
1698
|
setSlugManual(true);
|
|
1679
1699
|
setFormOpen(true);
|
|
@@ -1681,6 +1701,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1681
1701
|
async function handleSubmit() {
|
|
1682
1702
|
if (!form.title.trim()) return;
|
|
1683
1703
|
const effectiveSlug = form.slug.trim() || slugify(form.title);
|
|
1704
|
+
const mergedPrompt = mergePrompt(form.instruction, form.prompt) || null;
|
|
1684
1705
|
const nextOrder = sortedObjectives.length > 0 ? Math.max(...sortedObjectives.map((o) => o.order)) + 1 : 1;
|
|
1685
1706
|
try {
|
|
1686
1707
|
if (editTarget) {
|
|
@@ -1690,7 +1711,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1690
1711
|
body: {
|
|
1691
1712
|
title: form.title.trim(),
|
|
1692
1713
|
slug: effectiveSlug,
|
|
1693
|
-
prompt:
|
|
1714
|
+
prompt: mergedPrompt
|
|
1694
1715
|
}
|
|
1695
1716
|
});
|
|
1696
1717
|
toast4.success("Objetivo atualizado");
|
|
@@ -1700,7 +1721,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1700
1721
|
body: {
|
|
1701
1722
|
title: form.title.trim(),
|
|
1702
1723
|
slug: effectiveSlug,
|
|
1703
|
-
prompt:
|
|
1724
|
+
prompt: mergedPrompt,
|
|
1704
1725
|
order: nextOrder
|
|
1705
1726
|
}
|
|
1706
1727
|
});
|
|
@@ -1785,7 +1806,16 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1785
1806
|
/* @__PURE__ */ jsx5("span", { className: "truncate font-medium", children: objective.title }),
|
|
1786
1807
|
objective.slug && /* @__PURE__ */ jsx5(Badge2, { variant: "secondary", className: "shrink-0 text-xs font-mono", children: objective.slug })
|
|
1787
1808
|
] }),
|
|
1788
|
-
objective.prompt &&
|
|
1809
|
+
objective.prompt && (() => {
|
|
1810
|
+
const { instruction, body } = splitPrompt(objective.prompt);
|
|
1811
|
+
return /* @__PURE__ */ jsxs4("div", { className: "space-y-0.5", children: [
|
|
1812
|
+
instruction && /* @__PURE__ */ jsxs4("p", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
1813
|
+
"Quando: ",
|
|
1814
|
+
instruction
|
|
1815
|
+
] }),
|
|
1816
|
+
body && /* @__PURE__ */ jsx5("p", { className: "line-clamp-1 text-xs text-muted-foreground", children: body })
|
|
1817
|
+
] });
|
|
1818
|
+
})()
|
|
1789
1819
|
] }),
|
|
1790
1820
|
/* @__PURE__ */ jsx5(
|
|
1791
1821
|
Switch3,
|
|
@@ -1874,7 +1904,21 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1874
1904
|
/* @__PURE__ */ jsx5("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente. Usado pelo agente para identificar o objetivo." })
|
|
1875
1905
|
] }),
|
|
1876
1906
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1877
|
-
/* @__PURE__ */ jsx5(Label3, { htmlFor: "objective-
|
|
1907
|
+
/* @__PURE__ */ jsx5(Label3, { htmlFor: "objective-instruction", children: "Quando ativar (instru\xE7\xE3o curta) *" }),
|
|
1908
|
+
/* @__PURE__ */ jsx5(
|
|
1909
|
+
Input4,
|
|
1910
|
+
{
|
|
1911
|
+
id: "objective-instruction",
|
|
1912
|
+
name: "instruction",
|
|
1913
|
+
value: form.instruction,
|
|
1914
|
+
onChange: (e) => setForm((f) => ({ ...f, instruction: e.target.value })),
|
|
1915
|
+
placeholder: "Ex: Quando o utilizador quer agendar uma consulta"
|
|
1916
|
+
}
|
|
1917
|
+
),
|
|
1918
|
+
/* @__PURE__ */ jsx5("p", { className: "text-xs text-muted-foreground", children: "Instru\xE7\xE3o curta que diz ao agente QUANDO ativar este objetivo. Aparece na sec\xE7\xE3o [SKILLS] do prompt." })
|
|
1919
|
+
] }),
|
|
1920
|
+
/* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1921
|
+
/* @__PURE__ */ jsx5(Label3, { htmlFor: "objective-prompt", children: "Instru\xE7\xF5es detalhadas" }),
|
|
1878
1922
|
/* @__PURE__ */ jsx5(
|
|
1879
1923
|
Textarea,
|
|
1880
1924
|
{
|
|
@@ -1882,11 +1926,11 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1882
1926
|
name: "prompt",
|
|
1883
1927
|
value: form.prompt,
|
|
1884
1928
|
onChange: (e) => setForm((f) => ({ ...f, prompt: e.target.value })),
|
|
1885
|
-
placeholder: "Instru
|
|
1886
|
-
rows:
|
|
1929
|
+
placeholder: "Instru\xE7\xF5es detalhadas que o agente seguir\xE1 quando este objetivo for ativado...",
|
|
1930
|
+
rows: 6
|
|
1887
1931
|
}
|
|
1888
1932
|
),
|
|
1889
|
-
/* @__PURE__ */ jsx5("p", { className: "text-xs text-muted-foreground", children: "
|
|
1933
|
+
/* @__PURE__ */ jsx5("p", { className: "text-xs text-muted-foreground", children: "Passos, regras e contexto detalhado para o agente seguir quando este objetivo est\xE1 ativo." })
|
|
1890
1934
|
] })
|
|
1891
1935
|
] }),
|
|
1892
1936
|
/* @__PURE__ */ jsxs4(DialogFooter3, { children: [
|
|
@@ -1974,56 +2018,36 @@ function computeDiff(oldText, newText) {
|
|
|
1974
2018
|
}
|
|
1975
2019
|
function buildPreview(promptText, objectives, agentTools, allTools) {
|
|
1976
2020
|
let preview = promptText;
|
|
1977
|
-
const activeObjectives = objectives.filter((o) => o.active);
|
|
2021
|
+
const activeObjectives = objectives.filter((o) => o.active && o.slug);
|
|
1978
2022
|
const enabledAgentTools = agentTools.filter((at) => at.enabled);
|
|
1979
2023
|
const toolMap = new Map(allTools.map((t) => [t.id, t]));
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
2024
|
+
if (activeObjectives.length > 0) {
|
|
2025
|
+
preview += "\n\n[SKILLS]";
|
|
2026
|
+
for (const obj of activeObjectives) {
|
|
2027
|
+
preview += `
|
|
2028
|
+
- ${obj.slug}: ${obj.title}`;
|
|
2029
|
+
if (obj.prompt) {
|
|
2030
|
+
const firstLine = obj.prompt.split("\n")[0].trim();
|
|
2031
|
+
if (firstLine) preview += ` \u2014 ${firstLine}`;
|
|
2032
|
+
}
|
|
1989
2033
|
}
|
|
1990
2034
|
}
|
|
1991
|
-
const
|
|
1992
|
-
if (
|
|
1993
|
-
preview += "\n\n[
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
for (const obj of activeObjectives) {
|
|
2035
|
+
const toolBindings = enabledAgentTools.map((at) => ({ at, tool: toolMap.get(at.id_tool) })).filter((x) => !!x.tool);
|
|
2036
|
+
if (toolBindings.length > 0) {
|
|
2037
|
+
preview += "\n\n[TOOLS]";
|
|
2038
|
+
for (const { at, tool } of toolBindings) {
|
|
2039
|
+
if (at.custom_instructions) {
|
|
1997
2040
|
preview += `
|
|
1998
2041
|
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
${obj.prompt}`;
|
|
2002
|
-
}
|
|
2003
|
-
for (const { at, tool } of capabilityTools) {
|
|
2042
|
+
${at.custom_instructions}`;
|
|
2043
|
+
} else {
|
|
2004
2044
|
preview += `
|
|
2005
2045
|
|
|
2006
2046
|
### ${tool.name} (${tool.slug})`;
|
|
2007
2047
|
if (tool.description) preview += `
|
|
2008
2048
|
${tool.description}`;
|
|
2009
|
-
if (at.custom_instructions) preview += `
|
|
2010
|
-
${at.custom_instructions}`;
|
|
2011
2049
|
}
|
|
2012
2050
|
}
|
|
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.";
|
|
2027
2051
|
}
|
|
2028
2052
|
return preview;
|
|
2029
2053
|
}
|
|
@@ -2186,7 +2210,7 @@ function AgentPromptEditor({ config, agent }) {
|
|
|
2186
2210
|
}
|
|
2187
2211
|
),
|
|
2188
2212
|
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) => {
|
|
2189
|
-
const isTopSection = line.startsWith("[
|
|
2213
|
+
const isTopSection = line.startsWith("[TOOLS]") || line.startsWith("[SKILLS]");
|
|
2190
2214
|
const isH2 = line.startsWith("## ");
|
|
2191
2215
|
const isH3 = line.startsWith("### ");
|
|
2192
2216
|
const cls = isTopSection ? "font-bold text-foreground" : isH2 ? "font-semibold text-muted-foreground" : isH3 ? "font-medium text-muted-foreground" : "";
|
|
@@ -2634,9 +2658,11 @@ function cloneInstructions(state) {
|
|
|
2634
2658
|
return next;
|
|
2635
2659
|
}
|
|
2636
2660
|
function statesEqual(a, b) {
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2661
|
+
const aEffective = new Map([...a].filter(([, ops]) => ops.size > 0));
|
|
2662
|
+
const bEffective = new Map([...b].filter(([, ops]) => ops.size > 0));
|
|
2663
|
+
if (aEffective.size !== bEffective.size) return false;
|
|
2664
|
+
for (const [mod, opsA] of aEffective) {
|
|
2665
|
+
const opsB = bEffective.get(mod);
|
|
2640
2666
|
if (!opsB || opsA.size !== opsB.size) return false;
|
|
2641
2667
|
for (const op of opsA) {
|
|
2642
2668
|
if (!opsB.has(op)) return false;
|
|
@@ -2644,11 +2670,11 @@ function statesEqual(a, b) {
|
|
|
2644
2670
|
}
|
|
2645
2671
|
return true;
|
|
2646
2672
|
}
|
|
2647
|
-
function instructionsEqual(a, b) {
|
|
2648
|
-
|
|
2649
|
-
for (const
|
|
2650
|
-
const
|
|
2651
|
-
|
|
2673
|
+
function instructionsEqual(a, b, activeModules) {
|
|
2674
|
+
const relevantModules = new Set([...activeModules.keys()].filter((k) => (activeModules.get(k)?.size ?? 0) > 0));
|
|
2675
|
+
for (const mod of relevantModules) {
|
|
2676
|
+
const instrA = a.get(mod) ?? {};
|
|
2677
|
+
const instrB = b.get(mod) ?? {};
|
|
2652
2678
|
const keysA = Object.keys(instrA);
|
|
2653
2679
|
const keysB = Object.keys(instrB);
|
|
2654
2680
|
if (keysA.length !== keysB.length) return false;
|
|
@@ -2656,6 +2682,13 @@ function instructionsEqual(a, b) {
|
|
|
2656
2682
|
if (instrA[k] !== instrB[k]) return false;
|
|
2657
2683
|
}
|
|
2658
2684
|
}
|
|
2685
|
+
for (const mod of relevantModules) {
|
|
2686
|
+
const instrA = a.get(mod);
|
|
2687
|
+
const instrB = b.get(mod);
|
|
2688
|
+
const hasA = instrA && Object.keys(instrA).length > 0;
|
|
2689
|
+
const hasB = instrB && Object.keys(instrB).length > 0;
|
|
2690
|
+
if (hasA !== hasB) return false;
|
|
2691
|
+
}
|
|
2659
2692
|
return true;
|
|
2660
2693
|
}
|
|
2661
2694
|
function CapabilitiesTab({ config, agentId }) {
|
|
@@ -2682,7 +2715,7 @@ function CapabilitiesTab({ config, agentId }) {
|
|
|
2682
2715
|
setInitialized(false);
|
|
2683
2716
|
}, [agentId]);
|
|
2684
2717
|
const hasChanges = useMemo5(
|
|
2685
|
-
() => initialized && (!statesEqual(localState, serverState) || !instructionsEqual(localInstructions, serverInstructions)),
|
|
2718
|
+
() => initialized && (!statesEqual(localState, serverState) || !instructionsEqual(localInstructions, serverInstructions, localState)),
|
|
2686
2719
|
[localState, serverState, localInstructions, serverInstructions, initialized]
|
|
2687
2720
|
);
|
|
2688
2721
|
const updateState = useCallback4(
|
|
@@ -2982,11 +3015,8 @@ function buildCustomInstructions(integrationSlug, selectedFunctions, functionIns
|
|
|
2982
3015
|
const instruction = functionInstructions[f.slug] || f.defaultInstructions;
|
|
2983
3016
|
return `- ${f.slug}: ${instruction}`;
|
|
2984
3017
|
});
|
|
2985
|
-
return `
|
|
2986
|
-
|
|
2987
|
-
${lines.join("\n")}
|
|
2988
|
-
|
|
2989
|
-
Use EXATAMENTE os nomes de fun\xE7\xE3o listados acima.`;
|
|
3018
|
+
return `Fun\xE7\xF5es dispon\xEDveis (${integrationSlug}):
|
|
3019
|
+
${lines.join("\n")}`;
|
|
2990
3020
|
}
|
|
2991
3021
|
function IntegrationsTab({
|
|
2992
3022
|
config,
|
|
@@ -5624,6 +5654,8 @@ function IntegrationsManagementPage({
|
|
|
5624
5654
|
queryClient.invalidateQueries({ queryKey: ["greatagents", "tool-credentials"] });
|
|
5625
5655
|
queryClient.invalidateQueries({ queryKey: ["greatagents", "tools"] });
|
|
5626
5656
|
queryClient.invalidateQueries({ queryKey: ["greatagents", "agent-tools"] });
|
|
5657
|
+
queryClient.invalidateQueries({ queryKey: ["greatagents", "agent-capabilities"] });
|
|
5658
|
+
queryClient.invalidateQueries({ queryKey: ["greatagents", "capabilities"] });
|
|
5627
5659
|
setWizardOpen(false);
|
|
5628
5660
|
setActiveCard(null);
|
|
5629
5661
|
onWizardComplete?.();
|