From 93b5d4107753caaa22337383c6f1d15b65e147d8 Mon Sep 17 00:00:00 2001 From: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> Date: Tue, 30 Dec 2025 11:04:30 -0500 Subject: [PATCH 1/2] feat: Add Manus AI integration as specialized tool - Add Manus tool with Zod schema for parameter validation - Create ManusSection UI component for displaying task results - Register Manus tool conditionally based on MANUS_API_KEY - Add MANUS_API_KEY to environment configuration - Include comprehensive documentation in MANUS_INTEGRATION.md The integration follows QCX's existing tool-based architecture, allowing the Researcher Agent to delegate complex multi-step tasks to the Manus AI platform for advanced reasoning, research, and workflow automation. --- .env.local.example | 4 + MANUS_INTEGRATION.md | 187 +++++++++++++++++++++++++++++++++++ components/manus-section.tsx | 68 +++++++++++++ lib/agents/tools/index.tsx | 8 ++ lib/agents/tools/manus.tsx | 108 ++++++++++++++++++++ lib/schema/manus.tsx | 26 +++++ 6 files changed, 401 insertions(+) create mode 100644 MANUS_INTEGRATION.md create mode 100644 components/manus-section.tsx create mode 100644 lib/agents/tools/manus.tsx create mode 100644 lib/schema/manus.tsx diff --git a/.env.local.example b/.env.local.example index 928ed6f6..be40f155 100644 --- a/.env.local.example +++ b/.env.local.example @@ -11,6 +11,10 @@ SMITHERY_API_KEY="your_smithery_api_key_here" # Gemini 3 Pro (Google Generative AI) GEMINI_3_PRO_API_KEY="your_gemini_3_pro_api_key_here" +# Manus AI API Key +# Get your API key from https://open.manus.im/docs/quickstart +MANUS_API_KEY="your_manus_api_key_here" + # Supabase Credentials NEXT_PUBLIC_SUPABASE_URL="YOUR_SUPABASE_URL_HERE" NEXT_PUBLIC_SUPABASE_ANON_KEY="YOUR_SUPABASE_ANON_KEY_HERE" diff --git a/MANUS_INTEGRATION.md b/MANUS_INTEGRATION.md new file mode 100644 index 00000000..76d63ad8 --- /dev/null +++ b/MANUS_INTEGRATION.md @@ -0,0 +1,187 @@ +# Manus AI Integration + +This document describes the integration of Manus AI into the QCX platform. + +## Overview + +Manus AI has been integrated as a specialized tool available to the QCX Researcher Agent. This integration enables QCX to delegate complex, multi-step tasks to the Manus AI platform, which can perform advanced reasoning, research, code execution, and workflow automation. + +## Architecture Decision + +The Manus integration follows a **tool-based architecture** rather than creating a separate agent. This decision was made based on several factors: + +- **Consistency**: Aligns with existing QCX patterns (search, retrieve, geospatial tools) +- **Simplicity**: Minimal changes to existing routing logic +- **Flexibility**: The Researcher Agent can intelligently decide when Manus is appropriate +- **Maintainability**: Follows established patterns in the codebase +- **Cost Efficiency**: Avoids unnecessary LLM calls for routing decisions + +## Implementation Details + +### Files Created + +1. **`lib/schema/manus.tsx`** - Zod schema for Manus tool parameters + - Defines validation for prompt, agentProfile, taskMode, and interactiveMode + - Provides TypeScript types for type safety + +2. **`lib/agents/tools/manus.tsx`** - Manus tool implementation + - Handles API calls to Manus AI platform + - Manages error handling and UI updates + - Creates tasks and returns task information + +3. **`components/manus-section.tsx`** - UI component for displaying Manus task results + - Shows task title, ID, and status + - Provides links to view task progress and share results + - Follows QCX design patterns + +### Files Modified + +1. **`lib/agents/tools/index.tsx`** - Tool registry + - Added Manus tool import + - Conditionally registers Manus tool when MANUS_API_KEY is present + +2. **`.env.local.example`** - Environment configuration + - Added MANUS_API_KEY configuration with documentation + +## Configuration + +### Environment Variables + +Add the following to your `.env.local` file: + +```bash +# Manus AI API Key +# Get your API key from https://open.manus.im/docs/quickstart +MANUS_API_KEY="your_manus_api_key_here" +``` + +### Getting Your API Key + +1. Visit the [Manus API Integration settings](https://open.manus.im/docs/quickstart) +2. Generate a new API key +3. Add it to your `.env.local` file +4. Restart your development server + +## Usage + +Once configured, the Manus tool is automatically available to the QCX Researcher Agent. The agent will use Manus for tasks that require: + +- Complex multi-step workflows +- Deep research across multiple sources +- Code execution or file manipulation +- Advanced reasoning and planning +- Tasks beyond simple search and retrieval + +### Tool Parameters + +The Manus tool accepts the following parameters: + +- **prompt** (required): The task instruction for Manus +- **agentProfile** (optional): Agent profile to use + - `manus-1.6` (default) - Balanced performance + - `manus-1.6-lite` - Faster execution + - `manus-1.6-max` - Most capable +- **taskMode** (optional): Execution mode + - `chat` - Conversational mode + - `adaptive` - Adaptive mode + - `agent` - Full agent mode +- **interactiveMode** (optional): Enable follow-up questions (default: false) + +### Example Usage + +When a user asks a complex question like "Research the latest developments in quantum computing and create a comprehensive report with code examples," the Researcher Agent may decide to use the Manus tool: + +```typescript +{ + prompt: "Research the latest developments in quantum computing and create a comprehensive report with code examples", + agentProfile: "manus-1.6", + taskMode: "agent", + interactiveMode: false +} +``` + +The tool will: +1. Create a task on the Manus platform +2. Display a loading state in the UI +3. Show the task information with links to view progress +4. Return task details to the Researcher Agent for context + +## API Reference + +### Manus API Endpoint + +- **URL**: `https://api.manus.ai/v1/tasks` +- **Method**: POST +- **Authentication**: API_KEY header + +### Request Schema + +```typescript +{ + prompt: string + agentProfile: 'manus-1.6' | 'manus-1.6-lite' | 'manus-1.6-max' + taskMode?: 'chat' | 'adaptive' | 'agent' + interactiveMode?: boolean + createShareableLink?: boolean +} +``` + +### Response Schema + +```typescript +{ + task_id: string + task_title: string + task_url: string + share_url?: string +} +``` + +## Future Enhancements + +Potential improvements for future iterations: + +1. **Task Result Polling**: Implement polling to fetch and display task results directly in QCX +2. **Webhook Integration**: Use Manus webhooks for real-time task completion notifications +3. **Connector Support**: Enable Manus connectors (Gmail, Notion, Google Calendar, etc.) +4. **Dedicated Agent**: Create a specialized Manus agent for complex workflows requiring multiple Manus calls +5. **File Attachments**: Support file uploads to Manus tasks +6. **Multi-turn Conversations**: Enable continuing existing Manus tasks + +## Testing + +To test the integration: + +1. Ensure MANUS_API_KEY is set in `.env.local` +2. Start the development server: `bun dev` +3. Ask a complex question that would benefit from Manus capabilities +4. Verify the Manus tool is called and task information is displayed +5. Click the task URL to view progress on the Manus platform + +## Troubleshooting + +### Tool Not Available + +If the Manus tool is not being used: +- Check that MANUS_API_KEY is set in `.env.local` +- Restart the development server after adding the API key +- Verify the API key is valid by testing it directly with the Manus API + +### API Errors + +If you encounter API errors: +- Check the console for detailed error messages +- Verify your API key has not expired +- Ensure you have sufficient credits on your Manus account +- Check the Manus API status page for service issues + +## Resources + +- [Manus API Documentation](https://open.manus.im/docs/quickstart) +- [Manus API Reference](https://open.manus.im/docs/api-reference) +- [AI SDK Workflow Patterns](https://ai-sdk.dev/docs/agents/workflows) +- [QCX Repository](https://github.com/QueueLab/QCX) + +## License + +This integration follows the same license as the QCX project (Apache-2.0). diff --git a/components/manus-section.tsx b/components/manus-section.tsx new file mode 100644 index 00000000..4069cb56 --- /dev/null +++ b/components/manus-section.tsx @@ -0,0 +1,68 @@ +import React from 'react' +import { Section } from '@/components/section' +import { Card } from '@/components/ui/card' +import { ExternalLink } from 'lucide-react' + +interface ManusSectionProps { + data: { + task_id: string + task_title: string + task_url: string + share_url?: string + } +} + +const ManusSection: React.FC = ({ data }) => { + return ( +
+ +
+
+ Task Title +
+
{data.task_title}
+
+ +
+
+ Task ID +
+
+ {data.task_id} +
+
+ +
+ + + View Task Progress + + + {data.share_url && ( + + + Public Share Link + + )} +
+ +
+ The Manus agent is working on your task. Click the link above to view + real-time progress and results. +
+
+
+ ) +} + +export default ManusSection diff --git a/lib/agents/tools/index.tsx b/lib/agents/tools/index.tsx index 4c08f373..f5a61397 100644 --- a/lib/agents/tools/index.tsx +++ b/lib/agents/tools/index.tsx @@ -3,6 +3,7 @@ import { retrieveTool } from './retrieve' import { searchTool } from './search' import { videoSearchTool } from './video-search' import { geospatialTool } from './geospatial' // Removed useGeospatialToolMcp import +import { manusTool } from './manus' export interface ToolProps { uiStream: ReturnType @@ -35,5 +36,12 @@ export const getTools = ({ uiStream, fullResponse }: ToolProps) => { }) } + if (process.env.MANUS_API_KEY) { + tools.manusTask = manusTool({ + uiStream, + fullResponse + }) + } + return tools } \ No newline at end of file diff --git a/lib/agents/tools/manus.tsx b/lib/agents/tools/manus.tsx new file mode 100644 index 00000000..20f7a395 --- /dev/null +++ b/lib/agents/tools/manus.tsx @@ -0,0 +1,108 @@ +import { manusSchema } from '@/lib/schema/manus' +import { ToolProps } from '.' +import { Card } from '@/components/ui/card' +import { SearchSkeleton } from '@/components/search-skeleton' +import ManusSection from '@/components/manus-section' + +export const manusTool = ({ uiStream, fullResponse }: ToolProps) => ({ + description: + 'Execute complex tasks using the Manus AI agent platform. Use this for multi-step tasks requiring planning, research across multiple sources, code execution, file manipulation, or advanced reasoning. Manus can browse the web, analyze data, write code, and perform complex workflows.', + parameters: manusSchema, + execute: async ({ + prompt, + agentProfile, + taskMode, + interactiveMode + }: { + prompt: string + agentProfile: 'manus-1.6' | 'manus-1.6-lite' | 'manus-1.6-max' + taskMode?: 'chat' | 'adaptive' | 'agent' + interactiveMode: boolean + }) => { + let hasError = false + // Show loading state + uiStream.append() + + let taskResult: { + task_id: string + task_title: string + task_url: string + share_url?: string + } | null = null + + try { + const apiKey = process.env.MANUS_API_KEY + if (!apiKey) { + throw new Error('MANUS_API_KEY is not configured') + } + + // Create task + const response = await fetch('https://api.manus.ai/v1/tasks', { + method: 'POST', + headers: { + accept: 'application/json', + 'content-type': 'application/json', + API_KEY: apiKey + }, + body: JSON.stringify({ + prompt, + agentProfile, + taskMode, + interactiveMode, + createShareableLink: true + }) + }) + + if (!response.ok) { + const errorText = await response.text() + throw new Error( + `Manus API error: ${response.status} - ${errorText}` + ) + } + + taskResult = await response.json() + + if (!taskResult) { + hasError = true + } + } catch (error) { + hasError = true + console.error('Manus API error:', error) + + const errorMessage = + error instanceof Error ? error.message : 'Unknown error occurred' + fullResponse += `\nAn error occurred while executing Manus task: ${errorMessage}` + + uiStream.update( + + {`An error occurred while executing Manus task: ${errorMessage}`} + + ) + return null + } + + if (hasError || !taskResult) { + fullResponse += `\nAn error occurred while executing the Manus task.` + uiStream.update( + + An error occurred while executing the Manus task. + + ) + return null + } + + // Update UI with task result + uiStream.update() + + // Add task information to the response context + fullResponse += `\n\nManus task created successfully: +- Task ID: ${taskResult.task_id} +- Title: ${taskResult.task_title} +- Task URL: ${taskResult.task_url} +${taskResult.share_url ? `- Share URL: ${taskResult.share_url}` : ''} + +You can view the task progress and results at the provided URL.` + + return taskResult + } +}) diff --git a/lib/schema/manus.tsx b/lib/schema/manus.tsx new file mode 100644 index 00000000..2ff52767 --- /dev/null +++ b/lib/schema/manus.tsx @@ -0,0 +1,26 @@ +import { DeepPartial } from 'ai' +import { z } from 'zod' + +export const manusSchema = z.object({ + prompt: z + .string() + .describe('The task prompt or instruction for the Manus agent'), + agentProfile: z + .enum(['manus-1.6', 'manus-1.6-lite', 'manus-1.6-max']) + .default('manus-1.6') + .describe( + 'Agent profile to use: manus-1.6 (balanced), manus-1.6-lite (faster), manus-1.6-max (most capable)' + ), + taskMode: z + .enum(['chat', 'adaptive', 'agent']) + .optional() + .describe('Task execution mode: chat, adaptive, or agent'), + interactiveMode: z + .boolean() + .default(false) + .describe( + 'Enable interactive mode to allow Manus to ask follow-up questions when input is insufficient' + ) +}) + +export type PartialManus = DeepPartial From 10fd45100b94e55d60ddaffcc9b51b8fb45f6209 Mon Sep 17 00:00:00 2001 From: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> Date: Tue, 30 Dec 2025 11:26:22 -0500 Subject: [PATCH 2/2] fix: Apply security and code quality improvements to Manus integration - Fix PartialManus type to use z.infer correctly - Add fetch timeout with AbortController (30s) - Sanitize error messages to prevent info leakage - Validate URLs before rendering to prevent injection - Filter undefined fields from request body - Validate API response structure with Zod - Add aria-labels for accessibility - Disable shareable links by default for privacy - Add audit logging for task creation - Update documentation with security features Addresses all review comments from CodeRabbit and qodo-code-review. --- MANUS_INTEGRATION.md | 95 ++++++++++++++--- components/manus-section.tsx | 6 +- lib/agents/tools/manus.tsx | 192 ++++++++++++++++++++++------------- lib/schema/manus.tsx | 4 +- 4 files changed, 209 insertions(+), 88 deletions(-) diff --git a/MANUS_INTEGRATION.md b/MANUS_INTEGRATION.md index 76d63ad8..49a15e68 100644 --- a/MANUS_INTEGRATION.md +++ b/MANUS_INTEGRATION.md @@ -22,16 +22,20 @@ The Manus integration follows a **tool-based architecture** rather than creating 1. **`lib/schema/manus.tsx`** - Zod schema for Manus tool parameters - Defines validation for prompt, agentProfile, taskMode, and interactiveMode - - Provides TypeScript types for type safety + - Provides TypeScript types for type safety using `z.infer` 2. **`lib/agents/tools/manus.tsx`** - Manus tool implementation - Handles API calls to Manus AI platform - - Manages error handling and UI updates - - Creates tasks and returns task information + - Implements comprehensive error handling with sanitized messages + - Validates API responses and URLs for security + - Includes fetch timeout to prevent hanging requests + - Filters undefined fields from request body + - Manages UI updates with proper streaming 3. **`components/manus-section.tsx`** - UI component for displaying Manus task results - Shows task title, ID, and status - - Provides links to view task progress and share results + - Provides accessible links with aria-labels + - Validates URLs before rendering - Follows QCX design patterns ### Files Modified @@ -43,6 +47,39 @@ The Manus integration follows a **tool-based architecture** rather than creating 2. **`.env.local.example`** - Environment configuration - Added MANUS_API_KEY configuration with documentation +## Security Features + +The integration implements several security measures: + +### 1. Error Message Sanitization +- Raw API errors are not exposed to users +- Error messages are sanitized to prevent information leakage +- Sensitive configuration errors are replaced with generic messages + +### 2. URL Validation +- All URLs from the API are validated before use +- Only HTTPS URLs from manus.ai domain are allowed +- Invalid URLs are rejected to prevent injection attacks + +### 3. Request Timeout +- 30-second timeout on API requests using AbortController +- Prevents indefinite hanging on slow or unresponsive API + +### 4. Response Validation +- API responses are validated against expected schema +- Malformed responses are rejected +- Type safety enforced with Zod validation + +### 5. Audit Logging +- Task creation events are logged (without sensitive data) +- Errors are logged securely with timestamps +- Helps with debugging and compliance + +### 6. Privacy by Default +- Shareable links are disabled by default +- Can be enabled when needed for specific use cases +- Prevents accidental data exposure + ## Configuration ### Environment Variables @@ -101,10 +138,13 @@ When a user asks a complex question like "Research the latest developments in qu ``` The tool will: -1. Create a task on the Manus platform -2. Display a loading state in the UI -3. Show the task information with links to view progress -4. Return task details to the Researcher Agent for context +1. Validate the API key is configured +2. Filter undefined fields from the request +3. Create a task on the Manus platform with timeout protection +4. Validate the API response +5. Validate URLs before displaying +6. Show the task information with accessible links +7. Log the task creation for audit trail ## API Reference @@ -113,6 +153,7 @@ The tool will: - **URL**: `https://api.manus.ai/v1/tasks` - **Method**: POST - **Authentication**: API_KEY header +- **Timeout**: 30 seconds ### Request Schema @@ -132,11 +173,21 @@ The tool will: { task_id: string task_title: string - task_url: string - share_url?: string + task_url: string (validated HTTPS URL) + share_url?: string (validated HTTPS URL) } ``` +## Accessibility + +The integration follows WCAG guidelines: + +- Links have descriptive aria-labels +- Icons are marked as decorative with aria-hidden +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly + ## Future Enhancements Potential improvements for future iterations: @@ -147,6 +198,7 @@ Potential improvements for future iterations: 4. **Dedicated Agent**: Create a specialized Manus agent for complex workflows requiring multiple Manus calls 5. **File Attachments**: Support file uploads to Manus tasks 6. **Multi-turn Conversations**: Enable continuing existing Manus tasks +7. **Configurable Share Links**: Add UI option to enable/disable shareable links per task ## Testing @@ -156,7 +208,9 @@ To test the integration: 2. Start the development server: `bun dev` 3. Ask a complex question that would benefit from Manus capabilities 4. Verify the Manus tool is called and task information is displayed -5. Click the task URL to view progress on the Manus platform +5. Check that URLs are valid and accessible +6. Verify error handling with invalid API key +7. Test timeout behavior with network issues ## Troubleshooting @@ -170,10 +224,26 @@ If the Manus tool is not being used: ### API Errors If you encounter API errors: -- Check the console for detailed error messages +- Check the console for detailed error logs (sanitized for security) - Verify your API key has not expired - Ensure you have sufficient credits on your Manus account - Check the Manus API status page for service issues +- Verify network connectivity + +### Timeout Errors + +If requests timeout: +- Check your network connection +- Verify the Manus API is responding +- Consider increasing the timeout if needed for complex tasks +- Check if firewall or proxy is blocking requests + +### Invalid URLs + +If URL validation fails: +- Verify the Manus API is returning valid HTTPS URLs +- Check that URLs are from manus.ai domain +- Report any issues to Manus support ## Resources @@ -181,6 +251,7 @@ If you encounter API errors: - [Manus API Reference](https://open.manus.im/docs/api-reference) - [AI SDK Workflow Patterns](https://ai-sdk.dev/docs/agents/workflows) - [QCX Repository](https://github.com/QueueLab/QCX) +- [WCAG Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) ## License diff --git a/components/manus-section.tsx b/components/manus-section.tsx index 4069cb56..04f747d2 100644 --- a/components/manus-section.tsx +++ b/components/manus-section.tsx @@ -37,9 +37,10 @@ const ManusSection: React.FC = ({ data }) => { href={data.task_url} target="_blank" rel="noopener noreferrer" + aria-label={`View progress for task: ${data.task_title}`} className="inline-flex items-center gap-2 text-sm text-primary hover:underline" > - +