Merge pull request #920 from escapade-mckv/cleanup-main

fix: frontend mcp type fix
This commit is contained in:
Bobbie 2025-07-09 20:07:43 +05:30 committed by GitHub
commit 6f9c8147ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 105 additions and 19 deletions

View File

@ -289,7 +289,10 @@ export const CreateAgentDialog = ({ isOpen, onOpenChange, onAgentCreated }: Crea
<TabsContent value="mcp" className="flex-1 m-0 p-6 overflow-y-auto">
<MCPConfigurationNew
configuredMCPs={formData.configured_mcps}
configuredMCPs={formData.configured_mcps.map(mcp => ({
...mcp,
enabledTools: mcp.enabledTools || []
}))}
onConfigurationChange={handleMCPConfigurationChange}
/>
</TabsContent>

View File

@ -393,14 +393,20 @@ export const UpdateAgentDialog = ({ agentId, isOpen, onOpenChange, onAgentUpdate
<TabsContent value="mcp" className="flex-1 m-0 p-6 overflow-y-auto">
<MCPConfigurationNew
configuredMCPs={[...(formData.configured_mcps || []), ...(formData.custom_mcps || []).map(customMcp => ({
name: customMcp.name,
qualifiedName: `custom_${customMcp.type}_${customMcp.name.replace(' ', '_').toLowerCase()}`,
config: customMcp.config,
enabledTools: customMcp.enabledTools,
isCustom: true,
customType: customMcp.type
}))]}
configuredMCPs={[
...(formData.configured_mcps || []).map(mcp => ({
...mcp,
enabledTools: mcp.enabledTools || []
})),
...(formData.custom_mcps || []).map(customMcp => ({
name: customMcp.name,
qualifiedName: `custom_${customMcp.type}_${customMcp.name.replace(' ', '_').toLowerCase()}`,
config: customMcp.config,
enabledTools: customMcp.enabledTools,
isCustom: true,
customType: customMcp.type
}))
]}
onConfigurationChange={handleMCPConfigurationChange}
/>
</TabsContent>

View File

@ -86,15 +86,25 @@ export const PipedreamAppBrowser: React.FC<PipedreamAppBrowserProps> = ({
<div className="space-y-4">
<div className="flex gap-2">
<div className="relative flex-1">
<form onSubmit={(e) => {e.preventDefault()}} className="relative flex-1">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input
placeholder="Search apps..."
placeholder="Search apps... (e.g., Gmail, Slack, Notion)"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10"
/>
</div>
{searchQuery && (
<Button
type="submit"
size="sm"
variant="ghost"
className="absolute right-1 top-1/2 transform -translate-y-1/2 h-8 px-2"
>
Search
</Button>
)}
</form>
{selectedCategory && (
<Button
variant="outline"

View File

@ -66,6 +66,11 @@ export const PipedreamRegistry: React.FC<PipedreamRegistryProps> = ({
setPage(1);
};
const handleSearchSubmit = (e: React.FormEvent) => {
e.preventDefault();
refetch();
};
const handleCategorySelect = (category: string) => {
setSelectedCategory(category === selectedCategory ? '' : category);
setPage(1);
@ -281,15 +286,25 @@ export const PipedreamRegistry: React.FC<PipedreamRegistryProps> = ({
</p>
</div>
</div>
<div className="relative">
<form onSubmit={handleSearchSubmit} className="relative">
<Search className="absolute left-2.5 top-1/2 transform -translate-y-1/2 h-3 w-3 text-muted-foreground" />
<Input
placeholder="Search apps..."
placeholder="Search apps... (e.g., Gmail, Slack, Notion)"
value={search}
onChange={(e) => handleSearch(e.target.value)}
className="pl-8 h-8 text-sm"
/>
</div>
{search && (
<Button
type="submit"
size="sm"
variant="ghost"
className="absolute right-1 top-1/2 transform -translate-y-1/2 h-6 px-2"
>
Search
</Button>
)}
</form>
</div>
<div className="flex-1 overflow-auto p-4">
{isLoading && (

View File

@ -7,6 +7,7 @@ export const pipedreamKeys = {
workflows: () => [...pipedreamKeys.all, 'workflows'] as const,
workflowRuns: (workflowId: string) => [...pipedreamKeys.all, 'workflow-runs', workflowId] as const,
apps: (page: number, search?: string, category?: string) => [...pipedreamKeys.all, 'apps', page, search || '', category || ''] as const,
appsSearch: (query: string, page: number, category?: string) => [...pipedreamKeys.all, 'apps', 'search', query, page, category || ''] as const,
availableTools: () => [...pipedreamKeys.all, 'available-tools'] as const,
mcpDiscovery: (options?: { app_slug?: string; oauth_app_id?: string; custom?: boolean }) =>
[...pipedreamKeys.all, 'mcp-discovery', options?.app_slug, options?.oauth_app_id, options?.custom] as const,

View File

@ -62,6 +62,18 @@ export const usePipedreamApps = (page: number = 1, search?: string, category?: s
});
};
export const usePipedreamAppsSearch = (query: string, page: number = 1, category?: string) => {
return useQuery({
queryKey: ['pipedream', 'apps', 'search', query, page, category],
queryFn: async (): Promise<PipedreamAppResponse> => {
return await pipedreamApi.searchApps(query, page, category);
},
staleTime: 5 * 60 * 1000,
retry: 2,
enabled: !!query && query.length > 0,
});
};
export const usePipedreamAvailableTools = createQueryHook(
pipedreamKeys.availableTools(),
async (forceRefresh: boolean = false): Promise<PipedreamToolsResponse> => {

View File

@ -100,8 +100,13 @@ export interface PipedreamAppResponse {
current_page: number;
page_size: number;
has_more: boolean;
count?: number;
start_cursor?: string;
end_cursor?: string;
};
total_count: number;
error?: string;
search_query?: string;
}
export interface PipedreamTool {
@ -174,13 +179,14 @@ export const pipedreamApi = {
},
async getApps(page: number = 1, search?: string, category?: string): Promise<PipedreamAppResponse> {
if (search) {
return await this.searchApps(search, page, category);
}
const params = new URLSearchParams({
page: page.toString(),
});
if (search) {
params.append('search', search);
}
if (category) {
params.append('category', category);
}
@ -195,8 +201,41 @@ export const pipedreamApi = {
if (!result.success) {
throw new Error(result.error?.message || 'Failed to get apps');
}
const data = result.data!;
if (!data.success && data.error) {
throw new Error(data.error);
}
return data;
},
return result.data!;
async searchApps(query: string, page: number = 1, category?: string): Promise<PipedreamAppResponse> {
const params = new URLSearchParams({
q: query,
page: page.toString(),
});
if (category) {
params.append('category', category);
}
const result = await backendApi.get<PipedreamAppResponse>(
`/pipedream/apps/search?${params.toString()}`,
{
errorContext: { operation: 'search apps', resource: 'Pipedream apps' },
}
);
if (!result.success) {
throw new Error(result.error?.message || 'Failed to search apps');
}
// Handle both success response and potential error in the data
const data = result.data!;
if (!data.success && data.error) {
throw new Error(data.error);
}
return data;
},
async getAvailableTools(): Promise<PipedreamToolsResponse> {