mirror of https://github.com/kortix-ai/suna.git
fix granular tool
This commit is contained in:
parent
a2b30e85bb
commit
77d2d04a03
|
@ -71,12 +71,12 @@ class MethodMetadata:
|
||||||
display_name (str): Human-readable method name
|
display_name (str): Human-readable method name
|
||||||
description (str): Method description
|
description (str): Method description
|
||||||
is_core (bool): Whether this is a core method (always enabled)
|
is_core (bool): Whether this is a core method (always enabled)
|
||||||
visible (bool): Whether method is visible in frontend UI (default False)
|
visible (bool): Whether method is visible in frontend UI (default True)
|
||||||
"""
|
"""
|
||||||
display_name: str
|
display_name: str
|
||||||
description: str
|
description: str
|
||||||
is_core: bool = False
|
is_core: bool = False
|
||||||
visible: bool = False
|
visible: bool = True
|
||||||
|
|
||||||
class Tool(ABC):
|
class Tool(ABC):
|
||||||
"""Abstract base class for all tools.
|
"""Abstract base class for all tools.
|
||||||
|
@ -254,7 +254,7 @@ def method_metadata(
|
||||||
display_name: str,
|
display_name: str,
|
||||||
description: str,
|
description: str,
|
||||||
is_core: bool = False,
|
is_core: bool = False,
|
||||||
visible: bool = False
|
visible: bool = True
|
||||||
):
|
):
|
||||||
"""Decorator to add metadata to a tool method.
|
"""Decorator to add metadata to a tool method.
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from core.services.supabase import DBConnection
|
||||||
icon="FileText",
|
icon="FileText",
|
||||||
color="bg-emerald-100 dark:bg-emerald-800/50",
|
color="bg-emerald-100 dark:bg-emerald-800/50",
|
||||||
weight=270,
|
weight=270,
|
||||||
visible=True
|
visible=False
|
||||||
)
|
)
|
||||||
class PaperSearchTool(Tool):
|
class PaperSearchTool(Tool):
|
||||||
def __init__(self, thread_manager: ThreadManager):
|
def __init__(self, thread_manager: ThreadManager):
|
||||||
|
|
|
@ -268,7 +268,9 @@ def ask(self, question: str):
|
||||||
|
|
||||||
## 👁️ Visible in UI
|
## 👁️ Visible in UI
|
||||||
|
|
||||||
**Default:** `visible = True` (both tool and method level)
|
**Default:**
|
||||||
|
- **Tool level:** `visible = False` (tools hidden by default)
|
||||||
|
- **Method level:** `visible = True` (methods visible by default)
|
||||||
|
|
||||||
Controls whether a tool/method is shown in the frontend UI.
|
Controls whether a tool/method is shown in the frontend UI.
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ def _extract_tool_metadata(tool_name: str, tool_class: Type[Tool]) -> Dict[str,
|
||||||
method_info["description"] = f"{method_name} function"
|
method_info["description"] = f"{method_name} function"
|
||||||
|
|
||||||
method_info["is_core"] = False
|
method_info["is_core"] = False
|
||||||
method_info["visible"] = False
|
method_info["visible"] = True
|
||||||
|
|
||||||
metadata["methods"].append(method_info)
|
metadata["methods"].append(method_info)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -206,7 +206,10 @@ export const GranularToolConfiguration = ({
|
||||||
const toolGroup = getToolGroup(toolName, toolsData);
|
const toolGroup = getToolGroup(toolName, toolsData);
|
||||||
if (!toolGroup) return 0;
|
if (!toolGroup) return 0;
|
||||||
|
|
||||||
return toolGroup.methods.filter(method => isMethodEnabled(toolName, method.name)).length;
|
// Only count visible methods
|
||||||
|
return toolGroup.methods
|
||||||
|
.filter(method => method.visible !== false)
|
||||||
|
.filter(method => isMethodEnabled(toolName, method.name)).length;
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredGroups = getFilteredToolGroups();
|
const filteredGroups = getFilteredToolGroups();
|
||||||
|
@ -251,7 +254,7 @@ export const GranularToolConfiguration = ({
|
||||||
const isGroupEnabled = isToolGroupEnabled(toolGroup.name);
|
const isGroupEnabled = isToolGroupEnabled(toolGroup.name);
|
||||||
const isExpanded = expandedGroups.has(toolGroup.name);
|
const isExpanded = expandedGroups.has(toolGroup.name);
|
||||||
const enabledMethodsCount = getEnabledMethodsCount(toolGroup.name);
|
const enabledMethodsCount = getEnabledMethodsCount(toolGroup.name);
|
||||||
const totalMethodsCount = toolGroup.methods.length;
|
const totalMethodsCount = toolGroup.methods.filter(m => m.visible !== false).length;
|
||||||
const IconComponent = getIconComponent(toolGroup.icon);
|
const IconComponent = getIconComponent(toolGroup.icon);
|
||||||
const hasGranular = hasGranularControl(toolGroup.name, toolsData);
|
const hasGranular = hasGranularControl(toolGroup.name, toolsData);
|
||||||
|
|
||||||
|
@ -323,7 +326,9 @@ export const GranularToolConfiguration = ({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{toolGroup.methods.map((method) => {
|
{toolGroup.methods
|
||||||
|
.filter(method => method.visible !== false) // Only show visible methods
|
||||||
|
.map((method) => {
|
||||||
const isMethodEnabledState = isMethodEnabled(toolGroup.name, method.name);
|
const isMethodEnabledState = isMethodEnabled(toolGroup.name, method.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -57,13 +57,13 @@ export function normalizeToolGroup(apiToolGroup: any): ToolGroup {
|
||||||
enabled: m.enabled ?? true,
|
enabled: m.enabled ?? true,
|
||||||
isCore: m.is_core || m.isCore,
|
isCore: m.is_core || m.isCore,
|
||||||
is_core: m.is_core,
|
is_core: m.is_core,
|
||||||
visible: m.visible ?? false, // Default false - tools must explicitly set visible=True
|
visible: m.visible, // Use API value directly - backend controls visibility
|
||||||
})) || [],
|
})) || [],
|
||||||
enabled: apiToolGroup.enabled ?? true,
|
enabled: apiToolGroup.enabled ?? true,
|
||||||
isCore: apiToolGroup.is_core || apiToolGroup.isCore,
|
isCore: apiToolGroup.is_core || apiToolGroup.isCore,
|
||||||
is_core: apiToolGroup.is_core,
|
is_core: apiToolGroup.is_core,
|
||||||
weight: apiToolGroup.weight ?? 100,
|
weight: apiToolGroup.weight ?? 100,
|
||||||
visible: apiToolGroup.visible ?? false, // Default false - tools must explicitly set visible=True
|
visible: apiToolGroup.visible, // Use API value directly - backend controls visibility
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,12 @@ export function getAllToolGroups(toolsData?: Record<string, any>): Record<string
|
||||||
|
|
||||||
export function hasGranularControl(toolName: string, toolsData?: Record<string, any>): boolean {
|
export function hasGranularControl(toolName: string, toolsData?: Record<string, any>): boolean {
|
||||||
const group = getToolGroup(toolName, toolsData);
|
const group = getToolGroup(toolName, toolsData);
|
||||||
return group ? group.methods.length > 1 : false;
|
if (!group) return false;
|
||||||
|
|
||||||
|
// Only count visible methods for granular control (visible=true or visible=undefined counts as visible)
|
||||||
|
const visibleMethods = group.methods.filter(m => m.visible !== false);
|
||||||
|
console.log(`[hasGranularControl] ${toolName}: ${group.methods.length} total methods, ${visibleMethods.length} visible`, group.methods.map(m => ({ name: m.name, visible: m.visible })));
|
||||||
|
return visibleMethods.length > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnabledMethodsForTool(
|
export function getEnabledMethodsForTool(
|
||||||
|
|
|
@ -11,7 +11,6 @@ import {
|
||||||
FileText,
|
FileText,
|
||||||
Search,
|
Search,
|
||||||
Users,
|
Users,
|
||||||
Code2,
|
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
@ -25,7 +24,7 @@ interface SunaModesPanelProps {
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModeType = 'research' | 'people' | 'code' | 'docs' | 'data' | 'slides' | 'image';
|
type ModeType = 'image' | 'slides' | 'data' | 'docs' | 'people' | 'research';
|
||||||
|
|
||||||
interface Mode {
|
interface Mode {
|
||||||
id: ModeType;
|
id: ModeType;
|
||||||
|
@ -53,83 +52,74 @@ interface Mode {
|
||||||
|
|
||||||
const modes: Mode[] = [
|
const modes: Mode[] = [
|
||||||
{
|
{
|
||||||
id: 'research',
|
id: 'image',
|
||||||
label: 'Research',
|
label: 'Image',
|
||||||
icon: <Search className="w-4 h-4" />,
|
icon: <ImageIcon className="w-4 h-4" />,
|
||||||
samplePrompts: [
|
samplePrompts: [
|
||||||
'Analyze emerging trends in quantum computing and potential business applications',
|
'A majestic golden eagle soaring through misty mountain peaks at sunrise with dramatic lighting',
|
||||||
'Research top 10 competitors in the AI-powered CRM space with feature comparison',
|
'Close-up portrait of a fashion model with avant-garde makeup, studio lighting, high contrast shadows',
|
||||||
'Investigate regulatory requirements for launching a fintech app in the EU',
|
'Cozy Scandinavian living room with natural wood furniture, indoor plants, and soft morning sunlight',
|
||||||
'Compile market analysis on electric vehicle adoption rates across major markets',
|
'Futuristic cyberpunk street market at night with neon signs, rain-slicked pavement, and holographic displays',
|
||||||
'Study the impact of remote work on commercial real estate demand in major cities',
|
'Elegant product photography of luxury perfume bottle on marble surface with soft reflections',
|
||||||
'Research Web3 adoption patterns among Fortune 500 companies',
|
'Whimsical floating islands connected by rope bridges in a pastel sky with dreamy clouds',
|
||||||
'Analyze consumer sentiment towards sustainable fashion brands',
|
'Macro close-up of morning dew drops on vibrant flower petals with bokeh background',
|
||||||
'Investigate the latest developments in gene therapy for rare diseases',
|
'Modern workspace desk setup with laptop, coffee, notebook, and succulent plants from above',
|
||||||
'Study pricing strategies of successful D2C subscription box companies',
|
'Mystical forest path with ancient trees, glowing fireflies, and ethereal light beams through fog',
|
||||||
'Research the competitive landscape of AI-powered cybersecurity solutions',
|
'Architectural detail of contemporary glass building facade with geometric patterns and reflections',
|
||||||
|
'Vibrant street food vendor stall with colorful ingredients, steam rising, and warm lighting',
|
||||||
|
'Serene Japanese zen garden with raked sand, moss-covered stones, and cherry blossom petals',
|
||||||
|
'Dynamic action shot of athlete mid-jump against dramatic sunset sky, silhouette effect',
|
||||||
|
'Rustic farmhouse kitchen with copper pots, fresh herbs, wooden cutting boards, and natural textures',
|
||||||
|
'Abstract fluid art with swirling metallic gold, deep blue, and emerald green organic patterns',
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
title: 'Choose a style',
|
||||||
|
items: [
|
||||||
|
{ id: 'photorealistic', name: 'Photorealistic', image: '/images/image-styles/photorealistic_eagle-min.png' },
|
||||||
|
{ id: 'watercolor', name: 'Watercolor', image: '/images/image-styles/watercolor_garden-min.png' },
|
||||||
|
{ id: 'digital-art', name: 'Digital Art', image: '/images/image-styles/digital_art_cyberpunk-min.png' },
|
||||||
|
{ id: 'oil-painting', name: 'Oil Painting', image: '/images/image-styles/oil_painting_villa-min.png' },
|
||||||
|
{ id: 'minimalist', name: 'Minimalist', image: '/images/image-styles/minimalist_coffee-min.png' },
|
||||||
|
{ id: 'isometric', name: 'Isometric', image: '/images/image-styles/isometric_bedroom-min.png' },
|
||||||
|
{ id: 'vintage', name: 'Vintage', image: '/images/image-styles/vintage_diner-min.png' },
|
||||||
|
{ id: 'comic', name: 'Comic Book', image: '/images/image-styles/comic_book_robot-min.png' },
|
||||||
|
{ id: 'neon', name: 'Neon', image: '/images/image-styles/neon_jellyfish-min.png' },
|
||||||
|
{ id: 'pastel', name: 'Pastel', image: '/images/image-styles/pastel_landscape-min.png' },
|
||||||
|
{ id: 'geometric', name: 'Geometric', image: '/images/image-styles/geometric_crystal-min.png' },
|
||||||
|
{ id: 'abstract', name: 'Abstract', image: '/images/image-styles/abstract_organic-min.png' },
|
||||||
|
{ id: 'anime', name: 'Anime', image: '/images/image-styles/anime_forest-min.png' },
|
||||||
|
{ id: 'impressionist', name: 'Impressionist', image: '/images/image-styles/impressionist_garden-min.png' },
|
||||||
|
{ id: 'surreal', name: 'Surreal', image: '/images/image-styles/surreal_islands-min.png' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'people',
|
|
||||||
label: 'People',
|
|
||||||
icon: <Users className="w-4 h-4" />,
|
|
||||||
samplePrompts: [
|
|
||||||
'Find VP of Engineering candidates at Series B+ AI companies in NYC',
|
|
||||||
'Build lead list of CMOs at SaaS companies with 50-200 employees',
|
|
||||||
'Research blockchain developers with Solidity experience open to relocation',
|
|
||||||
'Generate prospect list of tech founders who raised funding in the last 6 months',
|
|
||||||
'Identify Product Managers at fintech startups with 5+ years experience',
|
|
||||||
'Find decision-makers at mid-market companies in healthcare IT',
|
|
||||||
'Research sales leaders at B2B companies with recent ARR growth',
|
|
||||||
'Build list of CTOs at enterprise companies adopting AI infrastructure',
|
|
||||||
'Find UX designers with experience in mobile-first e-commerce',
|
|
||||||
'Identify DevOps engineers at cloud-native startups in Austin',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'code',
|
id: 'slides',
|
||||||
label: 'Code',
|
label: 'Slides',
|
||||||
icon: <Code2 className="w-4 h-4" />,
|
icon: <Presentation className="w-4 h-4" />,
|
||||||
samplePrompts: [
|
samplePrompts: [
|
||||||
'Build a modern landing page with React, Tailwind CSS, and smooth animations',
|
'Create a Series A pitch deck with market size, traction, and financial projections',
|
||||||
'Create a Python script to scrape product data and generate CSV reports',
|
'Build a Q4 business review showcasing KPIs, wins, and strategic initiatives',
|
||||||
'Develop a REST API with authentication and rate limiting',
|
'Design a product launch presentation with demo videos and customer testimonials',
|
||||||
'Build an interactive data dashboard with real-time charts and filters',
|
'Develop a sales enablement deck explaining our value prop and competitive advantages',
|
||||||
'Create a Chrome extension to track time spent on websites',
|
'Create an investor update highlighting key metrics and upcoming milestones',
|
||||||
'Build a Node.js backend with PostgreSQL and Redis caching',
|
'Build a customer case study presentation showing ROI and success metrics',
|
||||||
'Develop a real-time chat application with WebSocket support',
|
'Design an all-hands presentation covering company updates and vision',
|
||||||
'Create an automated email campaign system with analytics',
|
'Develop a training deck for new product features and workflows',
|
||||||
'Build a portfolio website with dark mode and CMS integration',
|
'Create a conference talk about scaling engineering teams',
|
||||||
'Develop a Python CLI tool for automating deployment workflows',
|
'Build a board meeting presentation with strategic recommendations',
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'docs',
|
|
||||||
label: 'Docs',
|
|
||||||
icon: <FileText className="w-4 h-4" />,
|
|
||||||
samplePrompts: [
|
|
||||||
'Write a comprehensive PRD for an AI-powered recommendation engine',
|
|
||||||
'Draft a technical architecture document for a scalable microservices platform',
|
|
||||||
'Create a go-to-market strategy document for our Q2 product launch',
|
|
||||||
'Develop a 90-day onboarding playbook for engineering managers',
|
|
||||||
'Write an API documentation guide with examples and best practices',
|
|
||||||
'Create a company handbook covering culture, policies, and benefits',
|
|
||||||
'Draft a data privacy policy compliant with GDPR and CCPA',
|
|
||||||
'Develop a customer success playbook for SaaS enterprise accounts',
|
|
||||||
'Write a security incident response plan with escalation procedures',
|
|
||||||
'Create a comprehensive style guide for brand and content',
|
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
title: 'Choose a template',
|
title: 'Choose a template',
|
||||||
items: [
|
items: [
|
||||||
{ id: 'prd', name: 'PRD', description: 'Product requirements document' },
|
{ id: 'modern', name: 'Modern', description: 'Clean and professional' },
|
||||||
{ id: 'technical', name: 'Technical', description: 'Technical documentation' },
|
{ id: 'bold', name: 'Bold', description: 'High impact design' },
|
||||||
{ id: 'proposal', name: 'Proposal', description: 'Business proposal' },
|
{ id: 'elegant', name: 'Elegant', description: 'Sophisticated style' },
|
||||||
{ id: 'report', name: 'Report', description: 'Detailed report format' },
|
{ id: 'tech', name: 'Tech', description: 'Technology focused' },
|
||||||
{ id: 'guide', name: 'Guide', description: 'Step-by-step guide' },
|
{ id: 'creative', name: 'Creative', description: 'Artistic and unique' },
|
||||||
{ id: 'wiki', name: 'Wiki', description: 'Knowledge base article' },
|
{ id: 'minimal', name: 'Minimal', description: 'Simple and clear' },
|
||||||
{ id: 'policy', name: 'Policy', description: 'Policy document' },
|
{ id: 'corporate', name: 'Corporate', description: 'Business standard' },
|
||||||
{ id: 'meeting-notes', name: 'Meeting Notes', description: 'Meeting minutes' },
|
{ id: 'vibrant', name: 'Vibrant', description: 'Colorful and energetic' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -175,76 +165,68 @@ const modes: Mode[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'slides',
|
id: 'docs',
|
||||||
label: 'Slides',
|
label: 'Docs',
|
||||||
icon: <Presentation className="w-4 h-4" />,
|
icon: <FileText className="w-4 h-4" />,
|
||||||
samplePrompts: [
|
samplePrompts: [
|
||||||
'Create a Series A pitch deck with market size, traction, and financial projections',
|
'Write a comprehensive PRD for an AI-powered recommendation engine',
|
||||||
'Build a Q4 business review showcasing KPIs, wins, and strategic initiatives',
|
'Draft a technical architecture document for a scalable microservices platform',
|
||||||
'Design a product launch presentation with demo videos and customer testimonials',
|
'Create a go-to-market strategy document for our Q2 product launch',
|
||||||
'Develop a sales enablement deck explaining our value prop and competitive advantages',
|
'Develop a 90-day onboarding playbook for engineering managers',
|
||||||
'Create an investor update highlighting key metrics and upcoming milestones',
|
'Write an API documentation guide with examples and best practices',
|
||||||
'Build a customer case study presentation showing ROI and success metrics',
|
'Create a company handbook covering culture, policies, and benefits',
|
||||||
'Design an all-hands presentation covering company updates and vision',
|
'Draft a data privacy policy compliant with GDPR and CCPA',
|
||||||
'Develop a training deck for new product features and workflows',
|
'Develop a customer success playbook for SaaS enterprise accounts',
|
||||||
'Create a conference talk about scaling engineering teams',
|
'Write a security incident response plan with escalation procedures',
|
||||||
'Build a board meeting presentation with strategic recommendations',
|
'Create a comprehensive style guide for brand and content',
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
title: 'Choose a template',
|
title: 'Choose a template',
|
||||||
items: [
|
items: [
|
||||||
{ id: 'modern', name: 'Modern', description: 'Clean and professional' },
|
{ id: 'prd', name: 'PRD', description: 'Product requirements document' },
|
||||||
{ id: 'bold', name: 'Bold', description: 'High impact design' },
|
{ id: 'technical', name: 'Technical', description: 'Technical documentation' },
|
||||||
{ id: 'elegant', name: 'Elegant', description: 'Sophisticated style' },
|
{ id: 'proposal', name: 'Proposal', description: 'Business proposal' },
|
||||||
{ id: 'tech', name: 'Tech', description: 'Technology focused' },
|
{ id: 'report', name: 'Report', description: 'Detailed report format' },
|
||||||
{ id: 'creative', name: 'Creative', description: 'Artistic and unique' },
|
{ id: 'guide', name: 'Guide', description: 'Step-by-step guide' },
|
||||||
{ id: 'minimal', name: 'Minimal', description: 'Simple and clear' },
|
{ id: 'wiki', name: 'Wiki', description: 'Knowledge base article' },
|
||||||
{ id: 'corporate', name: 'Corporate', description: 'Business standard' },
|
{ id: 'policy', name: 'Policy', description: 'Policy document' },
|
||||||
{ id: 'vibrant', name: 'Vibrant', description: 'Colorful and energetic' },
|
{ id: 'meeting-notes', name: 'Meeting Notes', description: 'Meeting minutes' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'image',
|
id: 'people',
|
||||||
label: 'Image',
|
label: 'People',
|
||||||
icon: <ImageIcon className="w-4 h-4" />,
|
icon: <Users className="w-4 h-4" />,
|
||||||
samplePrompts: [
|
samplePrompts: [
|
||||||
'A majestic golden eagle soaring through misty mountain peaks at sunrise with dramatic lighting',
|
'Find VP of Engineering candidates at Series B+ AI companies in NYC',
|
||||||
'Close-up portrait of a fashion model with avant-garde makeup, studio lighting, high contrast shadows',
|
'Build lead list of CMOs at SaaS companies with 50-200 employees',
|
||||||
'Cozy Scandinavian living room with natural wood furniture, indoor plants, and soft morning sunlight',
|
'Research blockchain developers with Solidity experience open to relocation',
|
||||||
'Futuristic cyberpunk street market at night with neon signs, rain-slicked pavement, and holographic displays',
|
'Generate prospect list of tech founders who raised funding in the last 6 months',
|
||||||
'Elegant product photography of luxury perfume bottle on marble surface with soft reflections',
|
'Identify Product Managers at fintech startups with 5+ years experience',
|
||||||
'Whimsical floating islands connected by rope bridges in a pastel sky with dreamy clouds',
|
'Find decision-makers at mid-market companies in healthcare IT',
|
||||||
'Macro close-up of morning dew drops on vibrant flower petals with bokeh background',
|
'Research sales leaders at B2B companies with recent ARR growth',
|
||||||
'Modern workspace desk setup with laptop, coffee, notebook, and succulent plants from above',
|
'Build list of CTOs at enterprise companies adopting AI infrastructure',
|
||||||
'Mystical forest path with ancient trees, glowing fireflies, and ethereal light beams through fog',
|
'Find UX designers with experience in mobile-first e-commerce',
|
||||||
'Architectural detail of contemporary glass building facade with geometric patterns and reflections',
|
'Identify DevOps engineers at cloud-native startups in Austin',
|
||||||
'Vibrant street food vendor stall with colorful ingredients, steam rising, and warm lighting',
|
|
||||||
'Serene Japanese zen garden with raked sand, moss-covered stones, and cherry blossom petals',
|
|
||||||
'Dynamic action shot of athlete mid-jump against dramatic sunset sky, silhouette effect',
|
|
||||||
'Rustic farmhouse kitchen with copper pots, fresh herbs, wooden cutting boards, and natural textures',
|
|
||||||
'Abstract fluid art with swirling metallic gold, deep blue, and emerald green organic patterns',
|
|
||||||
],
|
|
||||||
options: {
|
|
||||||
title: 'Choose a style',
|
|
||||||
items: [
|
|
||||||
{ id: 'photorealistic', name: 'Photorealistic', image: '/images/image-styles/photorealistic_eagle-min.png' },
|
|
||||||
{ id: 'watercolor', name: 'Watercolor', image: '/images/image-styles/watercolor_garden-min.png' },
|
|
||||||
{ id: 'digital-art', name: 'Digital Art', image: '/images/image-styles/digital_art_cyberpunk-min.png' },
|
|
||||||
{ id: 'oil-painting', name: 'Oil Painting', image: '/images/image-styles/oil_painting_villa-min.png' },
|
|
||||||
{ id: 'minimalist', name: 'Minimalist', image: '/images/image-styles/minimalist_coffee-min.png' },
|
|
||||||
{ id: 'isometric', name: 'Isometric', image: '/images/image-styles/isometric_bedroom-min.png' },
|
|
||||||
{ id: 'vintage', name: 'Vintage', image: '/images/image-styles/vintage_diner-min.png' },
|
|
||||||
{ id: 'comic', name: 'Comic Book', image: '/images/image-styles/comic_book_robot-min.png' },
|
|
||||||
{ id: 'neon', name: 'Neon', image: '/images/image-styles/neon_jellyfish-min.png' },
|
|
||||||
{ id: 'pastel', name: 'Pastel', image: '/images/image-styles/pastel_landscape-min.png' },
|
|
||||||
{ id: 'geometric', name: 'Geometric', image: '/images/image-styles/geometric_crystal-min.png' },
|
|
||||||
{ id: 'abstract', name: 'Abstract', image: '/images/image-styles/abstract_organic-min.png' },
|
|
||||||
{ id: 'anime', name: 'Anime', image: '/images/image-styles/anime_forest-min.png' },
|
|
||||||
{ id: 'impressionist', name: 'Impressionist', image: '/images/image-styles/impressionist_garden-min.png' },
|
|
||||||
{ id: 'surreal', name: 'Surreal', image: '/images/image-styles/surreal_islands-min.png' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'research',
|
||||||
|
label: 'Research',
|
||||||
|
icon: <Search className="w-4 h-4" />,
|
||||||
|
samplePrompts: [
|
||||||
|
'Analyze emerging trends in quantum computing and potential business applications',
|
||||||
|
'Research top 10 competitors in the AI-powered CRM space with feature comparison',
|
||||||
|
'Investigate regulatory requirements for launching a fintech app in the EU',
|
||||||
|
'Compile market analysis on electric vehicle adoption rates across major markets',
|
||||||
|
'Study the impact of remote work on commercial real estate demand in major cities',
|
||||||
|
'Research Web3 adoption patterns among Fortune 500 companies',
|
||||||
|
'Analyze consumer sentiment towards sustainable fashion brands',
|
||||||
|
'Investigate the latest developments in gene therapy for rare diseases',
|
||||||
|
'Study pricing strategies of successful D2C subscription box companies',
|
||||||
|
'Research the competitive landscape of AI-powered cybersecurity solutions',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -347,7 +329,7 @@ export function SunaModesPanel({ selectedMode, onModeSelect, onSelectPrompt, isM
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Sample Prompts - Card Grid Style (for code, docs, data, slides, image) */}
|
{/* Sample Prompts - Card Grid Style (for image, slides, data, docs) */}
|
||||||
{selectedMode && displayedPrompts && !['research', 'people'].includes(selectedMode) && (
|
{selectedMode && displayedPrompts && !['research', 'people'].includes(selectedMode) && (
|
||||||
<div className="space-y-3 animate-in fade-in-0 zoom-in-95 duration-300">
|
<div className="space-y-3 animate-in fade-in-0 zoom-in-95 duration-300">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
|
|
@ -37,11 +37,23 @@ export function useToolsMetadata() {
|
||||||
return useQuery<ToolsMetadataResponse>({
|
return useQuery<ToolsMetadataResponse>({
|
||||||
queryKey: ['tools', 'metadata'],
|
queryKey: ['tools', 'metadata'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await backendApi.get<ToolsMetadataResponse>('/tools');
|
const response = await backendApi.get<{ success: boolean; tools: ToolMetadata[] }>('/tools');
|
||||||
if (!response.success || !response.data) {
|
if (!response.success || !response.data) {
|
||||||
throw new Error('Failed to fetch tools metadata');
|
throw new Error('Failed to fetch tools metadata');
|
||||||
}
|
}
|
||||||
return response.data;
|
|
||||||
|
// Backend returns array, convert to object keyed by tool name
|
||||||
|
const toolsArray = response.data.tools;
|
||||||
|
const toolsObject: Record<string, ToolMetadata> = {};
|
||||||
|
|
||||||
|
for (const tool of toolsArray) {
|
||||||
|
toolsObject[tool.name] = tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: response.data.success,
|
||||||
|
tools: toolsObject
|
||||||
|
};
|
||||||
},
|
},
|
||||||
staleTime: 1000 * 60 * 60, // Cache for 1 hour since tools don't change frequently
|
staleTime: 1000 * 60 * 60, // Cache for 1 hour since tools don't change frequently
|
||||||
gcTime: 1000 * 60 * 60 * 24, // Keep in cache for 24 hours
|
gcTime: 1000 * 60 * 60 * 24, // Keep in cache for 24 hours
|
||||||
|
|
Loading…
Reference in New Issue