# Custom Agent Execution - Product Requirements Document **Version:** 1.0 **Status:** In Development **Last Updated:** 2025-11-15 --- ## Executive Summary This feature enables users to execute custom AI agents that were created through Morgan (Agent Architect). Users can pin agents locally, access them from the hero section and pinned drawer, and interact with them through the same chat interface as predefined agents. Each custom agent inherits its personality and behavior from its system prompt, created by Morgan. --- ## Problem Statement Currently, the multi-agent chat interface only supports predefined agents configured via environment variables. Custom agents created by Morgan exist as "prompt packages" but lack: - A way to persistently store user-created agents - Easy access/discovery from the UI - Integration with the chat workflow - Execution through n8n with system prompt inheritance Users want to create specialized agents for specific tasks and reuse them without recreating them each time. --- ## Goals 1. **Enable Agent Creation** - Users can create custom agents through Morgan's interactive workflow 2. **Persistent Storage** - Custom agents stored locally (localStorage) for retrieval across sessions 3. **Easy Discovery** - Custom agents visible in hero section and pinned drawer 4. **Seamless Execution** - Custom agents execute with full system prompt context through n8n 5. **Clear UX** - Distinction between predefined and custom agents through visual design --- ## User Stories ### US1: Pin a Custom Agent **As a** user creating an agent with Morgan **I want to** save that agent for later use **So that** I don't have to recreate it each time **Acceptance Criteria:** - [ ] AgentForgeCard displays "Pin for later" button - [ ] Clicking "Pin for later" saves agent to `pinned-agents` localStorage - [ ] Agent appears in pinned drawer immediately after - [ ] Agent data includes: agentId, displayName, summary, tags, systemPrompt, hints, pinnedAt ### US2: Use a Custom Agent Immediately **As a** user who just created an agent **I want to** start chatting with it right away **So that** I can test it without extra steps **Acceptance Criteria:** - [ ] AgentForgeCard displays "Use now" button - [ ] Clicking clears chat history, switches to custom agent, shows fade-out animation - [ ] Custom agent is automatically pinned - [ ] Chat input has focus, ready for first message - [ ] Agent selector shows custom agent as highlighted ### US3: Select Custom Agent from Hero Section **As a** user with pinned agents **I want to** see custom agents in the hero section **So that** I can quickly switch between them **Acceptance Criteria:** - [ ] Hero section displays pinned agents as pill buttons - [ ] Custom agent pills use subdued orange color (palette-based) - [ ] Predefined agents listed first, custom agents after - [ ] Clicking custom agent pill switches to it, clears history - [ ] Custom agent pills are visually distinct from predefined ### US4: Manage Pinned Agents in Drawer **As a** user with multiple pinned agents **I want to** access them from a dedicated drawer **So that** I can organize and manage my custom agents **Acceptance Criteria:** - [ ] Pinned agents drawer shows all saved custom agents - [ ] Each agent card shows: icon, displayName, summary, tags - [ ] Clicking agent card switches to it, clears chat history - [ ] Drawer persists across page reloads - [ ] Visual indication of currently active agent (highlight) ### US5: Custom Agent Execution **As a** system **I need to** execute custom agents with their system prompts **So that** they behave as designed by Morgan **Acceptance Criteria:** - [ ] `/api/chat` routes `custom-*` agentIds to `CUSTOM_AGENT_WEBHOOK` - [ ] systemPrompt is passed in webhook payload - [ ] n8n uses systemPrompt as LLM system context - [ ] Response formatted in standard JSON structure - [ ] Tool calls from custom agents are supported (future extensibility) --- ## Feature Overview ### Architecture ``` User Flow: 1. User asks Morgan to create agent 2. Morgan outputs create_agent_package tool call 3. AgentForgeCard displays with "Use now" / "Pin for later" options 4. User clicks "Use now": - Card fades out - Agent saved to pinned-agents localStorage - Chat history cleared - Agent set as active - Composer focused and ready Chat Flow: 1. User selects custom agent (from hero, drawer, or already active) 2. ChatInterface sends message to /api/chat with systemPrompt 3. /api/chat routes to CUSTOM_AGENT_WEBHOOK 4. n8n receives: { message, sessionId, agentId, systemPrompt, ... } 5. n8n loads systemPrompt into LLM context 6. LLM executes with agent's personality 7. Response returned in standard format 8. Frontend displays like any other agent message ``` ### Data Model **PinnedAgent (localStorage)** ```typescript { agentId: "custom-voyage-architect" displayName: "Voyage Architect" summary: "Creative vacation planning assistant" tags: ["travel", "itinerary", "html"] systemPrompt: "# Web Agent Bundle Instructions\n..." // Full prompt recommendedIcon: "✈️" whenToUse: "Use when you want a vacation itinerary" pinnedAt: "2025-11-15T10:30:00Z" note?: "Optional user note" } ``` **localStorage Keys** - `pinned-agents` - Array of PinnedAgent objects - `chat-session-{agentId}` - Session ID (existing) - `chat-messages-{agentId}` - Message history (existing) ### Components #### 1. AgentForgeCard (Updated) - Displays when Morgan emits `create_agent_package` tool call - Shows agent metadata with animated reveal - Buttons: "Use now", "Pin for later", "Share" - "Use now" action: - Saves to pinned-agents - Triggers fade-out animation - Switches active agent - Clears chat #### 2. Hero Section (Updated) - Shows predefined agent pills (existing style) - Shows pinned custom agent pills (subdued orange) - Custom agents clickable to switch - Inherits existing hero state when chat is empty #### 3. PinnedAgentsDrawer (Updated) - Lists all pinned agents - Click to switch agent + clear chat - Visual highlight of currently active agent - Future: Edit/delete/note-taking per agent #### 4. Agent Selector (Updated) - Highlight active agent (predefined or custom) - Subtle background/border when selected - Shows custom agents if they're ever displayed here (future) #### 5. ChatInterface (Updated) - Fetches systemPrompt from pinned-agents for custom agents - Passes systemPrompt in /api/chat payload - Clears messages when agent changes - Handles response same as predefined agents ### API Changes **POST /api/chat** (Updated) ```typescript Request body: { message: string agentId: string sessionId: string timestamp: string systemPrompt?: string // NEW: For custom agents images?: string[] } Response: { response?: string toolCall?: ToolCall error?: string } ``` **Routing Logic** ```typescript if (agentId.startsWith('custom-')) { webhookUrl = process.env.CUSTOM_AGENT_WEBHOOK } else { webhookUrl = process.env[`AGENT_${agentIndex}_URL`] } ``` ### Environment Variables ```env # Custom Agent Webhook CUSTOM_AGENT_WEBHOOK=https://n8n.example.com/webhook/custom-agent # Existing (unchanged) AGENT_1_URL=... AGENT_2_URL=... ``` ### n8n Workflow **Custom Agent Executor Workflow** ``` Webhook Trigger ↓ Extract: message, systemPrompt, sessionId ↓ Retrieve/Load conversation history (by sessionId) ↓ LLM Node: - System: {{ systemPrompt }} - User: {{ message }} - History: [previous messages] ↓ Code Node (format response): - Parse LLM output - Ensure JSON structure: { messageType, content, toolCall? } - Unwrap nested fields ↓ HTTP Response (JSON) ``` --- ## User Experience ### Agent Creation → Use Flow ``` ┌─────────────────────────────────────┐ │ Chat with Morgan │ │ "Create a vacation planning agent" │ └─────────────────────────────────────┘ ↓ (Morgan outputs tool_call) ┌─────────────────────────────────────┐ │ AgentForgeCard [Animated Reveal] │ │ ✈️ Voyage Architect │ │ Creative vacation planning... │ │ tags: travel, itinerary, html │ │ │ │ [ Use now ] [ Pin for later ] [⤴] │ └─────────────────────────────────────┘ ↓ (Click "Use now") [Fade out animation] [Agent set as active] [Chat cleared] [Hero updated] ↓ ┌─────────────────────────────────────┐ │ Now chatting with: Voyage Architect │ │ [Message input focused] │ └─────────────────────────────────────┘ ``` ### Hero Section Display ``` Predefined Agents (normal colors): [Morgan] [Analyst] [Developer] Custom Agents (subdued orange): [✈️ Voyage Architect] [🎨 Design Specialist] ``` ### Active Agent Indicator ``` Agent Selector: [Morgan] [✓ Voyage Architect] [Developer] ↑ Highlighted when selected ``` --- ## Implementation Phases ### Phase 1: Core Pinned Agent Support (THIS SPRINT) - [ ] Update AgentForgeCard with "Use now" functionality - [ ] Update Hero section to show custom agents - [ ] Update ChatInterface to pass systemPrompt - [ ] Update Agent Selector highlighting - [ ] Update /api/chat routing for custom-* agents - [ ] Environment variable setup ### Phase 2: Enhanced Pinned Drawer (NEXT) - [ ] Edit agent notes - [ ] Delete/unpin agents - [ ] Reorder agents - [ ] Search/filter pinned agents ### Phase 3: Tool Call Support (FUTURE) - [ ] Support show_diff tool calls from custom agents - [ ] Support additional custom tool calls - [ ] Tool call rendering in chat ### Phase 4: Advanced Features (FUTURE) - [ ] Server-side agent sync across devices - [ ] Agent sharing/marketplace - [ ] System prompt versioning - [ ] Agent usage analytics --- ## Technical Specifications ### Browser Storage - **localStorage Key:** `pinned-agents` - **Format:** JSON stringified array of PinnedAgent objects - **Size Limit:** ~5MB typical, ~50-100 agents max per key - **Future:** Migrate to IndexedDB if needed for larger scale ### Session Management - Sessions maintained per agent in n8n (not on client) - `sessionId` format: `session-{agentId}-{timestamp}-{random}` - New session created when user clicks "Start fresh conversation" - Existing session reused when switching back to same agent ### Response Format Consistency All responses (predefined and custom agents) return: ```json { "messageType": "regular_message" | "tool_call", "content": "Message text", "toolCall": { "type": "tool_call", "name": "tool_name", "payload": {} } } ``` ### Color Palette for Custom Agents - Use existing `burnt-orange` or `terracotta` with opacity - Proposed: `bg-burnt-orange/40` or palette muted variant - Ensure WCAG AA contrast on background --- ## Testing Strategy ### Unit Tests - [ ] PinnedAgent localStorage operations (save, retrieve, delete) - [ ] Agent selector highlighting logic - [ ] ChatInterface systemPrompt extraction ### Integration Tests - [ ] Create agent → save to localStorage → display in hero → click → chat - [ ] Switch between predefined and custom agents - [ ] Message routing to correct webhook ### E2E Tests - [ ] Full flow: Morgan creates agent → Use now → Chat → Test response - [ ] Custom agent response formatting - [ ] Session persistence across page reload ### Manual Testing Checklist - [ ] Pin agent, reload page, agent still there - [ ] Switch agents, chat history clears - [ ] Custom agent responds with correct personality - [ ] Tool calls from custom agents work (if supported) - [ ] Mobile responsiveness (hero pills, drawer) --- ## Success Metrics - ✅ Users can pin custom agents created by Morgan - ✅ Pinned agents accessible and usable within 2 clicks - ✅ Custom agents execute with inherited system prompts - ✅ No errors in response routing or formatting - ✅ Chat history properly isolated per agent - ✅ Visual distinction between predefined and custom agents --- ## Rollout Plan 1. **Development** - Implement all 4 phases of Phase 1 2. **Testing** - Manual + automated testing on localhost 3. **Staging** - Deploy to staging environment 4. **Production** - Deploy to Cloudflare Workers 5. **Monitoring** - Watch logs for routing errors, webhook failures --- ## Future Considerations - **Encryption:** Move systemPrompts to server-side storage (currently plain text) - **Sharing:** Enable users to share agent prompts (QR code, link) - **Versioning:** Track system prompt changes over time - **Analytics:** Track which agents users create/use most - **Marketplace:** Community-shared agents - **Advanced Pinning:** Tags, collections, search across pinned agents --- ## Appendix ### Custom Agent ID Format - Format: `custom-{descriptor}` or `custom-{uuid}` - Example: `custom-voyage-architect`, `custom-a1b2c3d4` - Used for localStorage key, session ID, and routing ### Error Handling - Missing systemPrompt → Error response, user prompted to re-pin - Custom webhook down → Generic error message + fallback to Morgan - Malformed response → Log error, return last working message ### Browser Compatibility - localStorage support required (all modern browsers) - Graceful degradation: if localStorage unavailable, prompt user - No Edge cases expected given localStorage ubiquity