apteva 0.4.57 → 0.7.1

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.
Files changed (142) hide show
  1. package/README.md +216 -54
  2. package/cli.js +35 -0
  3. package/install.js +92 -0
  4. package/package.json +15 -76
  5. package/LICENSE +0 -63
  6. package/bin/apteva.js +0 -196
  7. package/dist/ActivityPage.kxzzb4yc.js +0 -3
  8. package/dist/ApiDocsPage.zq998hbm.js +0 -4
  9. package/dist/App.55rea8mn.js +0 -61
  10. package/dist/App.5ywb23z4.js +0 -53
  11. package/dist/App.6thds120.js +0 -4
  12. package/dist/App.9tctxzqm.js +0 -8
  13. package/dist/App.a8r8ttaz.js +0 -4
  14. package/dist/App.agsv5bje.js +0 -4
  15. package/dist/App.cepapqmx.js +0 -4
  16. package/dist/App.dp041gb3.js +0 -221
  17. package/dist/App.fds72zb5.js +0 -4
  18. package/dist/App.fg9qj2dq.js +0 -4
  19. package/dist/App.ndfejbm9.js +0 -4
  20. package/dist/App.nxmfmq1h.js +0 -13
  21. package/dist/App.qdfyt8ba.js +0 -4
  22. package/dist/App.x2d0ygt6.js +0 -4
  23. package/dist/App.yt9p4nr3.js +0 -20
  24. package/dist/App.zn4mw16t.js +0 -1
  25. package/dist/ConnectionsPage.8r96ryw7.js +0 -3
  26. package/dist/McpPage.3cwh0gnd.js +0 -3
  27. package/dist/SettingsPage.ykgdh5ev.js +0 -3
  28. package/dist/SkillsPage.4np1s65b.js +0 -3
  29. package/dist/TasksPage.4g08t7p6.js +0 -3
  30. package/dist/TelemetryPage.72w9pwcp.js +0 -3
  31. package/dist/TestsPage.z4fk3r7r.js +0 -3
  32. package/dist/ThreadsPage.63tcajeh.js +0 -3
  33. package/dist/apteva-kit.css +0 -1
  34. package/dist/icon.png +0 -0
  35. package/dist/index.html +0 -16
  36. package/dist/styles.css +0 -1
  37. package/scripts/postinstall.mjs +0 -102
  38. package/src/auth/index.ts +0 -394
  39. package/src/auth/middleware.ts +0 -213
  40. package/src/binary.ts +0 -536
  41. package/src/channels/index.ts +0 -40
  42. package/src/channels/telegram.ts +0 -311
  43. package/src/crypto.ts +0 -301
  44. package/src/db-tests.ts +0 -174
  45. package/src/db.ts +0 -3133
  46. package/src/integrations/agentdojo.ts +0 -559
  47. package/src/integrations/composio.ts +0 -437
  48. package/src/integrations/index.ts +0 -87
  49. package/src/integrations/skillsmp.ts +0 -318
  50. package/src/mcp-client.ts +0 -605
  51. package/src/mcp-handler.ts +0 -394
  52. package/src/mcp-platform.ts +0 -2403
  53. package/src/openapi.ts +0 -2410
  54. package/src/providers.ts +0 -597
  55. package/src/routes/api/agent-utils.ts +0 -890
  56. package/src/routes/api/agents.ts +0 -916
  57. package/src/routes/api/api-keys.ts +0 -95
  58. package/src/routes/api/channels.ts +0 -182
  59. package/src/routes/api/helpers.ts +0 -12
  60. package/src/routes/api/integrations.ts +0 -639
  61. package/src/routes/api/mcp.ts +0 -574
  62. package/src/routes/api/meta-agent.ts +0 -195
  63. package/src/routes/api/projects.ts +0 -112
  64. package/src/routes/api/providers.ts +0 -424
  65. package/src/routes/api/skills.ts +0 -537
  66. package/src/routes/api/system.ts +0 -333
  67. package/src/routes/api/telemetry.ts +0 -203
  68. package/src/routes/api/tests.ts +0 -148
  69. package/src/routes/api/triggers.ts +0 -518
  70. package/src/routes/api/users.ts +0 -148
  71. package/src/routes/api/webhooks.ts +0 -171
  72. package/src/routes/api.ts +0 -53
  73. package/src/routes/auth.ts +0 -251
  74. package/src/routes/share.ts +0 -86
  75. package/src/routes/static.ts +0 -131
  76. package/src/server.ts +0 -642
  77. package/src/test-runner.ts +0 -598
  78. package/src/triggers/agentdojo.ts +0 -253
  79. package/src/triggers/composio.ts +0 -264
  80. package/src/triggers/index.ts +0 -71
  81. package/src/tui/AgentList.tsx +0 -145
  82. package/src/tui/App.tsx +0 -102
  83. package/src/tui/Login.tsx +0 -104
  84. package/src/tui/api.ts +0 -72
  85. package/src/tui/index.tsx +0 -7
  86. package/src/web/App.tsx +0 -455
  87. package/src/web/components/activity/ActivityPage.tsx +0 -314
  88. package/src/web/components/activity/index.ts +0 -1
  89. package/src/web/components/agents/AgentCard.tsx +0 -189
  90. package/src/web/components/agents/AgentPanel.tsx +0 -2244
  91. package/src/web/components/agents/AgentsView.tsx +0 -180
  92. package/src/web/components/agents/CreateAgentModal.tsx +0 -475
  93. package/src/web/components/agents/index.ts +0 -4
  94. package/src/web/components/api/ApiDocsPage.tsx +0 -842
  95. package/src/web/components/auth/CreateAccountStep.tsx +0 -176
  96. package/src/web/components/auth/LoginPage.tsx +0 -91
  97. package/src/web/components/auth/index.ts +0 -2
  98. package/src/web/components/common/Icons.tsx +0 -250
  99. package/src/web/components/common/LoadingSpinner.tsx +0 -44
  100. package/src/web/components/common/Modal.tsx +0 -199
  101. package/src/web/components/common/Select.tsx +0 -97
  102. package/src/web/components/common/index.ts +0 -20
  103. package/src/web/components/connections/ConnectionsPage.tsx +0 -54
  104. package/src/web/components/connections/IntegrationsTab.tsx +0 -170
  105. package/src/web/components/connections/OverviewTab.tsx +0 -137
  106. package/src/web/components/connections/TriggersTab.tsx +0 -1346
  107. package/src/web/components/dashboard/Dashboard.tsx +0 -572
  108. package/src/web/components/dashboard/index.ts +0 -1
  109. package/src/web/components/index.ts +0 -21
  110. package/src/web/components/layout/ErrorBanner.tsx +0 -18
  111. package/src/web/components/layout/Header.tsx +0 -332
  112. package/src/web/components/layout/Sidebar.tsx +0 -231
  113. package/src/web/components/layout/index.ts +0 -3
  114. package/src/web/components/mcp/IntegrationsPanel.tsx +0 -857
  115. package/src/web/components/mcp/McpPage.tsx +0 -2515
  116. package/src/web/components/mcp/index.ts +0 -1
  117. package/src/web/components/meta-agent/MetaAgent.tsx +0 -245
  118. package/src/web/components/onboarding/OnboardingWizard.tsx +0 -404
  119. package/src/web/components/onboarding/index.ts +0 -1
  120. package/src/web/components/settings/SettingsPage.tsx +0 -2776
  121. package/src/web/components/settings/index.ts +0 -1
  122. package/src/web/components/skills/SkillsPage.tsx +0 -1200
  123. package/src/web/components/tasks/TasksPage.tsx +0 -1116
  124. package/src/web/components/tasks/index.ts +0 -1
  125. package/src/web/components/telemetry/TelemetryPage.tsx +0 -1129
  126. package/src/web/components/tests/TestsPage.tsx +0 -594
  127. package/src/web/components/threads/ThreadsPage.tsx +0 -315
  128. package/src/web/context/AuthContext.tsx +0 -242
  129. package/src/web/context/ProjectContext.tsx +0 -214
  130. package/src/web/context/TelemetryContext.tsx +0 -299
  131. package/src/web/context/ThemeContext.tsx +0 -90
  132. package/src/web/context/UIModeContext.tsx +0 -49
  133. package/src/web/context/index.ts +0 -12
  134. package/src/web/hooks/index.ts +0 -3
  135. package/src/web/hooks/useAgents.ts +0 -115
  136. package/src/web/hooks/useOnboarding.ts +0 -20
  137. package/src/web/hooks/useProviders.ts +0 -75
  138. package/src/web/icon.png +0 -0
  139. package/src/web/index.html +0 -16
  140. package/src/web/styles.css +0 -118
  141. package/src/web/themes.ts +0 -162
  142. package/src/web/types.ts +0 -298
@@ -1,253 +0,0 @@
1
- // AgentDojo Trigger Provider
2
- // Uses our MCP API's subscription and trigger system
3
- // Docs: POST /subscribe, GET /subscriptions, GET /triggers
4
-
5
- import { createHmac, timingSafeEqual } from "crypto";
6
- import type { TriggerProvider, TriggerType, TriggerInstance } from "./index";
7
-
8
- const AGENTDOJO_API_BASE = process.env.AGENTDOJO_API_BASE || "https://api.agentdojo.dev";
9
-
10
- function headers(apiKey: string) {
11
- return { "X-API-Key": apiKey, "Content-Type": "application/json" };
12
- }
13
-
14
- export const AgentDojoTriggerProvider: TriggerProvider = {
15
- id: "agentdojo",
16
- name: "AgentDojo",
17
-
18
- async listTriggerTypes(apiKey: string, toolkitSlugs?: string[]): Promise<TriggerType[]> {
19
- const params = new URLSearchParams({ is_active: "true", limit: "500" });
20
- if (toolkitSlugs?.length) {
21
- // Filter by toolkit name(s) — API supports one at a time, so fetch each
22
- const allItems: any[] = [];
23
- for (const slug of toolkitSlugs) {
24
- const res = await fetch(
25
- `${AGENTDOJO_API_BASE}/triggers?${new URLSearchParams({ toolkit_name: slug, is_active: "true", limit: "500" })}`,
26
- { headers: headers(apiKey) },
27
- );
28
- if (res.ok) {
29
- const data = await res.json();
30
- const items = data.data || data.triggers || [];
31
- allItems.push(...items);
32
- }
33
- }
34
- return mapTriggerTypes(allItems);
35
- }
36
-
37
- const res = await fetch(`${AGENTDOJO_API_BASE}/triggers?${params}`, {
38
- headers: headers(apiKey),
39
- });
40
-
41
- if (!res.ok) {
42
- console.error("AgentDojo listTriggerTypes error:", res.status, await res.text());
43
- return [];
44
- }
45
-
46
- const data = await res.json();
47
- const items = data.data || data.triggers || [];
48
- return mapTriggerTypes(items);
49
- },
50
-
51
- async getTriggerType(apiKey: string, slug: string): Promise<TriggerType | null> {
52
- const res = await fetch(
53
- `${AGENTDOJO_API_BASE}/triggers/${encodeURIComponent(slug)}`,
54
- { headers: headers(apiKey) },
55
- );
56
-
57
- if (!res.ok) {
58
- if (res.status === 404) return null;
59
- console.error("AgentDojo getTriggerType error:", res.status, await res.text());
60
- return null;
61
- }
62
-
63
- const data = await res.json();
64
- const item = data.data || data;
65
- return {
66
- slug: item.slug,
67
- name: item.display_name || item.event_name || item.slug,
68
- description: item.description || "",
69
- type: (item.mechanism as "webhook" | "poll") || "webhook",
70
- toolkit_slug: item.toolkit?.name || item.toolkit_name || "",
71
- toolkit_name: item.toolkit?.display_name || item.toolkit_display_name || "",
72
- logo: item.toolkit?.icon_url || null,
73
- config_schema: item.config_schema || {},
74
- payload_schema: item.payload_schema || {},
75
- };
76
- },
77
-
78
- async createTrigger(
79
- apiKey: string,
80
- slug: string,
81
- connectedAccountId: string,
82
- config?: Record<string, unknown>,
83
- ): Promise<{ triggerId: string }> {
84
- // AgentDojo uses subscriptions — we create a subscription for this trigger
85
- // The callback_url should be set in config or from stored webhook URL
86
- const callbackUrl = (config?.callback_url as string) || "";
87
- if (!callbackUrl) {
88
- throw new Error("callback_url is required in config for AgentDojo triggers");
89
- }
90
-
91
- // Separate known top-level fields from extra config (e.g. owner, repo for GitHub)
92
- const { callback_url, title, events, server, prompt, agent_id, ...extraConfig } = config || {} as Record<string, unknown>;
93
-
94
- const body: Record<string, unknown> = {
95
- trigger_type_slug: slug,
96
- credential_id: connectedAccountId,
97
- callback_url: callbackUrl,
98
- title: (title as string) || `Trigger: ${slug}`,
99
- };
100
-
101
- if (events) body.events = events;
102
- if (server) body.server = server;
103
- if (prompt) body.prompt = prompt;
104
- if (agent_id) body.agent_id = agent_id;
105
-
106
- // Pass extra config fields (owner, repo, etc.) as the config object
107
- // mcp-subscribe spreads this into the webhook register payload
108
- if (Object.keys(extraConfig).length > 0) {
109
- body.config = extraConfig;
110
- console.log("AgentDojo createTrigger: extra config:", JSON.stringify(extraConfig));
111
- }
112
-
113
- const res = await fetch(`${AGENTDOJO_API_BASE}/subscribe`, {
114
- method: "POST",
115
- headers: headers(apiKey),
116
- body: JSON.stringify(body),
117
- });
118
-
119
- if (!res.ok) {
120
- const errText = await res.text();
121
- console.error("AgentDojo createTrigger error:", res.status, errText);
122
- throw new Error(`Failed to create AgentDojo subscription: ${errText}`);
123
- }
124
-
125
- const data = await res.json();
126
- return { triggerId: String(data.subscription_id || data.id) };
127
- },
128
-
129
- async listTriggers(apiKey: string): Promise<TriggerInstance[]> {
130
- const res = await fetch(`${AGENTDOJO_API_BASE}/subscriptions?status=active`, {
131
- headers: headers(apiKey),
132
- });
133
-
134
- if (!res.ok) {
135
- console.error("AgentDojo listTriggers error:", res.status, await res.text());
136
- return [];
137
- }
138
-
139
- const data = await res.json();
140
- const items = data.subscriptions || data.data || [];
141
-
142
- return items.map((item: any) => ({
143
- id: String(item.id || item.subscription_id),
144
- trigger_slug: item.title || item.server || "",
145
- connected_account_id: item.credential_id || null,
146
- status: item.status === "active" ? "active" as const : "disabled" as const,
147
- config: {
148
- server: item.server,
149
- events: item.events,
150
- callback_url: item.callback_url,
151
- prompt: item.prompt,
152
- title: item.title,
153
- },
154
- created_at: item.created_at || "",
155
- }));
156
- },
157
-
158
- async enableTrigger(apiKey: string, triggerId: string): Promise<boolean> {
159
- const res = await fetch(`${AGENTDOJO_API_BASE}/subscription/update`, {
160
- method: "POST",
161
- headers: headers(apiKey),
162
- body: JSON.stringify({ subscription_id: parseInt(triggerId), status: "active" }),
163
- });
164
- return res.ok;
165
- },
166
-
167
- async disableTrigger(apiKey: string, triggerId: string): Promise<boolean> {
168
- const res = await fetch(`${AGENTDOJO_API_BASE}/subscription/update`, {
169
- method: "POST",
170
- headers: headers(apiKey),
171
- body: JSON.stringify({ subscription_id: parseInt(triggerId), status: "disabled" }),
172
- });
173
- return res.ok;
174
- },
175
-
176
- async deleteTrigger(apiKey: string, triggerId: string): Promise<boolean> {
177
- const res = await fetch(`${AGENTDOJO_API_BASE}/unsubscribe`, {
178
- method: "POST",
179
- headers: headers(apiKey),
180
- body: JSON.stringify({ subscription_id: parseInt(triggerId) }),
181
- });
182
- return res.ok;
183
- },
184
-
185
- async setupWebhook(apiKey: string, webhookUrl: string): Promise<{ secret?: string }> {
186
- // AgentDojo uses per-subscription callback URLs, not a global webhook.
187
- // We just store the base URL locally — it will be passed when creating subscriptions.
188
- // No remote API call needed.
189
- return {};
190
- },
191
-
192
- async getWebhookConfig(apiKey: string): Promise<{ url: string | null; secret: string | null }> {
193
- // AgentDojo doesn't have a global webhook config — each subscription has its own callback_url.
194
- // Return null to indicate per-subscription mode.
195
- return { url: null, secret: null };
196
- },
197
-
198
- verifyWebhook(req: Request, body: string, secret: string): boolean {
199
- // AgentDojo forwards webhooks with an HMAC signature
200
- const signature = req.headers.get("x-webhook-signature") || "";
201
- if (!signature) {
202
- // If no signature header, check for a simple shared token
203
- const token = req.headers.get("x-webhook-token") || "";
204
- return token === secret;
205
- }
206
-
207
- // HMAC-SHA256 verification: signature is "sha256=<hex>"
208
- const sig = signature.startsWith("sha256=") ? signature.slice(7) : signature;
209
-
210
- try {
211
- const expected = createHmac("sha256", secret).update(body).digest("hex");
212
- return timingSafeEqual(Buffer.from(sig, "hex"), Buffer.from(expected, "hex"));
213
- } catch {
214
- return false;
215
- }
216
- },
217
-
218
- parseWebhookPayload(body: Record<string, unknown>): {
219
- triggerSlug: string;
220
- triggerInstanceId: string | null;
221
- payload: Record<string, unknown>;
222
- } {
223
- // AgentDojo forwarded payload format:
224
- // { type: "webhook", server: "stripe-payments", event: "payment_intent.succeeded",
225
- // data: { ... }, prompt: "...", subscription_id: 123, timestamp: "..." }
226
-
227
- const server = (body.server as string) || "";
228
- const event = (body.event as string) || "";
229
- const triggerSlug = event ? `${server}:${event}` : server || (body.type as string) || "unknown";
230
-
231
- const triggerInstanceId = body.subscription_id
232
- ? String(body.subscription_id)
233
- : null;
234
-
235
- const payload = (body.data as Record<string, unknown>) || {};
236
-
237
- return { triggerSlug, triggerInstanceId, payload };
238
- },
239
- };
240
-
241
- function mapTriggerTypes(items: any[]): TriggerType[] {
242
- return items.map((item: any) => ({
243
- slug: item.slug,
244
- name: item.display_name || item.event_name || item.slug,
245
- description: item.description || "",
246
- type: (item.mechanism as "webhook" | "poll") || "webhook",
247
- toolkit_slug: item.toolkit?.name || item.toolkit_name || "",
248
- toolkit_name: item.toolkit?.display_name || item.toolkit_display_name || "",
249
- logo: item.toolkit?.icon_url || null,
250
- config_schema: item.config_schema || {},
251
- payload_schema: item.payload_schema || {},
252
- }));
253
- }
@@ -1,264 +0,0 @@
1
- // Composio Trigger Provider
2
- // https://docs.composio.dev/api-reference/triggers
3
-
4
- import { createHmac, timingSafeEqual } from "crypto";
5
- import type { TriggerProvider, TriggerType, TriggerInstance } from "./index";
6
-
7
- const COMPOSIO_API_BASE = "https://backend.composio.dev";
8
-
9
- function headers(apiKey: string) {
10
- return { "x-api-key": apiKey, "Content-Type": "application/json" };
11
- }
12
-
13
- export const ComposioTriggerProvider: TriggerProvider = {
14
- id: "composio",
15
- name: "Composio",
16
-
17
- async listTriggerTypes(apiKey: string, toolkitSlugs?: string[]): Promise<TriggerType[]> {
18
- const params = new URLSearchParams();
19
- if (toolkitSlugs?.length) {
20
- params.set("toolkit_slugs", toolkitSlugs.join(","));
21
- }
22
-
23
- const res = await fetch(`${COMPOSIO_API_BASE}/api/v3/triggers_types?${params}`, {
24
- headers: headers(apiKey),
25
- });
26
-
27
- if (!res.ok) {
28
- console.error("Composio listTriggerTypes error:", res.status, await res.text());
29
- return [];
30
- }
31
-
32
- const data = await res.json();
33
- const items = data.items || data || [];
34
-
35
- return items.map((item: any) => ({
36
- slug: item.slug || item.enum,
37
- name: item.name || item.slug,
38
- description: item.description || "",
39
- type: item.type || "webhook",
40
- toolkit_slug: item.toolkit?.slug || item.app_slug || "",
41
- toolkit_name: item.toolkit?.name || item.app_name || "",
42
- logo: item.toolkit?.logo || item.logo || null,
43
- config_schema: item.config || {},
44
- payload_schema: item.payload || {},
45
- }));
46
- },
47
-
48
- async getTriggerType(apiKey: string, slug: string): Promise<TriggerType | null> {
49
- const res = await fetch(`${COMPOSIO_API_BASE}/api/v3/triggers_types/${encodeURIComponent(slug)}`, {
50
- headers: headers(apiKey),
51
- });
52
-
53
- if (!res.ok) {
54
- if (res.status === 404) return null;
55
- console.error("Composio getTriggerType error:", res.status, await res.text());
56
- return null;
57
- }
58
-
59
- const item = await res.json();
60
- return {
61
- slug: item.slug || item.enum,
62
- name: item.name || item.slug,
63
- description: item.description || "",
64
- type: item.type || "webhook",
65
- toolkit_slug: item.toolkit?.slug || item.app_slug || "",
66
- toolkit_name: item.toolkit?.name || item.app_name || "",
67
- logo: item.toolkit?.logo || item.logo || null,
68
- config_schema: item.config || {},
69
- payload_schema: item.payload || {},
70
- };
71
- },
72
-
73
- async createTrigger(
74
- apiKey: string,
75
- slug: string,
76
- connectedAccountId: string,
77
- config?: Record<string, unknown>,
78
- ): Promise<{ triggerId: string }> {
79
- const body: any = {
80
- connected_account_id: connectedAccountId,
81
- };
82
- if (config) {
83
- body.trigger_config = config;
84
- }
85
-
86
- const res = await fetch(
87
- `${COMPOSIO_API_BASE}/api/v3/trigger_instances/${encodeURIComponent(slug)}/upsert`,
88
- {
89
- method: "POST",
90
- headers: headers(apiKey),
91
- body: JSON.stringify(body),
92
- },
93
- );
94
-
95
- if (!res.ok) {
96
- const errText = await res.text();
97
- console.error("Composio createTrigger error:", res.status, errText);
98
- throw new Error(`Failed to create trigger: ${errText}`);
99
- }
100
-
101
- const data = await res.json();
102
- return { triggerId: data.trigger_id || data.deprecated?.uuid || data.id };
103
- },
104
-
105
- async listTriggers(apiKey: string): Promise<TriggerInstance[]> {
106
- const res = await fetch(`${COMPOSIO_API_BASE}/api/v3/trigger_instances/active`, {
107
- headers: headers(apiKey),
108
- });
109
-
110
- if (!res.ok) {
111
- console.error("Composio listTriggers error:", res.status, await res.text());
112
- return [];
113
- }
114
-
115
- const data = await res.json();
116
- const items = data.items || data.triggers || data || [];
117
-
118
- return items.map((item: any) => ({
119
- id: item.id || item.trigger_id,
120
- trigger_slug: item.trigger_name || item.trigger_slug || item.slug || "",
121
- connected_account_id: item.connected_account_id || item.connectedAccountId || null,
122
- status: item.disabled ? "disabled" : "active",
123
- config: item.trigger_config || item.triggerConfig || {},
124
- created_at: item.created_at || item.createdAt || "",
125
- }));
126
- },
127
-
128
- async enableTrigger(apiKey: string, triggerId: string): Promise<boolean> {
129
- const res = await fetch(
130
- `${COMPOSIO_API_BASE}/api/v3/trigger_instances/manage/${encodeURIComponent(triggerId)}`,
131
- {
132
- method: "PATCH",
133
- headers: headers(apiKey),
134
- body: JSON.stringify({ status: "enable" }),
135
- },
136
- );
137
- return res.ok;
138
- },
139
-
140
- async disableTrigger(apiKey: string, triggerId: string): Promise<boolean> {
141
- const res = await fetch(
142
- `${COMPOSIO_API_BASE}/api/v3/trigger_instances/manage/${encodeURIComponent(triggerId)}`,
143
- {
144
- method: "PATCH",
145
- headers: headers(apiKey),
146
- body: JSON.stringify({ status: "disable" }),
147
- },
148
- );
149
- return res.ok;
150
- },
151
-
152
- async deleteTrigger(apiKey: string, triggerId: string): Promise<boolean> {
153
- const res = await fetch(
154
- `${COMPOSIO_API_BASE}/api/v3/trigger_instances/manage/${encodeURIComponent(triggerId)}`,
155
- {
156
- method: "DELETE",
157
- headers: headers(apiKey),
158
- },
159
- );
160
- return res.ok;
161
- },
162
-
163
- async setupWebhook(apiKey: string, webhookUrl: string): Promise<{ secret?: string }> {
164
- // Use webhook_subscriptions API (requires HTTPS)
165
- const res = await fetch(`${COMPOSIO_API_BASE}/api/v3/webhook_subscriptions`, {
166
- method: "POST",
167
- headers: headers(apiKey),
168
- body: JSON.stringify({
169
- webhook_url: webhookUrl,
170
- enabled_events: ["composio.trigger.message"],
171
- version: "V3",
172
- }),
173
- });
174
-
175
- if (!res.ok) {
176
- const errText = await res.text();
177
- console.error("Composio setupWebhook error:", res.status, errText);
178
- throw new Error(`Failed to set webhook URL: ${errText}`);
179
- }
180
-
181
- const data = await res.json();
182
- const secret = data.secret || data.webhook_secret || undefined;
183
- return { secret };
184
- },
185
-
186
- async getWebhookConfig(apiKey: string): Promise<{ url: string | null; secret: string | null }> {
187
- const res = await fetch(`${COMPOSIO_API_BASE}/api/v3/webhook_subscriptions`, {
188
- headers: headers(apiKey),
189
- });
190
-
191
- if (!res.ok) {
192
- console.error("Composio getWebhookConfig error:", res.status, await res.text());
193
- return { url: null, secret: null };
194
- }
195
-
196
- const data = await res.json();
197
- const items = data.items || data.subscriptions || (Array.isArray(data) ? data : [data]);
198
- const sub = items[0];
199
- return {
200
- url: sub?.webhook_url || sub?.callback_url || sub?.url || null,
201
- secret: sub?.secret || sub?.webhook_secret || null,
202
- };
203
- },
204
-
205
- verifyWebhook(req: Request, body: string, secret: string): boolean {
206
- const signature = req.headers.get("webhook-signature") || "";
207
- const webhookId = req.headers.get("webhook-id") || "";
208
- const timestamp = req.headers.get("webhook-timestamp") || "";
209
-
210
- if (!signature || !webhookId || !timestamp) return false;
211
-
212
- // Check timestamp freshness (5-minute window to prevent replay)
213
- const now = Math.floor(Date.now() / 1000);
214
- const ts = parseInt(timestamp, 10);
215
- if (isNaN(ts) || Math.abs(now - ts) > 300) return false;
216
-
217
- // Composio signature: HMAC-SHA256("{webhook-id}.{timestamp}.{body}", secret)
218
- const signedContent = `${webhookId}.${timestamp}.${body}`;
219
- const expectedSignature = createHmac("sha256", secret)
220
- .update(signedContent)
221
- .digest("base64");
222
-
223
- // Signature header format: "v1,<base64>"
224
- const sig = signature.startsWith("v1,") ? signature.slice(3) : signature;
225
-
226
- try {
227
- return timingSafeEqual(
228
- Buffer.from(sig, "base64"),
229
- Buffer.from(expectedSignature, "base64"),
230
- );
231
- } catch {
232
- return false;
233
- }
234
- },
235
-
236
- parseWebhookPayload(body: Record<string, unknown>): {
237
- triggerSlug: string;
238
- triggerInstanceId: string | null;
239
- payload: Record<string, unknown>;
240
- } {
241
- // V3 format: { type: "composio.trigger.message", metadata: { trigger_slug, trigger_id, ... }, data: { ... } }
242
- // V2/V1 format: { trigger_name, trigger_id, payload: { ... } }
243
- const metadata = (body.metadata as Record<string, unknown>) || {};
244
- const data = (body.data as Record<string, unknown>) || {};
245
-
246
- const triggerSlug =
247
- (metadata.trigger_slug as string) ||
248
- (body.trigger_name as string) ||
249
- ((body.type as string) !== "composio.trigger.message" ? (body.type as string) : null) ||
250
- "unknown";
251
-
252
- const triggerInstanceId =
253
- (metadata.trigger_id as string) ||
254
- (body.trigger_id as string) ||
255
- (body.triggerId as string) ||
256
- null;
257
-
258
- const payload =
259
- (body.payload as Record<string, unknown>) ||
260
- data;
261
-
262
- return { triggerSlug, triggerInstanceId, payload };
263
- },
264
- };
@@ -1,71 +0,0 @@
1
- // Generic Trigger Provider Interface
2
- // Allows multiple providers (Composio, AgentDojo, local, etc.) to offer trigger/webhook integrations
3
-
4
- export interface TriggerType {
5
- slug: string;
6
- name: string;
7
- description: string;
8
- type: "webhook" | "poll";
9
- toolkit_slug: string;
10
- toolkit_name: string;
11
- logo: string | null;
12
- config_schema: Record<string, unknown>;
13
- payload_schema: Record<string, unknown>;
14
- }
15
-
16
- export interface TriggerInstance {
17
- id: string;
18
- trigger_slug: string;
19
- connected_account_id: string | null;
20
- status: "active" | "disabled";
21
- config: Record<string, unknown>;
22
- created_at: string;
23
- }
24
-
25
- export interface TriggerProvider {
26
- id: string;
27
- name: string;
28
-
29
- // Browse available trigger types
30
- listTriggerTypes(apiKey: string, toolkitSlugs?: string[]): Promise<TriggerType[]>;
31
- getTriggerType(apiKey: string, slug: string): Promise<TriggerType | null>;
32
-
33
- // CRUD trigger instances (all remote)
34
- createTrigger(
35
- apiKey: string,
36
- slug: string,
37
- connectedAccountId: string,
38
- config?: Record<string, unknown>,
39
- ): Promise<{ triggerId: string }>;
40
- listTriggers(apiKey: string): Promise<TriggerInstance[]>;
41
- enableTrigger(apiKey: string, triggerId: string): Promise<boolean>;
42
- disableTrigger(apiKey: string, triggerId: string): Promise<boolean>;
43
- deleteTrigger(apiKey: string, triggerId: string): Promise<boolean>;
44
-
45
- // Webhook configuration
46
- setupWebhook(apiKey: string, webhookUrl: string): Promise<{ secret?: string }>;
47
- getWebhookConfig(apiKey: string): Promise<{ url: string | null; secret: string | null }>;
48
-
49
- // Webhook verification and parsing (each provider signs differently)
50
- verifyWebhook(req: Request, body: string, secret: string): boolean;
51
- parseWebhookPayload(body: Record<string, unknown>): {
52
- triggerSlug: string;
53
- triggerInstanceId: string | null;
54
- payload: Record<string, unknown>;
55
- };
56
- }
57
-
58
- // Provider registry
59
- const triggerProviders: Map<string, TriggerProvider> = new Map();
60
-
61
- export function registerTriggerProvider(provider: TriggerProvider) {
62
- triggerProviders.set(provider.id, provider);
63
- }
64
-
65
- export function getTriggerProvider(id: string): TriggerProvider | undefined {
66
- return triggerProviders.get(id);
67
- }
68
-
69
- export function getTriggerProviderIds(): string[] {
70
- return Array.from(triggerProviders.keys());
71
- }