- Update `wrangler.jsonc` to correct the `CUSTOM_AGENT_WEBHOOK` URL. - Enhance `page.tsx` to load custom agents from localStorage and merge them with predefined agents. - Modify `route.ts` to validate `systemPrompt` for custom agents and include it in the webhook payload. - Adjust `chat-interface.tsx` to handle custom agents more effectively, including system prompt integration and event dispatching for pinned agents. - Remove obsolete `CUSTOM_AGENT_EXECUTION_PRD.md` and `DIFF_TOOL_USAGE.md` files as part of cleanup.
14 KiB
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
- Enable Agent Creation - Users can create custom agents through Morgan's interactive workflow
- Persistent Storage - Custom agents stored locally (localStorage) for retrieval across sessions
- Easy Discovery - Custom agents visible in hero section and pinned drawer
- Seamless Execution - Custom agents execute with full system prompt context through n8n
- 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-agentslocalStorage - 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/chatroutescustom-*agentIds toCUSTOM_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)
{
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 objectschat-session-{agentId}- Session ID (existing)chat-messages-{agentId}- Message history (existing)
Components
1. AgentForgeCard (Updated)
- Displays when Morgan emits
create_agent_packagetool 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)
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
if (agentId.startsWith('custom-')) {
webhookUrl = process.env.CUSTOM_AGENT_WEBHOOK
} else {
webhookUrl = process.env[`AGENT_${agentIndex}_URL`]
}
Environment Variables
# 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)
sessionIdformat: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:
{
"messageType": "regular_message" | "tool_call",
"content": "Message text",
"toolCall": {
"type": "tool_call",
"name": "tool_name",
"payload": {}
}
}
Color Palette for Custom Agents
- Use existing
burnt-orangeorterracottawith opacity - Proposed:
bg-burnt-orange/40or 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
- Development - Implement all 4 phases of Phase 1
- Testing - Manual + automated testing on localhost
- Staging - Deploy to staging environment
- Production - Deploy to Cloudflare Workers
- 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}orcustom-{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