Skip to main content

Agent Builder Sandbox

Interactive Visual Agent Configuration Tool

Document ID: E2-AGENT-BUILDER
Version: 1.0
Category: P5 - Interactive Learning
Format: React JSX Component


Component Overview

The Agent Builder Sandbox allows users to visually configure agentic systems by selecting paradigms, components, and tools. Users can see how their choices affect the agent architecture and export configurations for implementation.


JSX Component

import React, { useState } from 'react';
import { Settings, Database, Wrench, Users, Brain, Play, Download, Eye, AlertTriangle, CheckCircle, Info } from 'lucide-react';

const AgentBuilderSandbox = () => {
const [config, setConfig] = useState({
paradigm: null,
components: {
planning: [],
memory: [],
tools: [],
collaboration: null
},
settings: {
temperature: 0.7,
maxIterations: 5,
confidenceThreshold: 0.7,
auditLevel: 'standard'
}
});

const [activeTab, setActiveTab] = useState('paradigm');
const [showPreview, setShowPreview] = useState(false);

const paradigms = [
{
id: 'LSR',
name: 'Latent Space Reasoner',
icon: '🧠',
color: 'purple',
description: 'Creative synthesis using parametric knowledge',
useCases: ['Content creation', 'Brainstorming', 'Creative writing'],
recommendedComponents: {
planning: ['chain_of_thought'],
memory: ['context_window'],
tools: [],
collaboration: null
}
},
{
id: 'GS',
name: 'Grounded Synthesizer',
icon: '📚',
color: 'emerald',
description: 'Evidence-based reasoning with citations',
useCases: ['Research', 'Analysis', 'Fact-based reports'],
recommendedComponents: {
planning: ['query_decomposition', 'chain_of_thought'],
memory: ['context_window', 'vector_store'],
tools: ['knowledge_search', 'web_search'],
collaboration: null
}
},
{
id: 'EP',
name: 'Emergent Planner',
icon: '🎯',
color: 'amber',
description: 'Adaptive multi-step execution with learning',
useCases: ['Problem solving', 'Investigation', 'Complex tasks'],
recommendedComponents: {
planning: ['tree_of_thought', 'cognitive_map'],
memory: ['context_window', 'episodic_memory', 'reflexion_memory'],
tools: ['all_categories'],
collaboration: 'hierarchical'
}
},
{
id: 'VE',
name: 'Verifiable Executor',
icon: '✅',
color: 'blue',
description: 'Protocol-driven execution with audit trails',
useCases: ['Compliance', 'Workflows', 'Regulated processes'],
recommendedComponents: {
planning: ['protocol_mapper'],
memory: ['context_window', 'audit_log', 'state_register'],
tools: ['action_tools'],
collaboration: 'pipeline'
}
}
];

const components = {
planning: [
{ id: 'chain_of_thought', name: 'Chain of Thought', description: 'Sequential reasoning steps' },
{ id: 'tree_of_thought', name: 'Tree of Thought', description: 'Branching exploration of options' },
{ id: 'query_decomposition', name: 'Query Decomposition', description: 'Break complex queries into sub-queries' },
{ id: 'cognitive_map', name: 'Cognitive Map', description: 'Goal-state representation' },
{ id: 'protocol_mapper', name: 'Protocol Mapper', description: 'Match tasks to defined protocols' }
],
memory: [
{ id: 'context_window', name: 'Context Window', description: 'Conversation history in context' },
{ id: 'vector_store', name: 'Vector Store', description: 'Semantic search over knowledge' },
{ id: 'knowledge_graph', name: 'Knowledge Graph', description: 'Structured relationship storage' },
{ id: 'episodic_memory', name: 'Episodic Memory', description: 'Task execution history' },
{ id: 'reflexion_memory', name: 'Reflexion Memory', description: 'Learning from failures' },
{ id: 'audit_log', name: 'Audit Log', description: 'Immutable action record' },
{ id: 'state_register', name: 'State Register', description: 'Protocol execution state' }
],
tools: [
{ id: 'web_search', name: 'Web Search', category: 'knowledge', description: 'Search the internet' },
{ id: 'knowledge_search', name: 'Knowledge Search', category: 'knowledge', description: 'Search internal knowledge base' },
{ id: 'database_query', name: 'Database Query', category: 'knowledge', description: 'Query structured data' },
{ id: 'api_call', name: 'API Call', category: 'action', description: 'Call external APIs' },
{ id: 'file_operations', name: 'File Operations', category: 'action', description: 'Read/write files' },
{ id: 'email_send', name: 'Email Send', category: 'action', description: 'Send email messages' },
{ id: 'calculator', name: 'Calculator', category: 'compute', description: 'Mathematical calculations' },
{ id: 'code_execute', name: 'Code Execution', category: 'compute', description: 'Run code in sandbox' }
],
collaboration: [
{ id: 'none', name: 'Single Agent', description: 'No collaboration' },
{ id: 'hierarchical', name: 'Hierarchical', description: 'Orchestrator delegates to specialists' },
{ id: 'distributed', name: 'Distributed', description: 'Peer debate and consensus' },
{ id: 'pipeline', name: 'Pipeline', description: 'Sequential processing stages' }
]
};

const toggleComponent = (category, componentId) => {
setConfig(prev => {
const current = prev.components[category];
if (Array.isArray(current)) {
const newComponents = current.includes(componentId)
? current.filter(c => c !== componentId)
: [...current, componentId];
return {
...prev,
components: { ...prev.components, [category]: newComponents }
};
} else {
return {
...prev,
components: { ...prev.components, [category]: componentId }
};
}
});
};

const selectParadigm = (paradigmId) => {
const paradigm = paradigms.find(p => p.id === paradigmId);
setConfig(prev => ({
...prev,
paradigm: paradigmId,
components: { ...paradigm.recommendedComponents }
}));
};

const updateSetting = (key, value) => {
setConfig(prev => ({
...prev,
settings: { ...prev.settings, [key]: value }
}));
};

const getValidationMessages = () => {
const messages = [];

if (!config.paradigm) {
messages.push({ type: 'error', text: 'Select a paradigm to begin' });
}

if (config.paradigm === 'GS' && !config.components.tools.some(t =>
['web_search', 'knowledge_search', 'database_query'].includes(t)
)) {
messages.push({ type: 'warning', text: 'GS paradigm typically requires knowledge retrieval tools' });
}

if (config.paradigm === 'VE' && !config.components.memory.includes('audit_log')) {
messages.push({ type: 'warning', text: 'VE paradigm should include audit logging for compliance' });
}

if (config.paradigm === 'EP' && !config.components.memory.includes('reflexion_memory')) {
messages.push({ type: 'info', text: 'Consider adding Reflexion Memory for learning capability' });
}

if (config.components.tools.length > 5) {
messages.push({ type: 'info', text: 'Many tools selected - consider impact on token usage' });
}

if (messages.length === 0 && config.paradigm) {
messages.push({ type: 'success', text: 'Configuration looks good!' });
}

return messages;
};

const exportConfig = () => {
const exportData = {
paradigm: config.paradigm,
components: config.components,
settings: config.settings,
generatedAt: new Date().toISOString()
};

const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `agent-config-${config.paradigm || 'draft'}.json`;
a.click();
};

const selectedParadigm = paradigms.find(p => p.id === config.paradigm);

const getColorClasses = (color, selected) => {
const colors = {
purple: selected ? 'bg-purple-100 border-purple-500' : 'border-purple-200 hover:border-purple-400',
emerald: selected ? 'bg-emerald-100 border-emerald-500' : 'border-emerald-200 hover:border-emerald-400',
amber: selected ? 'bg-amber-100 border-amber-500' : 'border-amber-200 hover:border-amber-400',
blue: selected ? 'bg-blue-100 border-blue-500' : 'border-blue-200 hover:border-blue-400'
};
return colors[color];
};

return (
<div className="max-w-6xl mx-auto p-6 bg-gray-50 min-h-screen">
{/* Header */}
<div className="bg-white rounded-lg shadow-sm p-6 mb-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-gray-800">Agent Builder Sandbox</h1>
<p className="text-gray-500">Configure your agentic AI system</p>
</div>
<div className="flex gap-3">
<button
onClick={() => setShowPreview(!showPreview)}
className="flex items-center gap-2 px-4 py-2 border rounded-lg hover:bg-gray-50"
>
<Eye className="w-4 h-4" />
Preview
</button>
<button
onClick={exportConfig}
disabled={!config.paradigm}
className="flex items-center gap-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:opacity-50"
>
<Download className="w-4 h-4" />
Export
</button>
</div>
</div>
</div>

<div className="grid grid-cols-3 gap-6">
{/* Main Configuration Area */}
<div className="col-span-2 space-y-6">
{/* Tabs */}
<div className="bg-white rounded-lg shadow-sm">
<div className="flex border-b">
{[
{ id: 'paradigm', label: 'Paradigm', icon: Brain },
{ id: 'planning', label: 'Planning', icon: Settings },
{ id: 'memory', label: 'Memory', icon: Database },
{ id: 'tools', label: 'Tools', icon: Wrench },
{ id: 'collaboration', label: 'Collaboration', icon: Users }
].map(tab => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`flex items-center gap-2 px-6 py-4 border-b-2 transition-colors ${
activeTab === tab.id
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700'
}`}
>
<tab.icon className="w-4 h-4" />
{tab.label}
</button>
))}
</div>

<div className="p-6">
{/* Paradigm Selection */}
{activeTab === 'paradigm' && (
<div className="grid grid-cols-2 gap-4">
{paradigms.map(paradigm => (
<button
key={paradigm.id}
onClick={() => selectParadigm(paradigm.id)}
className={`p-4 rounded-lg border-2 text-left transition-all ${
getColorClasses(paradigm.color, config.paradigm === paradigm.id)
}`}
>
<div className="flex items-center gap-3 mb-2">
<span className="text-2xl">{paradigm.icon}</span>
<div>
<span className="font-bold text-gray-800">{paradigm.id}</span>
<p className="text-sm text-gray-600">{paradigm.name}</p>
</div>
</div>
<p className="text-sm text-gray-500 mb-3">{paradigm.description}</p>
<div className="flex flex-wrap gap-1">
{paradigm.useCases.map((useCase, idx) => (
<span key={idx} className="px-2 py-0.5 bg-gray-100 rounded text-xs text-gray-600">
{useCase}
</span>
))}
</div>
</button>
))}
</div>
)}

{/* Planning Components */}
{activeTab === 'planning' && (
<div className="space-y-3">
<p className="text-sm text-gray-500 mb-4">Select planning mechanisms for your agent</p>
{components.planning.map(comp => (
<button
key={comp.id}
onClick={() => toggleComponent('planning', comp.id)}
className={`w-full p-4 rounded-lg border-2 text-left transition-all ${
config.components.planning.includes(comp.id)
? 'bg-blue-50 border-blue-500'
: 'border-gray-200 hover:border-gray-400'
}`}
>
<div className="flex items-center justify-between">
<div>
<span className="font-medium text-gray-800">{comp.name}</span>
<p className="text-sm text-gray-500">{comp.description}</p>
</div>
{config.components.planning.includes(comp.id) && (
<CheckCircle className="w-5 h-5 text-blue-500" />
)}
</div>
</button>
))}
</div>
)}

{/* Memory Components */}
{activeTab === 'memory' && (
<div className="space-y-3">
<p className="text-sm text-gray-500 mb-4">Select memory layers for your agent</p>
{components.memory.map(comp => (
<button
key={comp.id}
onClick={() => toggleComponent('memory', comp.id)}
className={`w-full p-4 rounded-lg border-2 text-left transition-all ${
config.components.memory.includes(comp.id)
? 'bg-blue-50 border-blue-500'
: 'border-gray-200 hover:border-gray-400'
}`}
>
<div className="flex items-center justify-between">
<div>
<span className="font-medium text-gray-800">{comp.name}</span>
<p className="text-sm text-gray-500">{comp.description}</p>
</div>
{config.components.memory.includes(comp.id) && (
<CheckCircle className="w-5 h-5 text-blue-500" />
)}
</div>
</button>
))}
</div>
)}

{/* Tools */}
{activeTab === 'tools' && (
<div className="space-y-6">
{['knowledge', 'action', 'compute'].map(category => (
<div key={category}>
<h3 className="text-sm font-medium text-gray-700 mb-3 capitalize">{category} Tools</h3>
<div className="grid grid-cols-2 gap-3">
{components.tools.filter(t => t.category === category).map(tool => (
<button
key={tool.id}
onClick={() => toggleComponent('tools', tool.id)}
className={`p-3 rounded-lg border-2 text-left transition-all ${
config.components.tools.includes(tool.id)
? 'bg-blue-50 border-blue-500'
: 'border-gray-200 hover:border-gray-400'
}`}
>
<span className="font-medium text-gray-800 text-sm">{tool.name}</span>
<p className="text-xs text-gray-500">{tool.description}</p>
</button>
))}
</div>
</div>
))}
</div>
)}

{/* Collaboration */}
{activeTab === 'collaboration' && (
<div className="space-y-3">
<p className="text-sm text-gray-500 mb-4">Select collaboration topology</p>
{components.collaboration.map(collab => (
<button
key={collab.id}
onClick={() => toggleComponent('collaboration', collab.id)}
className={`w-full p-4 rounded-lg border-2 text-left transition-all ${
config.components.collaboration === collab.id
? 'bg-blue-50 border-blue-500'
: 'border-gray-200 hover:border-gray-400'
}`}
>
<div className="flex items-center justify-between">
<div>
<span className="font-medium text-gray-800">{collab.name}</span>
<p className="text-sm text-gray-500">{collab.description}</p>
</div>
{config.components.collaboration === collab.id && (
<CheckCircle className="w-5 h-5 text-blue-500" />
)}
</div>
</button>
))}
</div>
)}
</div>
</div>

{/* Settings */}
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="font-medium text-gray-800 mb-4">Agent Settings</h3>
<div className="grid grid-cols-2 gap-6">
<div>
<label className="block text-sm text-gray-600 mb-2">
Temperature: {config.settings.temperature}
</label>
<input
type="range"
min="0"
max="1"
step="0.1"
value={config.settings.temperature}
onChange={(e) => updateSetting('temperature', parseFloat(e.target.value))}
className="w-full"
/>
<div className="flex justify-between text-xs text-gray-400">
<span>Precise</span>
<span>Creative</span>
</div>
</div>

<div>
<label className="block text-sm text-gray-600 mb-2">
Max Iterations: {config.settings.maxIterations}
</label>
<input
type="range"
min="1"
max="20"
value={config.settings.maxIterations}
onChange={(e) => updateSetting('maxIterations', parseInt(e.target.value))}
className="w-full"
/>
<div className="flex justify-between text-xs text-gray-400">
<span>Quick</span>
<span>Thorough</span>
</div>
</div>

<div>
<label className="block text-sm text-gray-600 mb-2">
Confidence Threshold: {config.settings.confidenceThreshold}
</label>
<input
type="range"
min="0.5"
max="0.95"
step="0.05"
value={config.settings.confidenceThreshold}
onChange={(e) => updateSetting('confidenceThreshold', parseFloat(e.target.value))}
className="w-full"
/>
</div>

<div>
<label className="block text-sm text-gray-600 mb-2">Audit Level</label>
<select
value={config.settings.auditLevel}
onChange={(e) => updateSetting('auditLevel', e.target.value)}
className="w-full p-2 border rounded-lg"
>
<option value="minimal">Minimal</option>
<option value="standard">Standard</option>
<option value="full">Full</option>
</select>
</div>
</div>
</div>
</div>

{/* Sidebar */}
<div className="space-y-6">
{/* Current Configuration Summary */}
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="font-medium text-gray-800 mb-4">Configuration Summary</h3>

{selectedParadigm ? (
<div className="space-y-4">
<div className={`p-3 rounded-lg ${getColorClasses(selectedParadigm.color, true)}`}>
<span className="text-2xl mr-2">{selectedParadigm.icon}</span>
<span className="font-bold">{selectedParadigm.id}</span>
</div>

<div>
<h4 className="text-xs font-medium text-gray-500 uppercase mb-2">Planning</h4>
<div className="flex flex-wrap gap-1">
{config.components.planning.map(p => (
<span key={p} className="px-2 py-1 bg-gray-100 rounded text-xs">{p}</span>
))}
{config.components.planning.length === 0 && (
<span className="text-xs text-gray-400">None selected</span>
)}
</div>
</div>

<div>
<h4 className="text-xs font-medium text-gray-500 uppercase mb-2">Memory</h4>
<div className="flex flex-wrap gap-1">
{config.components.memory.map(m => (
<span key={m} className="px-2 py-1 bg-gray-100 rounded text-xs">{m}</span>
))}
</div>
</div>

<div>
<h4 className="text-xs font-medium text-gray-500 uppercase mb-2">Tools ({config.components.tools.length})</h4>
<div className="flex flex-wrap gap-1">
{config.components.tools.slice(0, 4).map(t => (
<span key={t} className="px-2 py-1 bg-gray-100 rounded text-xs">{t}</span>
))}
{config.components.tools.length > 4 && (
<span className="px-2 py-1 bg-gray-200 rounded text-xs">
+{config.components.tools.length - 4} more
</span>
)}
</div>
</div>

<div>
<h4 className="text-xs font-medium text-gray-500 uppercase mb-2">Collaboration</h4>
<span className="px-2 py-1 bg-gray-100 rounded text-xs">
{config.components.collaboration || 'None'}
</span>
</div>
</div>
) : (
<p className="text-gray-400 text-sm">Select a paradigm to begin</p>
)}
</div>

{/* Validation Messages */}
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="font-medium text-gray-800 mb-4">Validation</h3>
<div className="space-y-3">
{getValidationMessages().map((msg, idx) => (
<div
key={idx}
className={`flex items-start gap-2 p-3 rounded-lg ${
msg.type === 'error' ? 'bg-red-50 text-red-700' :
msg.type === 'warning' ? 'bg-amber-50 text-amber-700' :
msg.type === 'success' ? 'bg-green-50 text-green-700' :
'bg-blue-50 text-blue-700'
}`}
>
{msg.type === 'error' && <AlertTriangle className="w-4 h-4 flex-shrink-0 mt-0.5" />}
{msg.type === 'warning' && <AlertTriangle className="w-4 h-4 flex-shrink-0 mt-0.5" />}
{msg.type === 'success' && <CheckCircle className="w-4 h-4 flex-shrink-0 mt-0.5" />}
{msg.type === 'info' && <Info className="w-4 h-4 flex-shrink-0 mt-0.5" />}
<span className="text-sm">{msg.text}</span>
</div>
))}
</div>
</div>

{/* Resource Estimate */}
{config.paradigm && (
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="font-medium text-gray-800 mb-4">Resource Estimate</h3>
<div className="space-y-3 text-sm">
<div className="flex justify-between">
<span className="text-gray-500">Token Multiplier</span>
<span className="font-medium">
{config.components.collaboration && config.components.collaboration !== 'none' ? '15x' : '4x'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-500">Memory Overhead</span>
<span className="font-medium">
{config.components.memory.length > 3 ? 'High' :
config.components.memory.length > 1 ? 'Medium' : 'Low'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-500">Latency Class</span>
<span className="font-medium">
{config.paradigm === 'LSR' ? 'Fast' :
config.paradigm === 'VE' ? 'Medium' :
config.paradigm === 'GS' ? 'Medium' : 'Variable'}
</span>
</div>
</div>
</div>
)}
</div>
</div>
</div>
);
};

export default AgentBuilderSandbox;

Usage and Integration

The Agent Builder Sandbox provides:

  • Visual paradigm selection with automatic component recommendations
  • Component selection for planning, memory, tools, and collaboration
  • Real-time validation and guidance
  • Configuration export for implementation
  • Resource estimation based on selections

Component maintained by CODITECT Education Team. Feedback: education@coditect.com