Project

looped

0.0
The project is in a healthy, maintained state
A coding agent that learns from its own performance using GEPA prompt optimization running in the background.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 2.0
~> 11.1
~> 13.0
~> 3.12
~> 6.2
~> 3.18

Runtime

~> 2.23
~> 0.31.1
~> 1.0.3
~> 1.0.2
~> 0.23
 Project Readme

Looped

A self-improving coding agent that learns from its own performance.

Gem Version Build Status

                           ┌─────────────────────────────────────┐
                           │         YOU / YOUR APP              │
                           │   "Write a fibonacci function"      │
                           └──────────────┬──────────────────────┘
                                          │
                                          ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                              LOOPED::AGENT                                   │
│  ┌────────────────────────────────────────────────────────────────────────┐  │
│  │                         ReAct Loop (Think → Act → Observe)             │  │
│  │                                                                        │  │
│  │  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐              │  │
│  │  │    THINK     │───▶│     ACT      │───▶│   OBSERVE    │──┐           │  │
│  │  │  Plan next   │    │  Use tools   │    │   Process    │  │           │  │
│  │  │    step      │    │              │    │   results    │  │           │  │
│  │  └──────────────┘    └──────────────┘    └──────────────┘  │           │  │
│  │         ▲                                                   │           │  │
│  │         └───────────────────────────────────────────────────┘           │  │
│  │                        (repeat until solved)                            │  │
│  └────────────────────────────────────────────────────────────────────────┘  │
│                                                                              │
│  Tools: read_file │ write_file │ search_code │ run_command                   │
└──────────────────────────────────────────────────────────────────────────────┘
                                          │
                                          ▼ solution
┌──────────────────────────────────────────────────────────────────────────────┐
│                              LOOPED::JUDGE                                   │
│                                                                              │
│   Evaluates: Correctness • Code Quality • Best Practices                     │
│   Returns:   Score (0-10) • Pass/Fail • Critique • Suggestions               │
└──────────────────────────────────────────────────────────────────────────────┘
                                          │
                       ┌──────────────────┴──────────────────┐
                       │                                     │
                       ▼                                     ▼
              ┌────────────────┐                    ┌────────────────────┐
              │  Return to     │                    │  Persist Result    │
              │  User/App      │                    │  to Training       │
              │  with score    │                    │  Buffer            │
              └────────────────┘                    └─────────┬──────────┘
                                                              │
┌─────────────────────────────────────────────────────────────┼────────────────┐
│                          ~/.looped/                         │                │
│                                                             ▼                │
│  instructions.json ◀──────────────────────┐    training_buffer.json         │
│  (current best prompts)                   │    (recent results)              │
│                                           │           │                      │
│  history/                                 │           │ when buffer >= 5     │
│  (archived training data)                 │           ▼                      │
│                                    ┌──────┴───────────────────────┐          │
│                                    │     LOOPED::OPTIMIZER        │          │
│                                    │     (Background Async)       │          │
│                                    │                              │          │
│                                    │  1. Build training examples  │          │
│                                    │  2. Run GEPA optimization    │          │
│                                    │  3. Extract better prompts   │          │
│                                    │  4. Hot-swap instructions    │          │
│                                    └──────────────────────────────┘          │
└──────────────────────────────────────────────────────────────────────────────┘
                                          │
                                          │ Agent detects file change
                                          │ and hot-reloads improved
                                          ▼ instructions automatically
                              ┌─────────────────────────┐
                              │  Next task benefits     │
                              │  from learned prompts   │
                              └─────────────────────────┘

Why Looped?

The Problem: LLM-based coding agents use static prompts. When they fail or produce suboptimal code, there's no mechanism to learn from those mistakes. You're stuck manually tweaking prompts.

The Solution: Looped creates a feedback loop where the agent:

  1. Attempts coding tasks using ReAct (Reasoning + Acting)
  2. Gets scored by an LLM judge on correctness, quality, and best practices
  3. Stores results as training data
  4. Automatically optimizes its own prompts using GEPA (Genetic Evolution of Prompt Attributes)
  5. Hot-swaps improved prompts without restart

The Outcome: An agent that gets measurably better at coding tasks over time, with improvements persisted across sessions.

Benefits

Benefit Description
Self-Improving Automatically learns from successes and failures—no manual prompt engineering
Measurable Progress Every solution is scored; track improvement over generations
Persistent Learning Optimized prompts saved to disk; improvements survive restarts
Zero Configuration Works out of the box; optimization runs transparently in background
Flexible Models Use different OpenAI models for agent, judge, and optimizer

Expected Outcomes

When you use Looped over time:

  1. Generation 0 (Initial): Agent uses default DSPy.rb ReAct prompts
  2. After ~5 tasks: First optimization cycle runs, prompts refined based on judge feedback
  3. After ~20 tasks: Multiple optimization generations; agent develops task-specific reasoning patterns
  4. Ongoing: Continuous improvement as more diverse tasks provide richer training signal

Check progress anytime with the status command:

looped> status
=== Optimization Status ===
Generation: 3
Best Score: 8.7/10
Training Buffer: 2/5 results
Last Updated: 2024-11-28 12:30:00

Overview

Looped is a Ruby gem that creates a coding agent capable of:

  1. Executing coding tasks using DSPy.rb ReAct with file operations, code search, and command execution
  2. Evaluating its own work with an LLM-as-judge that scores solutions
  3. Continuously improving by optimizing prompts with GEPA running in the background
  4. Persisting learning to disk (~/.looped/) for cross-session improvement

Installation

Add to your Gemfile:

gem 'looped'

Or install directly:

gem install looped

Quick Start

Interactive Mode

# Set your API key
export OPENAI_API_KEY=sk-...

# Start the interactive agent
looped
╦  ┌─┐┌─┐┌─┐┌─┐┌┬┐
║  │ ││ │├─┘├┤  ││
╩═╝└─┘└─┘┴  └─┘─┴┘

Self-improving coding agent powered by DSPy.rb + GEPA

Type a coding task and press Enter. Type 'quit' to exit.
Type 'status' to see optimization status.

looped> Write a Ruby function that calculates fibonacci numbers

=== Result ===

Score: 8.5/10

Solution:
def fibonacci(n)
  return n if n <= 1
  fibonacci(n - 1) + fibonacci(n - 2)
end

Feedback:
Score: 8.5/10
Status: PASSED
...

Single Task Mode

# Run a single task and exit
looped "Fix the syntax error in main.rb"

# With custom model
looped -m openai/gpt-4o "Refactor the User class"

# With context file
looped -c README.md "Add installation instructions"

Programmatic Usage

require 'looped'

# Single task execution
result = Looped.execute(
  task: 'Write a function that reverses a string',
  context: 'Use Ruby best practices'
)

puts result.solution    # => "def reverse_string(str)..."
puts result.score       # => 8.5
puts result.feedback    # => "Score: 8.5/10..."

# Or use the agent directly
agent = Looped::Agent.new(model: 'openai/gpt-4o')
result = agent.run(task: 'Create a binary search function')

Available Tools

The agent has access to four tools:

Tool Description
read_file Read contents of a file
write_file Write content to a file
search_code Search for patterns in code using ripgrep
run_command Execute shell commands

CLI Reference

looped [options] [task]

Options:
    -m, --model MODEL         Agent model (default: openai/gpt-4o-mini)
    -j, --judge-model MODEL   Judge model for evaluation
    -r, --reflection-model MODEL  GEPA reflection model
    -i, --max-iterations N    Max ReAct iterations (default: 10)
    -c, --context FILE        Load context from file
        --no-optimizer        Disable background optimizer
    -v, --version             Show version
    -h, --help                Show this help message

Interactive Commands:
    <task>     Execute a coding task
    status     Show optimization status
    history    Show recent task history
    help       Show help message
    quit       Exit the application

Configuration

Environment Variables

Variable Description Default
OPENAI_API_KEY OpenAI API key (required)
LOOPED_MODEL Default agent model openai/gpt-4o-mini
LOOPED_JUDGE_MODEL Default judge model openai/gpt-4o-mini
LOOPED_STORAGE_DIR Storage directory ~/.looped

Supported Models

Currently supports OpenAI models via dspy-openai:

'openai/gpt-4o'
'openai/gpt-4o-mini'
'openai/o3-mini'

How It Works

1. Task Execution

When you give Looped a task, it uses a ReAct (Reasoning + Acting) loop:

  1. Think: Analyze the task and plan approach
  2. Act: Use tools (read/write files, search, run commands)
  3. Observe: Process tool outputs
  4. Repeat until solution is found

2. Evaluation

Every solution is evaluated by an LLM judge that scores:

  • Correctness
  • Code quality
  • Best practices adherence

3. Learning

Results are stored in a training buffer. When enough results accumulate, the background optimizer:

  1. Collects training examples
  2. Runs GEPA (Genetic Evolution of Prompt Attributes) optimization
  3. Generates improved instructions
  4. Hot-swaps the agent's prompts

4. Persistence

All state is persisted to ~/.looped/:

  • instructions.json - Current optimized prompts
  • training_buffer.json - Recent results for learning
  • history/ - Archived training data

Development

# Clone the repo
git clone https://github.com/vicentereig/looped.git
cd looped

# Install dependencies
bundle install

# Run tests
bundle exec rspec

# Run with local changes
bundle exec exe/looped

Dependencies

License

MIT License - see LICENSE.txt

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b feature/my-feature)
  3. Commit your changes (git commit -am 'Add my feature')
  4. Push to the branch (git push origin feature/my-feature)
  5. Create a Pull Request