Skip to content

Building Autonomous AI Agents on GitHub 🤖

Published: February 3, 2025

What if your GitHub repository could think, act, and evolve on its own? Welcome to the world of autonomous AI agents that live inside GitHub Actions.

The Vision

graph TB
    subgraph "GitHub Events"
        I[Issue Opened]
        PR[PR Created]
        C[Comment Added]
        S[Schedule/Cron]
    end

    subgraph "Agent Brain"
        A[Strands-Coder Agent]
        KB[Knowledge Base]
        P[Project Board]
    end

    subgraph "Actions"
        Code[Write Code]
        Review[Review PRs]
        Comment[Comment]
        Create[Create Issues/PRs]
    end

    I --> A
    PR --> A
    C --> A
    S --> A
    A <--> KB
    A <--> P
    A --> Code
    A --> Review
    A --> Comment
    A --> Create

    style A fill:#f9f,stroke:#333,stroke-width:4px

What Makes This Revolutionary

  • 🔄 Event-Driven: Responds to issues, PRs, comments, discussions
  • ⏰ Scheduled: Runs autonomously on cron schedules
  • 🧠 Memory: Knowledge base for continuous learning
  • 📊 Project Tracking: Self-manages work via GitHub Projects

How It Works

1. The GitHub Action

name: Agent
on:
  issues:
    types: [opened, edited, closed]
  issue_comment:
    types: [created, edited]
  pull_request:
    types: [opened, closed, edited]
  schedule:
    - cron: '0 */4 * * *'  # Every 4 hours
  workflow_dispatch:
    inputs:
      prompt:
        description: 'Task for agent'
        required: false

The agent triggers on any GitHub event - issues, PRs, comments, discussions, and scheduled runs.

2. Rich Context Injection

sequenceDiagram
    participant GH as GitHub Event
    participant CTX as Context Builder
    participant KB as Knowledge Base
    participant Agent as Agent
    participant Action as Action

    GH->>CTX: Raw Event JSON
    CTX->>CTX: Parse Event Type
    CTX->>CTX: Fetch Full Thread (GraphQL)
    CTX->>CTX: Fetch Project State
    KB->>CTX: Retrieve Related Context
    CTX->>Agent: Rich System Prompt
    Agent->>Agent: Reason & Decide
    Agent->>Action: Execute
    Action->>KB: Store Learning

The magic is in context.py - it transforms raw GitHub events into rich, actionable context:

def fetch_github_event_context() -> str:
    """Fetch rich GitHub event context based on the triggering event."""
    # Issue events → Full issue thread with comments
    # PR events → Reviews, comments, linked issues
    # Discussion events → Thread and replies

3. Self-Awareness

The agent injects its own source code into the system prompt:

def get_own_source_code() -> str:
    """Read own source code for self-awareness."""
    key_files = [
        ("agent_runner.py", "Main agent runner"),
        ("context.py", "Context building"),
    ]
    # ... inject into system prompt

Why Self-Awareness Matters

When an agent understands its own implementation, it can:

  • Debug its own behavior
  • Propose improvements to itself
  • Answer questions about its capabilities accurately

The Control Loop Pattern

stateDiagram-v2
    [*] --> Idle
    Idle --> CheckSchedule: Hourly Cron
    CheckSchedule --> DispatchJob: Job Due
    CheckSchedule --> Idle: No Jobs Due
    DispatchJob --> AgentRun
    AgentRun --> UpdateTimestamp
    UpdateTimestamp --> Idle

    Idle --> AgentRun: GitHub Event
    AgentRun --> StoreKB: Complete
    StoreKB --> UpdatePrompt: Learning
    UpdatePrompt --> Idle

Two-tier scheduling system:

  1. agent.yml: Event-driven + fixed schedule (every 4 hours)
  2. control.yml: Hourly control loop checking AGENT_SCHEDULES variable

This enables dynamic scheduling via the scheduler tool:

# Add a daily code review job
scheduler(
    action="add",
    job_id="daily_review",
    cron="0 9 * * *",
    prompt="Review open PRs and provide feedback"
)

Memory Architecture

flowchart LR
    subgraph "Before Execution"
        R[retrieve] --> CTX[Context]
    end

    subgraph "Execution"
        CTX --> Agent
        Agent --> Actions
    end

    subgraph "After Execution"
        Actions --> Store[store_in_kb]
        Actions --> Prompt[system_prompt add_context]
    end

    Store --> KB[(Knowledge Base)]
    Prompt --> Repo[(GitHub Variable)]

    KB --> R
    Repo --> CTX

    style KB fill:#bbf,stroke:#333
    style Repo fill:#bfb,stroke:#333

Continuous Learning Loop:

  1. Before: retrieve() - Load context from KB
  2. During: Execute with full context
  3. After:
  4. store_in_kb() - Save execution summary
  5. system_prompt(action="add_context") - Update if learned something

Sub-Agent Delegation

graph TD
    Main[Main Agent] --> Sub1[Sub-Agent: Code Review]
    Main --> Sub2[Sub-Agent: Documentation]
    Main --> Sub3[Sub-Agent: Issue Triage]

    Sub1 --> |Dispatch| WF1[workflow_dispatch]
    Sub2 --> |Dispatch| WF2[workflow_dispatch]
    Sub3 --> |Dispatch| WF3[workflow_dispatch]

    WF1 --> Run1[GitHub Actions Run]
    WF2 --> Run2[GitHub Actions Run]
    WF3 --> Run3[GitHub Actions Run]

    style Main fill:#f9f,stroke:#333,stroke-width:4px

The create_subagent tool spawns child agents with different: - Models: Opus for complex reasoning, Sonnet for fast tasks - Tools: Task-specific tool configurations - System prompts: Role-specific instructions

create_subagent(
    repository="owner/repo",
    workflow_id="agent.yml",
    prompt="Review PR #42 for security issues",
    model="us.anthropic.claude-opus-4-20250514-v1:0",
    tools="strands_tools:shell;strands_coder:use_github"
)

Security Model

flowchart TD
    Event[GitHub Event] --> Auth{User Authorized?}
    Auth -->|Yes| Run[Run Agent]
    Auth -->|No| Block[❌ Block + Log]

    Run --> Token{Token Selection}
    Token -->|Own Repos| GH[GITHUB_TOKEN]
    Token -->|Upstream| PAT[PAT_TOKEN]

    GH -->|No Cascade| Safe[Safe Execution]
    PAT -->|May Trigger| Cascade[Workflow Cascade]

Token Strategy

  • GITHUB_TOKEN: Own repos - won't trigger recursive workflows
  • PAT_TOKEN: Upstream repos - needed for write access, may trigger cascades

Authorization is controlled via AUTHORIZED_USERS secret:

AUTHORIZED_USERS="user1,user2,github-actions[bot]"

Real-World System Prompt

The SYSTEM_PROMPT.md is the agent's "soul" - defining:

  • Mission: Be a high-quality contributor
  • Anti-patterns: What to NEVER do (noise, untested code, duplicates)
  • Quality patterns: What to ALWAYS do (test first, one PR per issue)
  • Tools usage: How to use each tool correctly
  • Learning protocol: Memory query and storage patterns

Get Started

# 1. Fork strands-coder
gh repo fork cagataycali/strands-coder

# 2. Set secrets
gh secret set PAT_TOKEN --body "your-pat"
gh secret set AUTHORIZED_USERS --body "your-username"

# 3. Set variables
gh variable set SYSTEM_PROMPT --body "Your agent instructions"

# 4. Trigger manually
gh workflow run agent.yml -f prompt="Hello, agent!"

The future of software development isn't just AI-assisted—it's AI-autonomous. 🤖