apteva 0.2.7 → 0.2.9
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/App.m4hg4bxq.js +218 -0
- package/dist/index.html +4 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/auth/index.ts +386 -0
- package/src/auth/middleware.ts +183 -0
- package/src/binary.ts +19 -1
- package/src/db.ts +688 -45
- package/src/integrations/composio.ts +437 -0
- package/src/integrations/index.ts +80 -0
- package/src/openapi.ts +1724 -0
- package/src/routes/api.ts +1476 -118
- package/src/routes/auth.ts +242 -0
- package/src/server.ts +121 -11
- package/src/web/App.tsx +64 -19
- package/src/web/components/agents/AgentCard.tsx +24 -22
- package/src/web/components/agents/AgentPanel.tsx +810 -45
- package/src/web/components/agents/AgentsView.tsx +81 -9
- package/src/web/components/agents/CreateAgentModal.tsx +28 -1
- package/src/web/components/api/ApiDocsPage.tsx +583 -0
- package/src/web/components/auth/CreateAccountStep.tsx +176 -0
- package/src/web/components/auth/LoginPage.tsx +91 -0
- package/src/web/components/auth/index.ts +2 -0
- package/src/web/components/common/Icons.tsx +56 -0
- package/src/web/components/common/Modal.tsx +184 -1
- package/src/web/components/dashboard/Dashboard.tsx +70 -22
- package/src/web/components/index.ts +3 -0
- package/src/web/components/layout/Header.tsx +135 -18
- package/src/web/components/layout/Sidebar.tsx +87 -43
- package/src/web/components/mcp/IntegrationsPanel.tsx +743 -0
- package/src/web/components/mcp/McpPage.tsx +451 -63
- package/src/web/components/onboarding/OnboardingWizard.tsx +64 -8
- package/src/web/components/settings/SettingsPage.tsx +340 -26
- package/src/web/components/tasks/TasksPage.tsx +22 -20
- package/src/web/components/telemetry/TelemetryPage.tsx +163 -61
- package/src/web/context/AuthContext.tsx +230 -0
- package/src/web/context/ProjectContext.tsx +182 -0
- package/src/web/context/index.ts +5 -0
- package/src/web/hooks/useAgents.ts +18 -6
- package/src/web/hooks/useOnboarding.ts +20 -4
- package/src/web/hooks/useProviders.ts +15 -5
- package/src/web/icon.png +0 -0
- package/src/web/index.html +1 -1
- package/src/web/styles.css +12 -0
- package/src/web/types.ts +10 -1
- package/dist/App.3kb50qa3.js +0 -213
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from "react";
|
|
2
|
+
import { useAuth } from "./AuthContext";
|
|
3
|
+
|
|
4
|
+
export interface Project {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string | null;
|
|
8
|
+
color: string;
|
|
9
|
+
agentCount: number;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
updatedAt: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ProjectContextValue {
|
|
15
|
+
projects: Project[];
|
|
16
|
+
currentProjectId: string | null; // null = "All Projects", "unassigned" = unassigned agents
|
|
17
|
+
currentProject: Project | null;
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
error: string | null;
|
|
20
|
+
unassignedCount: number;
|
|
21
|
+
setCurrentProjectId: (id: string | null) => void;
|
|
22
|
+
createProject: (data: { name: string; description?: string; color?: string }) => Promise<Project | null>;
|
|
23
|
+
updateProject: (id: string, data: { name?: string; description?: string; color?: string }) => Promise<Project | null>;
|
|
24
|
+
deleteProject: (id: string) => Promise<boolean>;
|
|
25
|
+
refreshProjects: () => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const ProjectContext = createContext<ProjectContextValue | null>(null);
|
|
29
|
+
|
|
30
|
+
export function useProjects(): ProjectContextValue {
|
|
31
|
+
const context = useContext(ProjectContext);
|
|
32
|
+
if (!context) {
|
|
33
|
+
throw new Error("useProjects must be used within a ProjectProvider");
|
|
34
|
+
}
|
|
35
|
+
return context;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface ProjectProviderProps {
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const STORAGE_KEY = "apteva_current_project";
|
|
43
|
+
|
|
44
|
+
export function ProjectProvider({ children }: ProjectProviderProps) {
|
|
45
|
+
const { authFetch, isAuthenticated, isLoading: authLoading } = useAuth();
|
|
46
|
+
const [projects, setProjects] = useState<Project[]>([]);
|
|
47
|
+
const [currentProjectId, setCurrentProjectIdState] = useState<string | null>(() => {
|
|
48
|
+
// Load from localStorage
|
|
49
|
+
if (typeof window !== "undefined") {
|
|
50
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
});
|
|
54
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
55
|
+
const [error, setError] = useState<string | null>(null);
|
|
56
|
+
const [unassignedCount, setUnassignedCount] = useState(0);
|
|
57
|
+
|
|
58
|
+
const setCurrentProjectId = useCallback((id: string | null) => {
|
|
59
|
+
setCurrentProjectIdState(id);
|
|
60
|
+
if (typeof window !== "undefined") {
|
|
61
|
+
if (id === null) {
|
|
62
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
63
|
+
} else {
|
|
64
|
+
localStorage.setItem(STORAGE_KEY, id);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}, []);
|
|
68
|
+
|
|
69
|
+
const currentProject = projects.find(p => p.id === currentProjectId) || null;
|
|
70
|
+
|
|
71
|
+
const refreshProjects = useCallback(async () => {
|
|
72
|
+
if (!isAuthenticated && !authLoading) {
|
|
73
|
+
setProjects([]);
|
|
74
|
+
setIsLoading(false);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
setError(null);
|
|
80
|
+
const res = await authFetch("/api/projects");
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
throw new Error("Failed to fetch projects");
|
|
83
|
+
}
|
|
84
|
+
const data = await res.json();
|
|
85
|
+
setProjects(data.projects || []);
|
|
86
|
+
setUnassignedCount(data.unassignedCount || 0);
|
|
87
|
+
|
|
88
|
+
// If current project no longer exists, reset to all
|
|
89
|
+
if (currentProjectId && currentProjectId !== "unassigned" && !data.projects.find((p: Project) => p.id === currentProjectId)) {
|
|
90
|
+
setCurrentProjectId(null);
|
|
91
|
+
}
|
|
92
|
+
} catch (e) {
|
|
93
|
+
console.error("Failed to fetch projects:", e);
|
|
94
|
+
setError("Failed to load projects");
|
|
95
|
+
} finally {
|
|
96
|
+
setIsLoading(false);
|
|
97
|
+
}
|
|
98
|
+
}, [authFetch, isAuthenticated, authLoading, currentProjectId, setCurrentProjectId]);
|
|
99
|
+
|
|
100
|
+
const createProject = useCallback(async (data: { name: string; description?: string; color?: string }): Promise<Project | null> => {
|
|
101
|
+
try {
|
|
102
|
+
const res = await authFetch("/api/projects", {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: { "Content-Type": "application/json" },
|
|
105
|
+
body: JSON.stringify(data),
|
|
106
|
+
});
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
const err = await res.json();
|
|
109
|
+
throw new Error(err.error || "Failed to create project");
|
|
110
|
+
}
|
|
111
|
+
const result = await res.json();
|
|
112
|
+
await refreshProjects();
|
|
113
|
+
return result.project;
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.error("Failed to create project:", e);
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}, [authFetch, refreshProjects]);
|
|
119
|
+
|
|
120
|
+
const updateProject = useCallback(async (id: string, data: { name?: string; description?: string; color?: string }): Promise<Project | null> => {
|
|
121
|
+
try {
|
|
122
|
+
const res = await authFetch(`/api/projects/${id}`, {
|
|
123
|
+
method: "PUT",
|
|
124
|
+
headers: { "Content-Type": "application/json" },
|
|
125
|
+
body: JSON.stringify(data),
|
|
126
|
+
});
|
|
127
|
+
if (!res.ok) {
|
|
128
|
+
const err = await res.json();
|
|
129
|
+
throw new Error(err.error || "Failed to update project");
|
|
130
|
+
}
|
|
131
|
+
const result = await res.json();
|
|
132
|
+
await refreshProjects();
|
|
133
|
+
return result.project;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error("Failed to update project:", e);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}, [authFetch, refreshProjects]);
|
|
139
|
+
|
|
140
|
+
const deleteProject = useCallback(async (id: string): Promise<boolean> => {
|
|
141
|
+
try {
|
|
142
|
+
const res = await authFetch(`/api/projects/${id}`, {
|
|
143
|
+
method: "DELETE",
|
|
144
|
+
});
|
|
145
|
+
if (!res.ok) {
|
|
146
|
+
const err = await res.json();
|
|
147
|
+
throw new Error(err.error || "Failed to delete project");
|
|
148
|
+
}
|
|
149
|
+
if (currentProjectId === id) {
|
|
150
|
+
setCurrentProjectId(null);
|
|
151
|
+
}
|
|
152
|
+
await refreshProjects();
|
|
153
|
+
return true;
|
|
154
|
+
} catch (e) {
|
|
155
|
+
console.error("Failed to delete project:", e);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}, [authFetch, currentProjectId, setCurrentProjectId, refreshProjects]);
|
|
159
|
+
|
|
160
|
+
// Fetch projects when authenticated
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (!authLoading) {
|
|
163
|
+
refreshProjects();
|
|
164
|
+
}
|
|
165
|
+
}, [authLoading, refreshProjects]);
|
|
166
|
+
|
|
167
|
+
const value: ProjectContextValue = {
|
|
168
|
+
projects,
|
|
169
|
+
currentProjectId,
|
|
170
|
+
currentProject,
|
|
171
|
+
isLoading,
|
|
172
|
+
error,
|
|
173
|
+
unassignedCount,
|
|
174
|
+
setCurrentProjectId,
|
|
175
|
+
createProject,
|
|
176
|
+
updateProject,
|
|
177
|
+
deleteProject,
|
|
178
|
+
refreshProjects,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
return <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>;
|
|
182
|
+
}
|
package/src/web/context/index.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export { TelemetryProvider, useTelemetryContext, useTelemetry, useAgentActivity } from "./TelemetryContext";
|
|
2
2
|
export type { TelemetryEvent } from "./TelemetryContext";
|
|
3
|
+
|
|
4
|
+
export { AuthProvider, useAuth, useAuthHeaders } from "./AuthContext";
|
|
5
|
+
|
|
6
|
+
export { ProjectProvider, useProjects } from "./ProjectContext";
|
|
7
|
+
export type { Project } from "./ProjectContext";
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from "react";
|
|
2
2
|
import type { Agent, AgentFeatures } from "../types";
|
|
3
|
+
import { useAuth } from "../context";
|
|
3
4
|
|
|
4
5
|
export function useAgents(enabled: boolean) {
|
|
6
|
+
const { accessToken } = useAuth();
|
|
5
7
|
const [agents, setAgents] = useState<Agent[]>([]);
|
|
6
8
|
const [loading, setLoading] = useState(true);
|
|
7
9
|
|
|
10
|
+
const getHeaders = useCallback((): Record<string, string> => {
|
|
11
|
+
const headers: Record<string, string> = { "Content-Type": "application/json" };
|
|
12
|
+
if (accessToken) {
|
|
13
|
+
headers.Authorization = `Bearer ${accessToken}`;
|
|
14
|
+
}
|
|
15
|
+
return headers;
|
|
16
|
+
}, [accessToken]);
|
|
17
|
+
|
|
8
18
|
const fetchAgents = useCallback(async () => {
|
|
9
|
-
const res = await fetch("/api/agents");
|
|
19
|
+
const res = await fetch("/api/agents", { headers: getHeaders() });
|
|
10
20
|
const data = await res.json();
|
|
11
21
|
setAgents(data.agents || []);
|
|
12
22
|
setLoading(false);
|
|
13
|
-
}, []);
|
|
23
|
+
}, [getHeaders]);
|
|
14
24
|
|
|
15
25
|
useEffect(() => {
|
|
16
26
|
if (enabled) {
|
|
@@ -25,17 +35,18 @@ export function useAgents(enabled: boolean) {
|
|
|
25
35
|
systemPrompt: string;
|
|
26
36
|
features: AgentFeatures;
|
|
27
37
|
mcpServers?: string[];
|
|
38
|
+
projectId?: string | null;
|
|
28
39
|
}) => {
|
|
29
40
|
await fetch("/api/agents", {
|
|
30
41
|
method: "POST",
|
|
31
|
-
headers:
|
|
42
|
+
headers: getHeaders(),
|
|
32
43
|
body: JSON.stringify(agent),
|
|
33
44
|
});
|
|
34
45
|
await fetchAgents();
|
|
35
46
|
};
|
|
36
47
|
|
|
37
48
|
const deleteAgent = async (id: string) => {
|
|
38
|
-
await fetch(`/api/agents/${id}`, { method: "DELETE" });
|
|
49
|
+
await fetch(`/api/agents/${id}`, { method: "DELETE", headers: getHeaders() });
|
|
39
50
|
await fetchAgents();
|
|
40
51
|
};
|
|
41
52
|
|
|
@@ -46,10 +57,11 @@ export function useAgents(enabled: boolean) {
|
|
|
46
57
|
systemPrompt?: string;
|
|
47
58
|
features?: AgentFeatures;
|
|
48
59
|
mcpServers?: string[];
|
|
60
|
+
projectId?: string | null;
|
|
49
61
|
}): Promise<{ error?: string }> => {
|
|
50
62
|
const res = await fetch(`/api/agents/${id}`, {
|
|
51
63
|
method: "PUT",
|
|
52
|
-
headers:
|
|
64
|
+
headers: getHeaders(),
|
|
53
65
|
body: JSON.stringify(updates),
|
|
54
66
|
});
|
|
55
67
|
const data = await res.json();
|
|
@@ -62,7 +74,7 @@ export function useAgents(enabled: boolean) {
|
|
|
62
74
|
|
|
63
75
|
const toggleAgent = async (agent: Agent): Promise<{ error?: string }> => {
|
|
64
76
|
const action = agent.status === "running" ? "stop" : "start";
|
|
65
|
-
const res = await fetch(`/api/agents/${agent.id}/${action}`, { method: "POST" });
|
|
77
|
+
const res = await fetch(`/api/agents/${agent.id}/${action}`, { method: "POST", headers: getHeaders() });
|
|
66
78
|
const data = await res.json();
|
|
67
79
|
await fetchAgents();
|
|
68
80
|
if (!res.ok && data.error) {
|
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { useAuth } from "../context";
|
|
2
3
|
|
|
3
4
|
export function useOnboarding() {
|
|
5
|
+
const { accessToken, isAuthenticated } = useAuth();
|
|
4
6
|
const [isComplete, setIsComplete] = useState<boolean | null>(null);
|
|
5
7
|
|
|
8
|
+
const getHeaders = useCallback((): Record<string, string> => {
|
|
9
|
+
const headers: Record<string, string> = {};
|
|
10
|
+
if (accessToken) {
|
|
11
|
+
headers.Authorization = `Bearer ${accessToken}`;
|
|
12
|
+
}
|
|
13
|
+
return headers;
|
|
14
|
+
}, [accessToken]);
|
|
15
|
+
|
|
6
16
|
useEffect(() => {
|
|
7
|
-
|
|
17
|
+
// Only check onboarding status when authenticated
|
|
18
|
+
if (!isAuthenticated) {
|
|
19
|
+
setIsComplete(null);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fetch("/api/onboarding/status", { headers: getHeaders() })
|
|
8
24
|
.then(res => res.json())
|
|
9
25
|
.then(data => {
|
|
10
26
|
setIsComplete(data.completed || data.has_any_keys);
|
|
11
27
|
})
|
|
12
28
|
.catch(() => setIsComplete(true)); // Fallback to showing app
|
|
13
|
-
}, []);
|
|
29
|
+
}, [isAuthenticated, getHeaders]);
|
|
14
30
|
|
|
15
31
|
const complete = useCallback(async () => {
|
|
16
|
-
await fetch("/api/onboarding/complete", { method: "POST" });
|
|
32
|
+
await fetch("/api/onboarding/complete", { method: "POST", headers: getHeaders() });
|
|
17
33
|
setIsComplete(true);
|
|
18
|
-
}, []);
|
|
34
|
+
}, [getHeaders]);
|
|
19
35
|
|
|
20
36
|
return {
|
|
21
37
|
isComplete,
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from "react";
|
|
2
2
|
import type { Provider } from "../types";
|
|
3
|
+
import { useAuth } from "../context";
|
|
3
4
|
|
|
4
5
|
export function useProviders(enabled: boolean) {
|
|
6
|
+
const { accessToken } = useAuth();
|
|
5
7
|
const [providers, setProviders] = useState<Provider[]>([]);
|
|
6
8
|
|
|
9
|
+
const getHeaders = useCallback((): Record<string, string> => {
|
|
10
|
+
const headers: Record<string, string> = { "Content-Type": "application/json" };
|
|
11
|
+
if (accessToken) {
|
|
12
|
+
headers.Authorization = `Bearer ${accessToken}`;
|
|
13
|
+
}
|
|
14
|
+
return headers;
|
|
15
|
+
}, [accessToken]);
|
|
16
|
+
|
|
7
17
|
const fetchProviders = useCallback(async () => {
|
|
8
|
-
const res = await fetch("/api/providers");
|
|
18
|
+
const res = await fetch("/api/providers", { headers: getHeaders() });
|
|
9
19
|
const data = await res.json();
|
|
10
20
|
setProviders(data.providers || []);
|
|
11
|
-
}, []);
|
|
21
|
+
}, [getHeaders]);
|
|
12
22
|
|
|
13
23
|
useEffect(() => {
|
|
14
24
|
if (enabled) {
|
|
@@ -25,7 +35,7 @@ export function useProviders(enabled: boolean) {
|
|
|
25
35
|
// First test the key
|
|
26
36
|
const testRes = await fetch(`/api/keys/${providerId}/test`, {
|
|
27
37
|
method: "POST",
|
|
28
|
-
headers:
|
|
38
|
+
headers: getHeaders(),
|
|
29
39
|
body: JSON.stringify({ key: apiKey }),
|
|
30
40
|
});
|
|
31
41
|
const testData = await testRes.json();
|
|
@@ -37,7 +47,7 @@ export function useProviders(enabled: boolean) {
|
|
|
37
47
|
// Save the key
|
|
38
48
|
const saveRes = await fetch(`/api/keys/${providerId}`, {
|
|
39
49
|
method: "POST",
|
|
40
|
-
headers:
|
|
50
|
+
headers: getHeaders(),
|
|
41
51
|
body: JSON.stringify({ key: apiKey }),
|
|
42
52
|
});
|
|
43
53
|
|
|
@@ -51,7 +61,7 @@ export function useProviders(enabled: boolean) {
|
|
|
51
61
|
};
|
|
52
62
|
|
|
53
63
|
const deleteKey = async (providerId: string) => {
|
|
54
|
-
await fetch(`/api/keys/${providerId}`, { method: "DELETE" });
|
|
64
|
+
await fetch(`/api/keys/${providerId}`, { method: "DELETE", headers: getHeaders() });
|
|
55
65
|
await fetchProviders();
|
|
56
66
|
};
|
|
57
67
|
|
package/src/web/icon.png
ADDED
|
Binary file
|
package/src/web/index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>
|
|
6
|
+
<title>Apteva</title>
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
package/src/web/styles.css
CHANGED
|
@@ -39,3 +39,15 @@ html, body {
|
|
|
39
39
|
.scrollbar-hide::-webkit-scrollbar {
|
|
40
40
|
display: none;
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
/* Telemetry event slide-in animation */
|
|
44
|
+
@keyframes slideIn {
|
|
45
|
+
from {
|
|
46
|
+
opacity: 0;
|
|
47
|
+
transform: translateY(-8px);
|
|
48
|
+
}
|
|
49
|
+
to {
|
|
50
|
+
opacity: 1;
|
|
51
|
+
transform: translateY(0);
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/web/types.ts
CHANGED
|
@@ -7,6 +7,8 @@ export interface AgentFeatures {
|
|
|
7
7
|
operator: boolean;
|
|
8
8
|
mcp: boolean;
|
|
9
9
|
realtime: boolean;
|
|
10
|
+
files: boolean;
|
|
11
|
+
agents: boolean;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export const DEFAULT_FEATURES: AgentFeatures = {
|
|
@@ -16,6 +18,8 @@ export const DEFAULT_FEATURES: AgentFeatures = {
|
|
|
16
18
|
operator: false,
|
|
17
19
|
mcp: false,
|
|
18
20
|
realtime: false,
|
|
21
|
+
files: false,
|
|
22
|
+
agents: false,
|
|
19
23
|
};
|
|
20
24
|
|
|
21
25
|
export interface McpServerSummary {
|
|
@@ -37,6 +41,7 @@ export interface Agent {
|
|
|
37
41
|
features: AgentFeatures;
|
|
38
42
|
mcpServers: string[]; // Array of MCP server IDs
|
|
39
43
|
mcpServerDetails?: McpServerSummary[]; // Full details included from API
|
|
44
|
+
projectId: string | null; // Optional project grouping
|
|
40
45
|
createdAt: string;
|
|
41
46
|
}
|
|
42
47
|
|
|
@@ -46,8 +51,11 @@ export interface McpServer {
|
|
|
46
51
|
type: "npm" | "github" | "http" | "custom";
|
|
47
52
|
package: string | null;
|
|
48
53
|
command: string | null;
|
|
54
|
+
url: string | null;
|
|
55
|
+
headers: Record<string, string>;
|
|
49
56
|
port: number | null;
|
|
50
57
|
status: "stopped" | "running";
|
|
58
|
+
source: string | null; // "composio", "smithery", or null for local
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
export interface McpTool {
|
|
@@ -91,7 +99,7 @@ export interface OnboardingStatus {
|
|
|
91
99
|
has_any_keys: boolean;
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
export type Route = "dashboard" | "agents" | "tasks" | "mcp" | "telemetry" | "settings";
|
|
102
|
+
export type Route = "dashboard" | "agents" | "tasks" | "mcp" | "telemetry" | "settings" | "api";
|
|
95
103
|
|
|
96
104
|
export interface Task {
|
|
97
105
|
id: string;
|
|
@@ -134,4 +142,5 @@ export interface NewAgentForm {
|
|
|
134
142
|
systemPrompt: string;
|
|
135
143
|
features: AgentFeatures;
|
|
136
144
|
mcpServers: string[];
|
|
145
|
+
projectId?: string | null;
|
|
137
146
|
}
|