Skip to main content

AI Agent v2.0 - Integration Summary

Swarm ID: swarm_1764655531178_udtox74dx Architecture Phase: Complete Date: 2025-12-01


Integration Strategy Overview

The AI Agent v2.0 architecture follows a layered plugin architecture with clear separation between:

  • Orchestration Layer (coordination, planning, approval)
  • Intelligence Layer (RuVector, site context, memory)
  • Foundation Layer (LangChain, file operations, storage)

Key Integration Points

1. TaskPlanner ↔ SiteContext

Integration Pattern: Dependency Injection

// In main agent initialization
const siteContext = new SiteContext({ sitePath: CONFIG.sitePath });
await siteContext.initialize();

const taskPlanner = new TaskPlanner({
  siteContext: siteContext,
  patterns: INTENT_PATTERNS
});

// During planning
const intent = await taskPlanner.parseIntent(userMessage);
const plan = await taskPlanner.planActions(intent, siteContext);

Data Flow:

User Input → TaskPlanner.parseIntent()
                ↓
         Extract entities
                ↓
         SiteContext.getContentSchema()  ← Validate against schema
                ↓
         SiteContext.getSuggestions()     ← Get default values
                ↓
         TaskPlanner.planActions()
                ↓
         ActionPlan (enriched)

Benefits:

  • TaskPlanner knows site structure and schemas
  • Actions are pre-validated against schemas
  • Suggestions improve user experience

2. TaskPlanner ↔ RuVectorBridge

Integration Pattern: Service Injection

// Initialize RuVector bridge
const ruvectorBridge = new RuVectorBridge({
  indexUrl: '/assets/indices/projects-index.json',
  graphUrl: '/assets/indices/knowledge-graph.json'
});
await ruvectorBridge.initialize();

// Inject into TaskPlanner
taskPlanner.ruvectorBridge = ruvectorBridge;

// During entity extraction
async _extractTechnologies(message, intent) {
  // Extract from message
  const mentioned = this._extractKeywords(message);

  // Enrich with related technologies from graph
  if (this.ruvectorBridge) {
    const related = await this.ruvectorBridge.findRelated(
      mentioned[0],
      'technology'
    );
    return [...mentioned, ...related.map(r => r.name)];
  }

  return mentioned;
}

Data Flow:

User: "Add React project about e-commerce"
         ↓
TaskPlanner extracts: ["React"]
         ↓
RuVectorBridge.findRelated("React", "technology")
         ↓
Graph returns: ["React", "Node.js", "Redux", "Webpack"]
         ↓
TaskPlanner suggests: "Node.js" as backend
         ↓
Final technologies: ["React", "Node.js"]

Benefits:

  • Intelligent technology suggestions
  • Project recommendations from similar projects
  • Graph-based context enrichment

3. ChangePreview ↔ ApprovalWorkflow

Integration Pattern: Pipeline

// ApprovalWorkflow orchestrates the preview → approval flow
async requestApproval(plan) {
  // 1. Generate preview
  const preview = await this.changePreview.previewPlan(plan);

  // 2. Display to user
  console.log(preview.formattedOutput);

  // 3. Prompt for approval
  const response = await this._promptUser();

  // 4. Handle response
  if (response.decision === 'approve') {
    return { approved: true, plan };
  } else if (response.decision === 'modify') {
    const modified = await this.handleModification(plan, response.input);
    return this.requestApproval(modified); // Recursive
  } else {
    return { approved: false, reason: response.reason };
  }
}

Data Flow:

ActionPlan
    ↓
ChangePreview.previewPlan(plan)
    ↓
For each action:
  - Generate file diffs
  - Format YAML changes
  - Estimate impact
    ↓
Preview {formattedOutput}
    ↓
ApprovalWorkflow displays preview
    ↓
User decision [Y/n/modify]
    ↓
If approved → Execute
If rejected → Abort
If modify  → Re-plan → Recursive approval

Benefits:

  • User sees exactly what will change
  • Interactive modification without starting over
  • Safe execution gated by explicit approval

4. Memory ↔ All Modules

Integration Pattern: Singleton Service

// Global memory instance (existing pattern)
const memory = new AgentMemory({
  storagePath: './memory/vectors.json',
  maxEntries: 1000,
  maxBufferSize: 20
});

// All modules can access memory
// Example: TaskPlanner storing planning decisions
await memory.storeContext('last_project_category', category, 0.7);

// Example: RuVectorBridge recalling past searches
const pastSearches = await memory.recall('similar project searches', {
  type: 'action',
  k: 3
});

// Example: ApprovalWorkflow storing execution results
await memory.storeAction('execute_plan', [plan.id], 'Success');

Memory Types:

  • conversation: User messages and agent responses
  • action: Executed actions (file edits, commands)
  • context: Decisions, preferences, site structure

Benefits:

  • Persistent learning across sessions
  • Context-aware planning
  • Audit trail for debugging

5. LangChain Agent ↔ v2.0 Modules

Integration Pattern: Adapter Wrapper

// Wrap LangChain agent with v2.0 orchestration
class AgentV2 {
  constructor(options) {
    // LangChain agent (existing)
    this.langchainAgent = createReactAgent({
      llm: new ChatAnthropic({ model: 'claude-3-5-sonnet-20241022' }),
      tools: this._createTools()
    });

    // v2.0 modules
    this.taskPlanner = new TaskPlanner(options);
    this.changePreview = new ChangePreview(options);
    this.approvalWorkflow = new ApprovalWorkflow(options);
    this.siteContext = new SiteContext(options);
    this.ruvectorBridge = new RuVectorBridge(options);
    this.memory = new AgentMemory(options);
  }

  async processMessage(message) {
    // 1. Parse intent with TaskPlanner
    const intent = await this.taskPlanner.parseIntent(message);

    // 2. Generate action plan
    const plan = await this.taskPlanner.planActions(intent, this.siteContext);

    // 3. Generate preview
    const preview = await this.changePreview.previewPlan(plan);

    // 4. Request approval
    const approval = await this.approvalWorkflow.requestApproval(plan);

    // 5. Execute if approved
    if (approval.approved) {
      const result = await this.approvalWorkflow.executePlan(approval.plan);
      return this.approvalWorkflow.formatReport(result);
    } else {
      return `Plan rejected: ${approval.reason}`;
    }
  }

  // Backward compatibility: direct tool access
  async _executeWithLangChain(message) {
    // Falls back to LangChain ReAct for simple queries
    const result = await this.langchainAgent.invoke({
      messages: [{ role: 'user', content: message }]
    });
    return result.messages[result.messages.length - 1].content;
  }
}

Migration Path:

v1.0 (LangChain only)
    ↓
v1.5 (v2 modules + LangChain fallback)
    ↓
v2.0 (v2 modules primary, LangChain for tool execution only)

Benefits:

  • Backward compatible with v1.0
  • Gradual migration path
  • Can fallback to LangChain for edge cases

Module Interaction Matrix

Module TaskPlanner ChangePreview RuVectorBridge SiteContext ApprovalWorkflow Memory
TaskPlanner - ✓ (generates plans for preview) ✓ (enriches entities) ✓ (validates against schemas) ✓ (provides plans) ✓ (stores decisions)
ChangePreview ✓ (receives plans) - ✓ (provides previews)
RuVectorBridge ✓ (provides context) - ✓ (recalls past searches)
SiteContext ✓ (provides schemas) - ✓ (stores site structure)
ApprovalWorkflow ✓ (receives plans) ✓ (uses previews) - ✓ (stores executions)
Memory ✓ (recalls context) ✓ (recalls searches) ✓ (recalls structure) ✓ (recalls results) -

Legend:

  • ✓ = Direct dependency
  • ✗ = No dependency

Configuration Management

Centralized Config

// config.js
export const CONFIG = {
  // API Keys
  anthropic: {
    apiKey: process.env.ANTHROPIC_API_KEY,
    model: process.env.ANTHROPIC_MODEL || 'claude-3-5-sonnet-20241022',
    temperature: parseFloat(process.env.ANTHROPIC_TEMPERATURE || '0.7')
  },

  // Site
  site: {
    path: process.env.SITE_PATH || process.cwd(),
    jekyllConfig: '_config.yml',
    projectsDir: '_projects',
    dataDir: '_data'
  },

  // Memory
  memory: {
    storagePath: process.env.MEMORY_PATH || './memory/vectors.json',
    maxEntries: parseInt(process.env.MEMORY_MAX_ENTRIES || '1000'),
    maxBufferSize: parseInt(process.env.MEMORY_BUFFER_SIZE || '20')
  },

  // RuVector
  ruvector: {
    enabled: process.env.ENABLE_RUVECTOR !== 'false',
    indexUrl: '/assets/indices/projects-index.json',
    graphUrl: '/assets/indices/knowledge-graph.json',
    fallbackMode: true
  },

  // Preview
  preview: {
    contextLines: parseInt(process.env.PREVIEW_CONTEXT_LINES || '3'),
    maxPreviewLines: parseInt(process.env.PREVIEW_MAX_LINES || '500'),
    colorize: process.env.NO_COLOR !== 'true'
  },

  // Approval
  approval: {
    required: process.env.REQUIRE_APPROVAL !== 'false',
    timeout: parseInt(process.env.APPROVAL_TIMEOUT || '300000') // 5 minutes
  }
};

Environment Variables (.env)

# Required
ANTHROPIC_API_KEY=sk-ant-...

# Optional (with defaults)
ANTHROPIC_MODEL=claude-3-5-sonnet-20241022
ANTHROPIC_TEMPERATURE=0.7
SITE_PATH=/path/to/site
ENABLE_RUVECTOR=true
REQUIRE_APPROVAL=true
PREVIEW_CONTEXT_LINES=3
PREVIEW_MAX_LINES=500
MEMORY_MAX_ENTRIES=1000

Error Handling Strategy

Error Categories

  1. User Input Errors
    • Invalid intent (confidence < 0.5)
    • Missing required entities
    • Schema validation failures

    Handling: Prompt user for clarification

  2. System Errors
    • File read/write failures
    • RuVector initialization failures
    • Memory storage failures

    Handling: Graceful degradation with fallback

  3. Execution Errors
    • Action execution failures
    • Partial execution (some actions fail)

    Handling: Rollback + detailed error report

Error Flow

Error Occurs
    ↓
Categorize (user / system / execution)
    ↓
User Error → Prompt for clarification
System Error → Try fallback → Log error → Continue
Execution Error → Rollback → Report to user
    ↓
Store error in memory for learning

Example Error Handlers

// In TaskPlanner
try {
  const intent = await this.parseIntent(message);
} catch (error) {
  if (error.code === 'LOW_CONFIDENCE') {
    return {
      type: 'CLARIFICATION_NEEDED',
      message: 'I\'m not sure what you want to do. Could you rephrase?',
      suggestions: ['Add project', 'Update content', 'Search projects']
    };
  }
  throw error;
}

// In RuVectorBridge
try {
  await this.searchEngine.initialize();
} catch (error) {
  console.warn('[RuVector] Initialization failed, using fallback:', error);
  this._initializeFallback();
  // Continue without RuVector
}

// In ApprovalWorkflow
try {
  await this.executePlan(plan);
} catch (error) {
  console.error('[Execution] Failed:', error);
  await this.rollback(plan);
  return {
    success: false,
    error: error.message,
    rollbackStatus: 'complete'
  };
}

Testing Integration

Integration Test Example

// tests/integration/full-workflow.test.js
describe('Full Workflow Integration', () => {
  let agent;

  before(async () => {
    // Initialize agent with test config
    agent = new AgentV2({
      sitePath: './tests/fixtures/sample-site',
      memory: new AgentMemory({ storagePath: ':memory:' }),
      ruvector: { enabled: false } // Use fallback for tests
    });

    await agent.initialize();
  });

  it('should complete ADD_PROJECT workflow', async () => {
    // Mock user input
    const message = 'Add a React project about e-commerce';

    // 1. Parse intent
    const intent = await agent.taskPlanner.parseIntent(message);
    expect(intent.type).to.equal('ADD_PROJECT');

    // 2. Generate plan
    const plan = await agent.taskPlanner.planActions(
      intent,
      agent.siteContext
    );
    expect(plan.actions).to.have.lengthOf(2); // EDIT_YAML + CREATE_FILE

    // 3. Preview
    const preview = await agent.changePreview.previewPlan(plan);
    expect(preview.summary.filesModified).to.equal(1);
    expect(preview.summary.filesCreated).to.equal(1);

    // 4. Auto-approve for test
    const approval = { approved: true, plan };

    // 5. Execute
    const result = await agent.approvalWorkflow.executePlan(approval.plan);
    expect(result.success).to.be.true;

    // 6. Verify files
    const projectYaml = yaml.load(
      fs.readFileSync('tests/fixtures/sample-site/_data/projects.yml', 'utf-8')
    );
    const newProject = projectYaml.projects.find(
      p => p.name === intent.entities.projectName
    );
    expect(newProject).to.exist;
  });
});

Performance Considerations

Async Operations

All I/O operations are async to avoid blocking:

  • File reads/writes
  • RuVector searches
  • Memory queries
  • LLM API calls

Caching Strategy

Cache Locations:

  1. SiteContext: Cache site structure analysis (invalidate on file changes)
  2. RuVectorBridge: Cache search results (TTL: 5 minutes)
  3. Memory: In-memory buffer for recent conversations (20 entries)

Example:

// In SiteContext
async analyzeSite() {
  if (this._cachedStructure && !this._isStale()) {
    return this._cachedStructure;
  }

  this._cachedStructure = await this._performAnalysis();
  this._cacheTimestamp = Date.now();
  return this._cachedStructure;
}

_isStale() {
  const TTL = 10 * 60 * 1000; // 10 minutes
  return (Date.now() - this._cacheTimestamp) > TTL;
}

Performance Targets

Operation Target Notes
Intent parsing <500ms Mostly regex, fast
Plan generation <1s Includes site context
RuVector search <300ms WASM-accelerated
Preview generation <2s Diff computation
Total workflow <5s Excluding user approval time

Security Considerations

Input Validation

All user inputs are sanitized:

// Prevent directory traversal
function sanitizeFilepath(filepath) {
  const normalized = path.normalize(filepath);
  if (normalized.includes('..')) {
    throw new Error('Invalid filepath: directory traversal detected');
  }
  return normalized;
}

// Command whitelist
const SAFE_COMMANDS = ['git', 'jekyll', 'bundle', 'ls', 'pwd'];
function validateCommand(command) {
  const cmd = command.split(' ')[0];
  if (!SAFE_COMMANDS.includes(cmd)) {
    throw new Error(`Unsafe command: ${cmd}`);
  }
}

API Key Protection

Never log or expose API keys:

// In logger
function sanitizeLog(message) {
  return message
    .replace(/sk-ant-[a-zA-Z0-9-]+/g, '***')
    .replace(/ANTHROPIC_API_KEY=[^\s]+/g, 'ANTHROPIC_API_KEY=***');
}

File Operation Safety

All file writes are atomic:

// Use temp file + rename for atomicity
async function safeWriteFile(filepath, content) {
  const tempPath = `${filepath}.tmp`;
  await fs.writeFile(tempPath, content, 'utf-8');
  await fs.rename(tempPath, filepath);
}

Deployment Checklist

Pre-Deployment

  • All modules have 90%+ test coverage
  • Integration tests pass
  • Performance benchmarks meet targets
  • Security audit complete
  • Documentation complete (API, Architecture, Migration)
  • Example scripts tested

Deployment Steps

  1. Backup existing installation
    cp -r ai-agent-simple ai-agent-simple.backup
    
  2. Install v2.0
    cd ai-agent-simple
    git fetch origin v2.0
    git checkout v2.0
    npm install
    
  3. Run migration script
    npm run migrate
    
  4. Test installation
    npm test
    node ai-agent.js "List projects" # Should work without approval
    
  5. Gradual rollout
    • Week 1: Internal testing
    • Week 2: Beta users (5-10 users)
    • Week 3: General availability

Post-Deployment

  • Monitor error rates
  • Collect user feedback
  • Track performance metrics
  • Update documentation based on real usage

Summary

The AI Agent v2.0 architecture provides:

Safety: Mandatory preview + approval before execution ✅ Intelligence: RuVector integration for context-aware planning ✅ Maintainability: Modular design with clear interfaces ✅ Extensibility: Plugin architecture for custom intent handlers ✅ Performance: Async operations, caching, <5s workflows ✅ Reliability: Graceful degradation, rollback capability ✅ Backward Compatibility: Can fallback to v1.0 LangChain agent

Next Phase: Implementation (Coder agents)


Architecture Status: ✅ Complete Review Status: Pending Implementation Status: Not started