sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
521 lines (404 loc) ⢠14.1 kB
JavaScript
/**
* Web Command Processor
* Handles slash commands (*help, *status, etc.) in web UI bundles
* This gets embedded into web bundles to provide interactive command support
*/
class WebCommandProcessor {
constructor() {
this.currentAgent = 'sf-orchestrator';
this.currentPhase = 'planning';
this.contextUsage = {
planning: { used: 0, limit: 128000 },
development: { used: 0, limit: 32000 },
};
this.artifacts = [];
this.checkpoints = [];
this.dependencies = new Set();
this.sessionStartTime = Date.now();
this.transformHistory = [];
}
/**
* Process a command and return the response
* @param {string} command - The command to process (e.g., "*help", "*status")
* @param {object} context - Current context object
* @returns {string} - Command response
*/
processCommand(command, context = {}) {
const parts = command.trim().split(' ');
const cmd = parts[0].toLowerCase();
const args = parts.slice(1);
switch (cmd) {
case '*help':
return this.showHelp();
case '*status':
return this.showStatus();
case '*reset':
return this.resetSession();
case '*agent':
return this.switchAgent(args[0]);
case '*list-agents':
return this.listAgents();
case '*transform':
return this.transformAgent(args[0]);
case '*orchestrator':
return this.returnToOrchestrator();
case '*phase':
return this.switchPhase(args[0]);
case '*context':
return this.showContext();
case '*workflow':
return this.startWorkflow();
case '*task':
return this.executeTask(args.join(' '));
case '*handoff':
return this.createHandoff(args[0]);
case '*artifacts':
return this.listArtifacts();
case '*save':
return this.saveArtifact(args.join(' '));
case '*load':
return this.loadResource(args.join(' '));
case '*checkpoint':
return this.createCheckpoint();
case '*summary':
return this.generateSummary();
case '*next-steps':
return this.suggestNextSteps();
case '*capabilities':
return this.showCapabilities();
case '*dependencies':
return this.listDependencies();
case '*templates':
return this.showTemplates();
case '*checklists':
return this.showChecklists();
default:
return `Unknown command: ${cmd}. Type *help for available commands.`;
}
}
showHelp() {
return `
# šÆ Available Commands
## Core Commands
- **\*help** - Show this help message
- **\*status** - Display current session status
- **\*reset** - Reset session to initial state
## Agent Management
- **\*agent <name>** - Switch to specific agent
- **\*list-agents** - List all available agents
- **\*transform <agent>** - Transform into specialist agent
- **\*orchestrator** - Return to orchestrator mode
## Phase Management
- **\*phase planning** - Switch to planning phase (128k tokens)
- **\*phase development** - Switch to development phase (32k tokens)
- **\*context** - Show context usage
## Workflow & Tasks
- **\*workflow** - Start interactive workflow
- **\*task <name>** - Execute specific task
- **\*handoff <agent>** - Create handoff to another agent
## Artifacts & Resources
- **\*artifacts** - List session artifacts
- **\*save <name>** - Mark artifact as saved
- **\*load <path>** - Load embedded resource
## Session Management
- **\*checkpoint** - Create session checkpoint
- **\*summary** - Generate work summary
- **\*next-steps** - Get suggested next actions
## Discovery
- **\*capabilities** - Show agent capabilities
- **\*dependencies** - List loaded dependencies
- **\*templates** - Show available templates
- **\*checklists** - Show available checklists
`;
}
showStatus() {
const uptime = Math.floor((Date.now() - this.sessionStartTime) / 1000);
const minutes = Math.floor(uptime / 60);
const seconds = uptime % 60;
return `
# š Current Status
**Agent:** ${this.currentAgent}
**Phase:** ${this.currentPhase}
**Session Time:** ${minutes}m ${seconds}s
**Context Usage:** ${this.contextUsage[this.currentPhase].used} / ${this.contextUsage[this.currentPhase].limit} tokens
**Artifacts Created:** ${this.artifacts.length}
**Checkpoints:** ${this.checkpoints.length}
**Transform History:** ${this.transformHistory.join(' ā ') || 'None'}
`;
}
resetSession() {
this.currentAgent = 'sf-orchestrator';
this.currentPhase = 'planning';
this.contextUsage = {
planning: { used: 0, limit: 128000 },
development: { used: 0, limit: 32000 },
};
this.artifacts = [];
this.checkpoints = [];
this.transformHistory = [];
this.sessionStartTime = Date.now();
return 'ā
Session reset to initial state';
}
switchAgent(agentName) {
if (!agentName) {
return 'ā Please specify an agent name. Use *list-agents to see available agents.';
}
const previousAgent = this.currentAgent;
this.currentAgent = agentName;
return `ā
Switched from ${previousAgent} to ${agentName}`;
}
listAgents() {
// This would be populated from the bundle manifest
const agents = [
'sf-orchestrator - Main orchestration agent',
'sf-architect - System architecture specialist',
'sf-analyst - Business analysis expert',
'sf-developer - Code implementation specialist',
'sf-pm - Project management',
'sf-tester - Quality assurance',
'sf-devops - Deployment and CI/CD',
];
return `
# š¤ Available Agents
${agents.map((a) => `- ${a}`).join('\n')}
Use \*agent <name> to switch agents or \*transform <name> for dynamic transformation.
`;
}
transformAgent(targetAgent) {
if (!targetAgent) {
return 'ā Please specify target agent for transformation';
}
this.transformHistory.push(this.currentAgent);
const previousAgent = this.currentAgent;
this.currentAgent = targetAgent;
return `
ā
Dynamic Transformation Complete
**From:** ${previousAgent}
**To:** ${targetAgent}
**Mode:** ${this.currentPhase === 'planning' ? 'Rich (Full Context)' : 'Lean (Optimized)'}
The orchestrator has transformed into ${targetAgent} while maintaining session context.
`;
}
returnToOrchestrator() {
const previousAgent = this.currentAgent;
this.currentAgent = 'sf-orchestrator';
this.transformHistory = [];
return `ā
Returned to orchestrator mode from ${previousAgent}`;
}
switchPhase(phase) {
if (!phase || !['planning', 'development'].includes(phase)) {
return 'ā Invalid phase. Use: *phase planning OR *phase development';
}
const previousPhase = this.currentPhase;
this.currentPhase = phase;
return `
ā
Phase switched from ${previousPhase} to ${phase}
**New Context Limit:** ${this.contextUsage[phase].limit} tokens
**Optimization:** ${phase === 'development' ? 'Lean agents for 70% context reduction' : 'Rich agents with full context'}
`;
}
showContext() {
const planning = this.contextUsage.planning;
const development = this.contextUsage.development;
const currentUsage = this.contextUsage[this.currentPhase];
const percentage = Math.round((currentUsage.used / currentUsage.limit) * 100);
return `
# š Context Usage
## Current Phase: ${this.currentPhase}
- **Used:** ${currentUsage.used} tokens
- **Limit:** ${currentUsage.limit} tokens
- **Available:** ${currentUsage.limit - currentUsage.used} tokens
- **Usage:** ${percentage}%
## Phase Comparison
| Phase | Used | Limit | Usage |
|-------|------|-------|-------|
| Planning | ${planning.used} | ${planning.limit} | ${Math.round((planning.used / planning.limit) * 100)}% |
| Development | ${development.used} | ${development.limit} | ${Math.round((development.used / development.limit) * 100)}% |
`;
}
startWorkflow() {
return `
# š Interactive Workflow
Choose your starting point:
1. **Requirements Gathering** - Start with business requirements
2. **Technical Planning** - Jump to architecture design
3. **Story Creation** - Create user stories
4. **Implementation** - Begin coding
5. **Testing** - Start with test planning
Reply with the number or name of your choice to begin.
`;
}
executeTask(taskName) {
if (!taskName) {
return 'ā Please specify a task name. Example: *task create-story';
}
return `
ā
Executing task: ${taskName}
Loading task definition from .sf-core/tasks/${taskName}.md
Task execution started with current agent: ${this.currentAgent}
`;
}
createHandoff(toAgent) {
if (!toAgent) {
return 'ā Please specify target agent for handoff';
}
const handoff = {
from: this.currentAgent,
to: toAgent,
artifacts: this.artifacts.slice(-3), // Last 3 artifacts
timestamp: new Date().toISOString(),
};
return `
# š¤ Agent Handoff Created
**From:** ${handoff.from}
**To:** ${handoff.to}
**Timestamp:** ${handoff.timestamp}
## Artifacts Being Passed:
${handoff.artifacts.length > 0 ? handoff.artifacts.map((a) => `- ${a}`).join('\n') : '- No artifacts to pass'}
## Next Steps:
Switch to ${toAgent} using \*agent ${toAgent} to continue with these artifacts.
`;
}
listArtifacts() {
if (this.artifacts.length === 0) {
return 'š No artifacts created yet in this session';
}
return `
# š Session Artifacts
${this.artifacts.map((a, i) => `${i + 1}. ${a}`).join('\n')}
Total: ${this.artifacts.length} artifacts
`;
}
saveArtifact(name) {
if (!name) {
return 'ā Please provide artifact name to save';
}
this.artifacts.push(name);
return `ā
Artifact "${name}" marked as saved (${this.artifacts.length} total)`;
}
loadResource(resourcePath) {
if (!resourcePath) {
return 'ā Please specify resource path. Example: *load .sf-core/tasks/create-story.md';
}
this.dependencies.add(resourcePath);
return `ā
Loading resource: ${resourcePath}`;
}
createCheckpoint() {
const checkpoint = {
id: this.checkpoints.length + 1,
timestamp: new Date().toISOString(),
agent: this.currentAgent,
phase: this.currentPhase,
artifactCount: this.artifacts.length,
};
this.checkpoints.push(checkpoint);
return `
ā
Checkpoint #${checkpoint.id} created
**Time:** ${checkpoint.timestamp}
**Agent:** ${checkpoint.agent}
**Phase:** ${checkpoint.phase}
**Artifacts:** ${checkpoint.artifactCount}
`;
}
generateSummary() {
const uptime = Math.floor((Date.now() - this.sessionStartTime) / 1000);
const minutes = Math.floor(uptime / 60);
return `
# š Session Summary
## Overview
- **Duration:** ${minutes} minutes
- **Current Agent:** ${this.currentAgent}
- **Phase:** ${this.currentPhase}
- **Checkpoints:** ${this.checkpoints.length}
## Work Completed
- **Artifacts Created:** ${this.artifacts.length}
- **Agents Used:** ${[...new Set([...this.transformHistory, this.currentAgent])].join(', ')}
- **Resources Loaded:** ${this.dependencies.size}
## Artifacts
${
this.artifacts
.slice(-5)
.map((a) => `- ${a}`)
.join('\n') || 'No artifacts created'
}
## Next Recommended Actions
${this.suggestNextSteps()}
`;
}
suggestNextSteps() {
const suggestions = [];
if (this.currentPhase === 'planning' && this.artifacts.length > 2) {
suggestions.push('Switch to development phase (*phase development)');
}
if (this.artifacts.length === 0) {
suggestions.push('Create initial artifacts (*task create-story)');
}
if (this.currentAgent === 'sf-orchestrator') {
suggestions.push('Transform to specialist agent (*transform sf-architect)');
}
if (this.checkpoints.length === 0) {
suggestions.push('Create a checkpoint (*checkpoint)');
}
return suggestions.length > 0
? suggestions.map((s, i) => `${i + 1}. ${s}`).join('\n')
: 'Continue with current workflow';
}
showCapabilities() {
const capabilities = {
'sf-orchestrator': ['Coordination', 'Phase management', 'Agent transformation'],
'sf-architect': ['System design', 'Technical architecture', 'Integration planning'],
'sf-analyst': ['Requirements analysis', 'Story creation', 'Business logic'],
'sf-developer': ['Code implementation', 'Apex development', 'LWC components'],
'sf-pm': ['Project planning', 'Timeline management', 'Resource allocation'],
'sf-tester': ['Test planning', 'Quality assurance', 'Bug tracking'],
'sf-devops': ['CI/CD setup', 'Deployment', 'Environment management'],
};
const agentCaps = capabilities[this.currentAgent] || ['General tasks'];
return `
# šÆ ${this.currentAgent} Capabilities
${agentCaps.map((c) => `- ${c}`).join('\n')}
Type *transform <agent> to access other capabilities.
`;
}
listDependencies() {
if (this.dependencies.size === 0) {
return 'š¦ No dependencies loaded yet';
}
return `
# š¦ Loaded Dependencies
${[...this.dependencies].map((d) => `- ${d}`).join('\n')}
Total: ${this.dependencies.size} dependencies
`;
}
showTemplates() {
return `
# š Available Templates
- **apex-class** - Apex class template
- **lwc-component** - Lightning Web Component
- **trigger** - Apex trigger template
- **test-class** - Test class template
- **flow** - Flow metadata template
- **permission-set** - Permission set template
Load templates using: *load .sf-core/templates/<template-name>
`;
}
showChecklists() {
return `
# ā
Available Checklists
- **deployment** - Pre-deployment checklist
- **code-review** - Code review checklist
- **security** - Security review checklist
- **performance** - Performance optimization checklist
- **testing** - Testing checklist
Load checklists using: *load .sf-core/checklists/<checklist-name>
`;
}
}
// Export for use in web bundles
if (typeof module !== 'undefined' && module.exports) {
module.exports = WebCommandProcessor;
}
// Also make available globally for web context
if (typeof window !== 'undefined') {
window.WebCommandProcessor = WebCommandProcessor;
}