Unified Agent Architecture

Single Agent, Multiple Capabilities - Modular Design Analysis

Current Architecture Analysis

The portfolio currently uses separate autonomous agents, each with its own workflow file:

Agent Workflow File Trigger Capability
CIF-AA autonomous-ci-fix-agent.yml workflow_run, workflow_dispatch CI failure analysis and auto-fix
LHA link-health-agent.yml schedule, push, workflow_dispatch Link health scanning and reporting
SA security-agent.yml schedule, push, workflow_dispatch Security vulnerability scanning

Common Patterns Identified

  • All agents use similar setup steps (checkout, Node.js setup)
  • All require similar permissions (contents: write, issues: write, pull-requests: write)
  • All follow similar patterns: scan/analyze → detect → fix/report
  • All use continue-on-error for graceful failure handling
  • All create GitHub issues or PRs for reporting

Unified Agent Architecture

Concept Overview

A single unified agent that can handle multiple capabilities through modular design. The agent determines which capability to execute based on:

Unified Agent Decision Flow

Unified Agent Workflow ├── Event Detection │ ├── workflow_run (CI failures) │ ├── schedule (scheduled tasks) │ ├── push (file changes) │ └── workflow_dispatch (manual) │ ├── Capability Router │ ├── Determines which capability to run │ ├── Based on: event type, file paths, config │ └── Loads appropriate module │ └── Capability Modules (./agents/) ├── ci-fix/ │ ├── detect.sh │ ├── analyze.sh │ └── fix.sh ├── link-health/ │ ├── scan.sh │ ├── analyze.sh │ └── report.sh ├── security/ │ ├── scan.sh │ ├── analyze.sh │ └── fix.sh └── config.json (capability settings)

Benefits of Unified Architecture

Advantages

  • Single Source of Truth: One workflow file to maintain
  • Shared Infrastructure: Common setup steps defined once
  • Easier Updates: Update permissions, Node version, etc. in one place
  • Consistent Patterns: All capabilities follow same structure
  • Better Monitoring: Single workflow to monitor all agent activities
  • Simplified Debugging: Unified logging and error handling
  • Resource Efficiency: Shared dependencies and caching
  • Easier Testing: Test all capabilities through one workflow

Considerations

  • Complexity: Single workflow file becomes larger
  • Failure Isolation: One capability failure could affect others (mitigated with proper error handling)
  • Parallel Execution: Need to handle multiple capabilities running simultaneously
  • Configuration: Need clear configuration system for capability selection

Implementation Approaches

Approach 1: Folder-Based Modular Design

Each capability lives in its own folder with scripts, and the unified agent routes to the appropriate folder.

.github/ └── workflows/ └── unified-autonomous-agent.yml agents/ ├── ci-fix/ │ ├── config.json │ ├── detect.sh │ ├── analyze.sh │ └── fix.sh ├── link-health/ │ ├── config.json │ ├── scan.sh │ ├── analyze.sh │ └── report.sh ├── security/ │ ├── config.json │ ├── scan.sh │ ├── analyze.sh │ └── fix.sh └── shared/ ├── setup.sh ├── notify.sh └── utils.sh

How It Works

  1. Unified workflow detects event type and context
  2. Router determines which capability folder to use
  3. Loads capability's config.json for settings
  4. Executes capability's scripts in sequence
  5. Uses shared utilities for common operations

Approach 2: Configuration-Driven Design

Single configuration file defines all capabilities, and the agent executes based on configuration.

// agents/config.json
{
  "capabilities": {
    "ci-fix": {
      "enabled": true,
      "triggers": ["workflow_run", "workflow_dispatch"],
      "conditions": {
        "workflow_run": {
          "conclusion": "failure",
          "workflows": ["CI", "Tests", "Build"]
        }
      },
      "scripts": {
        "detect": "agents/ci-fix/detect.sh",
        "analyze": "agents/ci-fix/analyze.sh",
        "fix": "agents/ci-fix/fix.sh"
      }
    },
    "link-health": {
      "enabled": true,
      "triggers": ["schedule", "push", "workflow_dispatch"],
      "schedule": "0 9 * * 1",
      "push_paths": ["**.html", "**.md"],
      "scripts": {
        "scan": "agents/link-health/scan.sh",
        "analyze": "agents/link-health/analyze.sh",
        "report": "agents/link-health/report.sh"
      }
    }
  }
}

Approach 3: Parameter-Based Design

Manual trigger with capability parameter, or automatic detection based on event context.

on:
  workflow_dispatch:
    inputs:
      capability:
        description: 'Which capability to run'
        required: false
        type: choice
        options:
          - auto-detect
          - ci-fix
          - link-health
          - security
          - all
  workflow_run:
    workflows: ["CI", "Tests", "Build"]
    types: [completed]
  schedule:
    - cron: '0 9 * * 1'  # Link health
    - cron: '0 10 * * 1' # Security
  push:
    paths:
      - '**.html'
      - '**.md'
      - 'package.json'

Recommended Implementation

Hybrid Approach: Configuration + Folder-Based

Combines the best of both worlds: configuration for routing logic, folders for capability implementation.

Unified Agent Structure

.github/workflows/ └── unified-autonomous-agent.yml agents/ ├── config.json (capability definitions) ├── router.sh (capability selection logic) ├── shared/ │ ├── setup.sh │ ├── notify.sh │ └── utils.sh ├── capabilities/ │ ├── ci-fix/ │ │ ├── config.json │ │ ├── detect.sh │ │ ├── analyze.sh │ │ └── fix.sh │ ├── link-health/ │ │ ├── config.json │ │ ├── scan.sh │ │ ├── analyze.sh │ │ └── report.sh │ └── security/ │ ├── config.json │ ├── scan.sh │ ├── analyze.sh │ └── fix.sh

Workflow Structure

name: Unified Autonomous Agent

on:
  workflow_run:
    workflows: ["CI", "Tests", "Build"]
    types: [completed]
  schedule:
    - cron: '0 9 * * 1'   # Monday 9 AM
    - cron: '0 10 * * 1'  # Monday 10 AM
  push:
    paths:
      - '**.html'
      - '**.md'
      - 'package.json'
      - 'package-lock.json'
  workflow_dispatch:
    inputs:
      capability:
        description: 'Capability to run (auto-detect if not specified)'
        required: false
        type: choice
        options:
          - auto
          - ci-fix
          - link-health
          - security
          - all

jobs:
  unified-agent:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      security-events: write
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: |
          npm install -g linkinator jq
          # Install other shared dependencies
      
      - name: Determine capabilities to run
        id: router
        run: |
          chmod +x agents/router.sh
          ./agents/router.sh
      
      - name: Run CI Fix capability
        if: steps.router.outputs.run_ci_fix == 'true'
        run: |
          cd agents/capabilities/ci-fix
          chmod +x *.sh
          ./detect.sh && ./analyze.sh && ./fix.sh
      
      - name: Run Link Health capability
        if: steps.router.outputs.run_link_health == 'true'
        run: |
          cd agents/capabilities/link-health
          chmod +x *.sh
          ./scan.sh && ./analyze.sh && ./report.sh
      
      - name: Run Security capability
        if: steps.router.outputs.run_security == 'true'
        run: |
          cd agents/capabilities/security
          chmod +x *.sh
          ./scan.sh && ./analyze.sh && ./fix.sh

Router Implementation

The router script determines which capabilities to run based on event context:

#!/bin/bash
# agents/router.sh

EVENT_NAME="${{ github.event_name }}"
MANUAL_CAPABILITY="${{ github.event.inputs.capability }}"

# If manual trigger with specific capability
if [ "$EVENT_NAME" == "workflow_dispatch" ] && [ -n "$MANUAL_CAPABILITY" ]; then
  if [ "$MANUAL_CAPABILITY" == "all" ]; then
    echo "run_ci_fix=true" >> $GITHUB_OUTPUT
    echo "run_link_health=true" >> $GITHUB_OUTPUT
    echo "run_security=true" >> $GITHUB_OUTPUT
  else
    echo "run_${MANUAL_CAPABILITY}=true" >> $GITHUB_OUTPUT
  fi
  exit 0
fi

# Auto-detect based on event
if [ "$EVENT_NAME" == "workflow_run" ]; then
  echo "run_ci_fix=true" >> $GITHUB_OUTPUT
fi

if [ "$EVENT_NAME" == "schedule" ]; then
  HOUR=$(date +%H)
  if [ "$HOUR" == "09" ]; then
    echo "run_link_health=true" >> $GITHUB_OUTPUT
  elif [ "$HOUR" == "10" ]; then
    echo "run_security=true" >> $GITHUB_OUTPUT
  fi
fi

if [ "$EVENT_NAME" == "push" ]; then
  CHANGED_FILES="${{ github.event.head_commit.modified }}"
  
  if echo "$CHANGED_FILES" | grep -qE '\.(html|md)$'; then
    echo "run_link_health=true" >> $GITHUB_OUTPUT
  fi
  
  if echo "$CHANGED_FILES" | grep -qE '(package\.json|package-lock\.json)'; then
    echo "run_security=true" >> $GITHUB_OUTPUT
  fi
fi

Migration Strategy

Phase 1: Preparation

  1. Create agents/ folder structure
  2. Extract capability scripts from existing workflows
  3. Create shared utilities for common operations
  4. Create router.sh for capability selection

Phase 2: Implementation

  1. Create unified-autonomous-agent.yml workflow
  2. Test each capability in isolation
  3. Test capability routing logic
  4. Test parallel capability execution

Phase 3: Migration

  1. Deploy unified agent alongside existing agents
  2. Run both in parallel for validation period
  3. Compare results between old and new agents
  4. Gradually disable old agents
  5. Remove old workflow files

Phase 4: Enhancement

  1. Add new capabilities using same structure
  2. Implement capability dependencies (e.g., security scan before CI fix)
  3. Add capability orchestration (run multiple in sequence)
  4. Implement capability priority system

Comparison: Current vs Unified

Aspect Current (Separate Agents) Unified Agent
Workflow Files 3+ separate files 1 unified file
Maintenance Update each file separately Update once, affects all capabilities
Setup Steps Duplicated in each workflow Defined once, shared
Monitoring Monitor multiple workflows Single workflow to monitor
Adding Capabilities Create new workflow file Add folder + config entry
Error Isolation Complete isolation Conditional execution (if statements)
Resource Usage Separate runs per agent Single run, multiple capabilities
Complexity Simple, separate concerns More complex, unified logic

Recommendation

Recommended Approach

Implement a unified agent with folder-based modular capabilities. This provides:

Key Benefits

  • Single workflow file for easier maintenance
  • Modular capability structure for clear organization
  • Easy to add new capabilities (just add a folder)
  • Shared infrastructure reduces duplication
  • Consistent patterns across all capabilities
  • Better resource utilization

Implementation Priority

  1. High Value: Unified agent reduces maintenance overhead significantly
  2. Medium Effort: Requires refactoring but structure is clear
  3. Future-Proof: Easy to add new capabilities as portfolio grows

Next Steps

  1. Create the agents/ folder structure
  2. Extract existing agent logic into capability folders
  3. Implement router.sh for capability selection
  4. Create unified-autonomous-agent.yml
  5. Test in parallel with existing agents
  6. Migrate once validated

Example Implementation

Would you like me to create the unified agent implementation? I can:

  • Create the folder structure
  • Extract existing agent logic into capability modules
  • Implement the router script
  • Create the unified workflow file
  • Set up the configuration system

This would consolidate CIF-AA, LHA, and SA into a single unified agent while maintaining all existing functionality.