apteva 0.4.16 → 0.4.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/ActivityPage.yv28a2vj.js +3 -0
- package/dist/ApiDocsPage.4ccwjjbk.js +4 -0
- package/dist/App.155wke5v.js +4 -0
- package/dist/App.2e19nvn4.js +13 -0
- package/dist/App.2ye1b5n0.js +4 -0
- package/dist/App.4da4ycbe.js +4 -0
- package/dist/App.b6wtzd1j.js +4 -0
- package/dist/App.fjrh28tf.js +4 -0
- package/dist/App.htc36cy8.js +4 -0
- package/dist/App.me6reaa6.js +4 -0
- package/dist/App.n5q6p960.js +4 -0
- package/dist/App.nft7h9jt.js +4 -0
- package/dist/App.np463xvy.js +4 -0
- package/dist/App.nps62kvt.js +4 -0
- package/dist/App.q8ws33cc.js +181 -0
- package/dist/App.tb0y0jmt.js +40 -0
- package/dist/ConnectionsPage.52evzrp7.js +3 -0
- package/dist/McpPage.bjqrp0n2.js +3 -0
- package/dist/SettingsPage.es76hnj2.js +3 -0
- package/dist/SkillsPage.06h8yf0h.js +3 -0
- package/dist/TasksPage.99df66mk.js +3 -0
- package/dist/TelemetryPage.bmdnxhq7.js +3 -0
- package/dist/TestsPage.denxrg8c.js +3 -0
- package/dist/index.html +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/auth/middleware.ts +2 -0
- package/src/db.ts +162 -11
- package/src/mcp-platform.ts +41 -1
- package/src/routes/api/agent-utils.ts +38 -2
- package/src/routes/api/agents.ts +65 -2
- package/src/routes/api/projects.ts +19 -2
- package/src/routes/api/system.ts +26 -12
- package/src/routes/api/triggers.ts +458 -0
- package/src/routes/api/webhooks.ts +171 -0
- package/src/routes/api.ts +4 -0
- package/src/routes/static.ts +12 -3
- package/src/server.ts +6 -4
- package/src/triggers/agentdojo.ts +248 -0
- package/src/triggers/composio.ts +264 -0
- package/src/triggers/index.ts +71 -0
- package/src/web/App.tsx +20 -12
- package/src/web/components/agents/AgentCard.tsx +14 -7
- package/src/web/components/agents/AgentPanel.tsx +105 -115
- package/src/web/components/common/Icons.tsx +8 -0
- package/src/web/components/common/index.ts +1 -0
- package/src/web/components/connections/ConnectionsPage.tsx +54 -0
- package/src/web/components/connections/IntegrationsTab.tsx +144 -0
- package/src/web/components/connections/OverviewTab.tsx +183 -0
- package/src/web/components/connections/TriggersTab.tsx +690 -0
- package/src/web/components/index.ts +1 -0
- package/src/web/components/layout/Sidebar.tsx +7 -1
- package/src/web/components/mcp/IntegrationsPanel.tsx +19 -3
- package/src/web/components/mcp/McpPage.tsx +9 -3
- package/src/web/components/settings/SettingsPage.tsx +96 -2
- package/src/web/components/tasks/TasksPage.tsx +2 -2
- package/src/web/components/tests/TestsPage.tsx +1 -2
- package/src/web/context/TelemetryContext.tsx +14 -1
- package/src/web/context/index.ts +1 -1
- package/src/web/hooks/useAgents.ts +15 -11
- package/src/web/types.ts +1 -1
- package/dist/App.2194efgj.js +0 -228
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import React, { useState, useCallback } from "react";
|
|
2
|
+
import { useAuth, useProjects } from "../../context";
|
|
3
|
+
import { IntegrationsPanel } from "../mcp/IntegrationsPanel";
|
|
4
|
+
|
|
5
|
+
interface TriggerType {
|
|
6
|
+
slug: string;
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
type: "webhook" | "poll";
|
|
10
|
+
toolkit_slug: string;
|
|
11
|
+
toolkit_name: string;
|
|
12
|
+
logo: string | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function IntegrationsTab() {
|
|
16
|
+
const { authFetch } = useAuth();
|
|
17
|
+
const { currentProjectId } = useProjects();
|
|
18
|
+
|
|
19
|
+
const projectId = currentProjectId && currentProjectId !== "unassigned" ? currentProjectId : null;
|
|
20
|
+
|
|
21
|
+
// Provider selection
|
|
22
|
+
const [selectedProvider, setSelectedProvider] = useState("composio");
|
|
23
|
+
const providerOptions = [
|
|
24
|
+
{ id: "composio", name: "Composio" },
|
|
25
|
+
{ id: "agentdojo", name: "AgentDojo" },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
// Trigger type browsing
|
|
29
|
+
const [browsingToolkit, setBrowsingToolkit] = useState<string | null>(null);
|
|
30
|
+
const [triggerTypes, setTriggerTypes] = useState<TriggerType[]>([]);
|
|
31
|
+
const [typesLoading, setTypesLoading] = useState(false);
|
|
32
|
+
|
|
33
|
+
const handleBrowseTriggers = useCallback(async (toolkitSlug: string) => {
|
|
34
|
+
setBrowsingToolkit(toolkitSlug);
|
|
35
|
+
setTypesLoading(true);
|
|
36
|
+
try {
|
|
37
|
+
let url = `/api/triggers/types?provider=${selectedProvider}&toolkit_slugs=${toolkitSlug}`;
|
|
38
|
+
if (projectId) url += `&project_id=${projectId}`;
|
|
39
|
+
const res = await authFetch(url);
|
|
40
|
+
if (res.ok) {
|
|
41
|
+
const data = await res.json();
|
|
42
|
+
setTriggerTypes(data.types || []);
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error("Failed to fetch trigger types:", e);
|
|
46
|
+
}
|
|
47
|
+
setTypesLoading(false);
|
|
48
|
+
}, [authFetch, projectId, selectedProvider]);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<p className="text-sm text-[#666] mb-4">
|
|
53
|
+
Connect external apps via OAuth or API Key. Connected apps can be used for triggers and MCP integrations.
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
{/* Provider Selector */}
|
|
57
|
+
<div className="flex items-center gap-2 mb-4">
|
|
58
|
+
<span className="text-xs text-[#666]">Provider:</span>
|
|
59
|
+
<div className="flex gap-1 bg-[#111] border border-[#1a1a1a] rounded-lg p-0.5">
|
|
60
|
+
{providerOptions.map(p => (
|
|
61
|
+
<button
|
|
62
|
+
key={p.id}
|
|
63
|
+
onClick={() => setSelectedProvider(p.id)}
|
|
64
|
+
className={`px-3 py-1 rounded text-xs font-medium transition ${
|
|
65
|
+
selectedProvider === p.id
|
|
66
|
+
? "bg-[#1a1a1a] text-white"
|
|
67
|
+
: "text-[#666] hover:text-[#888]"
|
|
68
|
+
}`}
|
|
69
|
+
>
|
|
70
|
+
{p.name}
|
|
71
|
+
</button>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<IntegrationsPanel
|
|
77
|
+
providerId={selectedProvider}
|
|
78
|
+
projectId={projectId}
|
|
79
|
+
hideMcpConfig
|
|
80
|
+
onBrowseTriggers={handleBrowseTriggers}
|
|
81
|
+
/>
|
|
82
|
+
|
|
83
|
+
{/* Trigger Types Panel */}
|
|
84
|
+
{browsingToolkit && (
|
|
85
|
+
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
|
86
|
+
<div className="bg-[#111] border border-[#333] rounded-lg w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col">
|
|
87
|
+
<div className="p-4 border-b border-[#1a1a1a] flex items-center justify-between">
|
|
88
|
+
<div>
|
|
89
|
+
<h3 className="font-medium">Trigger Types</h3>
|
|
90
|
+
<p className="text-xs text-[#666]">{browsingToolkit}</p>
|
|
91
|
+
</div>
|
|
92
|
+
<button
|
|
93
|
+
onClick={() => { setBrowsingToolkit(null); setTriggerTypes([]); }}
|
|
94
|
+
className="text-[#666] hover:text-white transition text-lg px-2"
|
|
95
|
+
>
|
|
96
|
+
x
|
|
97
|
+
</button>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div className="flex-1 overflow-auto p-4">
|
|
101
|
+
{typesLoading ? (
|
|
102
|
+
<div className="text-center py-8 text-[#666]">Loading trigger types...</div>
|
|
103
|
+
) : triggerTypes.length === 0 ? (
|
|
104
|
+
<div className="text-center py-8 text-[#666]">
|
|
105
|
+
No trigger types available for this app.
|
|
106
|
+
</div>
|
|
107
|
+
) : (
|
|
108
|
+
<div className="space-y-2">
|
|
109
|
+
{triggerTypes.map(tt => (
|
|
110
|
+
<div key={tt.slug} className="bg-[#0a0a0a] border border-[#1a1a1a] rounded-lg p-3">
|
|
111
|
+
<div className="flex items-start gap-3">
|
|
112
|
+
{tt.logo ? (
|
|
113
|
+
<img src={tt.logo} alt={tt.toolkit_name} className="w-6 h-6 rounded object-contain flex-shrink-0 mt-0.5" />
|
|
114
|
+
) : (
|
|
115
|
+
<div className="w-6 h-6 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0 mt-0.5">
|
|
116
|
+
{tt.toolkit_name?.[0]?.toUpperCase() || "?"}
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
119
|
+
<div className="flex-1 min-w-0">
|
|
120
|
+
<div className="text-sm font-medium">{tt.name}</div>
|
|
121
|
+
<div className="text-xs text-[#666] mt-0.5">{tt.description}</div>
|
|
122
|
+
<div className="flex items-center gap-2 mt-1.5">
|
|
123
|
+
<span className="text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded font-mono">
|
|
124
|
+
{tt.slug}
|
|
125
|
+
</span>
|
|
126
|
+
<span className={`text-[10px] px-1.5 py-0.5 rounded ${
|
|
127
|
+
tt.type === "webhook" ? "bg-blue-500/10 text-blue-400" : "bg-yellow-500/10 text-yellow-400"
|
|
128
|
+
}`}>
|
|
129
|
+
{tt.type}
|
|
130
|
+
</span>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
))}
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
)}
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import { useAuth, useProjects } from "../../context";
|
|
3
|
+
|
|
4
|
+
interface Subscription {
|
|
5
|
+
id: string;
|
|
6
|
+
trigger_slug: string;
|
|
7
|
+
trigger_instance_id: string | null;
|
|
8
|
+
agent_id: string;
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
project_id: string | null;
|
|
11
|
+
created_at: string;
|
|
12
|
+
updated_at: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface TriggerInstance {
|
|
16
|
+
id: string;
|
|
17
|
+
trigger_slug: string;
|
|
18
|
+
connected_account_id: string | null;
|
|
19
|
+
status: "active" | "disabled";
|
|
20
|
+
config: Record<string, unknown>;
|
|
21
|
+
created_at: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface Agent {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
status: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function OverviewTab() {
|
|
31
|
+
const { authFetch } = useAuth();
|
|
32
|
+
const { currentProjectId } = useProjects();
|
|
33
|
+
|
|
34
|
+
const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
|
|
35
|
+
const [triggers, setTriggers] = useState<TriggerInstance[]>([]);
|
|
36
|
+
const [agents, setAgents] = useState<Agent[]>([]);
|
|
37
|
+
const [loading, setLoading] = useState(true);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const fetchAll = async () => {
|
|
41
|
+
setLoading(true);
|
|
42
|
+
const projectParam = currentProjectId && currentProjectId !== "unassigned" ? `?project_id=${currentProjectId}` : "";
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const [subsRes, triggersRes, agentsRes] = await Promise.all([
|
|
46
|
+
authFetch(`/api/subscriptions${projectParam}`).catch(() => null),
|
|
47
|
+
authFetch(`/api/triggers${projectParam}`).catch(() => null),
|
|
48
|
+
authFetch(`/api/agents`).catch(() => null),
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
if (subsRes?.ok) {
|
|
52
|
+
const data = await subsRes.json();
|
|
53
|
+
setSubscriptions(data.subscriptions || []);
|
|
54
|
+
}
|
|
55
|
+
if (triggersRes?.ok) {
|
|
56
|
+
const data = await triggersRes.json();
|
|
57
|
+
setTriggers(data.triggers || []);
|
|
58
|
+
}
|
|
59
|
+
if (agentsRes?.ok) {
|
|
60
|
+
const data = await agentsRes.json();
|
|
61
|
+
setAgents(data.agents || []);
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error("Failed to fetch overview data:", e);
|
|
65
|
+
}
|
|
66
|
+
setLoading(false);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
fetchAll();
|
|
70
|
+
}, [authFetch, currentProjectId]);
|
|
71
|
+
|
|
72
|
+
if (loading) {
|
|
73
|
+
return <div className="text-center py-12 text-[#666]">Loading...</div>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const activeTriggers = triggers.filter(t => t.status === "active");
|
|
77
|
+
const enabledSubscriptions = subscriptions.filter(s => s.enabled);
|
|
78
|
+
const agentMap = new Map(agents.map(a => [a.id, a]));
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div className="space-y-6">
|
|
82
|
+
{/* Stats */}
|
|
83
|
+
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
|
84
|
+
<StatCard label="Subscriptions" value={enabledSubscriptions.length} />
|
|
85
|
+
<StatCard label="Active Triggers" value={activeTriggers.length} />
|
|
86
|
+
<StatCard label="Total Triggers" value={triggers.length} />
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
{/* Active Subscriptions */}
|
|
90
|
+
<section>
|
|
91
|
+
<h3 className="text-sm font-medium text-[#888] mb-3">Active Subscriptions ({enabledSubscriptions.length})</h3>
|
|
92
|
+
{enabledSubscriptions.length === 0 ? (
|
|
93
|
+
<div className="bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm">
|
|
94
|
+
No subscriptions. Go to the Triggers tab to route trigger events to agents.
|
|
95
|
+
</div>
|
|
96
|
+
) : (
|
|
97
|
+
<div className="space-y-2">
|
|
98
|
+
{enabledSubscriptions.map(sub => {
|
|
99
|
+
const agent = agentMap.get(sub.agent_id);
|
|
100
|
+
return (
|
|
101
|
+
<div key={sub.id} className="bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3">
|
|
102
|
+
<div className="w-2 h-2 rounded-full bg-green-400 flex-shrink-0" />
|
|
103
|
+
<div className="flex-1 min-w-0">
|
|
104
|
+
<div className="text-sm font-medium truncate">
|
|
105
|
+
{sub.trigger_slug.replace(/_/g, " ")}
|
|
106
|
+
</div>
|
|
107
|
+
<div className="text-xs text-[#666]">
|
|
108
|
+
{sub.trigger_instance_id
|
|
109
|
+
? `Instance: ${sub.trigger_instance_id.slice(0, 12)}...`
|
|
110
|
+
: "All instances"
|
|
111
|
+
}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div className="text-xs text-[#888] flex-shrink-0">
|
|
115
|
+
<span className="text-[#555]">→</span>{" "}
|
|
116
|
+
<span className="text-[#f97316]">{agent?.name || "Unknown Agent"}</span>
|
|
117
|
+
</div>
|
|
118
|
+
{agent && (
|
|
119
|
+
<span className={`text-xs px-2 py-0.5 rounded flex-shrink-0 ${
|
|
120
|
+
agent.status === "running"
|
|
121
|
+
? "bg-green-500/10 text-green-400"
|
|
122
|
+
: "bg-yellow-500/10 text-yellow-400"
|
|
123
|
+
}`}>
|
|
124
|
+
{agent.status}
|
|
125
|
+
</span>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
})}
|
|
130
|
+
</div>
|
|
131
|
+
)}
|
|
132
|
+
</section>
|
|
133
|
+
|
|
134
|
+
{/* Active Triggers */}
|
|
135
|
+
<section>
|
|
136
|
+
<h3 className="text-sm font-medium text-[#888] mb-3">Active Triggers ({activeTriggers.length})</h3>
|
|
137
|
+
{activeTriggers.length === 0 ? (
|
|
138
|
+
<div className="bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm">
|
|
139
|
+
No active triggers on Composio.
|
|
140
|
+
</div>
|
|
141
|
+
) : (
|
|
142
|
+
<div className="space-y-2">
|
|
143
|
+
{activeTriggers.map(trigger => (
|
|
144
|
+
<div key={trigger.id} className="bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3">
|
|
145
|
+
<div className="w-2 h-2 rounded-full bg-green-400 flex-shrink-0" />
|
|
146
|
+
<div className="flex-1 min-w-0">
|
|
147
|
+
<div className="text-sm font-medium truncate">
|
|
148
|
+
{trigger.trigger_slug.replace(/_/g, " ")}
|
|
149
|
+
</div>
|
|
150
|
+
<div className="text-xs text-[#666]">
|
|
151
|
+
ID: {trigger.id.slice(0, 8)}...
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
<span className="text-xs text-green-400 bg-green-500/10 px-2 py-0.5 rounded">
|
|
155
|
+
active
|
|
156
|
+
</span>
|
|
157
|
+
</div>
|
|
158
|
+
))}
|
|
159
|
+
</div>
|
|
160
|
+
)}
|
|
161
|
+
</section>
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function StatCard({
|
|
167
|
+
label,
|
|
168
|
+
value,
|
|
169
|
+
valueColor,
|
|
170
|
+
}: {
|
|
171
|
+
label: string;
|
|
172
|
+
value: string | number;
|
|
173
|
+
valueColor?: string;
|
|
174
|
+
}) {
|
|
175
|
+
return (
|
|
176
|
+
<div className="bg-[#111] border border-[#1a1a1a] rounded-lg p-4">
|
|
177
|
+
<div className="text-xs text-[#666] mb-1">{label}</div>
|
|
178
|
+
<div className={`text-2xl font-bold ${valueColor || "text-[#e0e0e0]"}`}>
|
|
179
|
+
{value}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
183
|
+
}
|