Skip to main content

Prerequisites

If you’d like to use Blocks with other providers such as GitLab or Bitbucket, please reach out: dev@blocks.team.
1

Install Blocks

pip install blocks-sdk
2

Initialize Blocks

blocks init --key <your-api-key>
We’ll verify your API key and create a .blocks directory in the current working directory.
3

Create a Ralph Loop Code Automation

The easiest way to create an agent is to use the create command.
blocks create ci-ralph-loop
This will create a new agent in the .blocks directory with the following structure:
.blocks/
    ci-ralph-loop/
        main.py
        requirements.txt
Below is an example you can copy to get started. It runs a “Ralph” loop on every pull request: a coding agent watches a CI workflow, and if it’s failing, it diagnoses the root cause, makes the smallest fix on a dedicated branch, and keeps iterating until CI is green.
import os
import sys
from blocks_control_sdk.constants.openai import OpenAIModels, OpenAIAuthenticationMode
from blocks_control_sdk.constants.core import WORKSPACE_DIR
from blocks import on, task
from blocks_control_sdk import Codex, CodexAgentConfig

WORKFLOW_NAME = "Unit Test"   # CI workflow we want to get green
MAX_ITERATIONS = 5


def done(response):
return "<BLOCKS_EXIT>" in response


@on("github.pull_request")
@task(name="ci-ralph-loop")
def ci_ralph_loop(input):
owner, repo = input["owner"], input["repo"]
branch_name = input["ref"]
pr_number = (input.get("pull_request") or {}).get("number")

# Avoid recursion: skip if we're already on our own fix branch
if not branch_name or branch_name.endswith("-ralphci"):
    print("Loop already running, exiting.")
    return

fix_branch = f"{branch_name}-ralphci"
memory = WORKSPACE_DIR.absolute() / "MEMORY.md"
os.chdir(WORKSPACE_DIR.absolute())

# Spin up the coding agent
agent = Codex()
agent.init(CodexAgentConfig(
    model=OpenAIModels.gpt_5_3_codex,
    authentication_mode=OpenAIAuthenticationMode.oauth,
))

context = f"PR #{pr_number} on {owner}/{repo}, branch '{branch_name}', fix branch '{fix_branch}'."

def check_prompt(branch):
    return f"""{context}
Wait for the "{WORKFLOW_NAME}" CI workflow on branch "{branch}" to finish.
- If it passes (or doesn't exist), reply with <BLOCKS_EXIT>.
- If it fails, summarize which tests failed."""

fix_prompt = f"""{context}
The "{WORKFLOW_NAME}" workflow is failing. You run in a loop with fresh context
each time, so {memory} is your only record of past attempts.

1. Read {memory}; don't retry anything already marked as failed there.
2. Find the root cause. If it's transient infra (not a code bug), note it in
{memory} and reply with <BLOCKS_EXIT>.
3. Otherwise make the smallest fix and append an attempt note to {memory}.
4. Commit only the fix to '{fix_branch}' (create + open a PR if needed), push it."""

branch = branch_name
for i in range(MAX_ITERATIONS):
    print(f"--- Iteration {i}: checking {branch} ---")
    # Fresh Context window
    agent.new_chat_thread(new_session=True)
    if done(status := agent.query_sync_beta(check_prompt(branch))):
        print("CI is green. Done.")
        return
    print(status)

    print(f"--- Iteration {i}: fixing -> {fix_branch} ---")
    # Fresh Context window
    agent.new_chat_thread(new_session=True)
    if done(agent.query_sync_beta(fix_prompt)):
        print("Failure not actionable (transient). Exiting.")
        return

    branch = fix_branch  # now watch CI on the fix branch

print(f"Exhausted {MAX_ITERATIONS} attempts.")
sys.exit(1)
Declare your Python dependencies in a requirements.txt and any MCP servers or CLI tools in a package.json alongside main.py. Adding these files automatically installs the dependencies when the agent image is built.
blocks-control-sdk>=0.2.2,<0.3.0
blocks-sdk>=0.1.81,<0.2.0
requests
litellm>=1.61.16,<=1.74.8
slack-sdk>=3.19.2
fastmcp
tomlkit>=0.13.3,<1.0.0
openai<=1.99.9
jinja2>=3.1.0
{
"dependencies": {
    "@upstash/context7-mcp": "^1.0.16",
    "firecrawl-mcp": "^2.0.2",
    "mcp-remote": "^0.1.29",
    "@modelcontextprotocol/server-slack": "2025.4.25",
    "@playwright/mcp": "^0.0.36",
    "@tacticlaunch/mcp-linear": "^1.0.11",
    "playwright": "^1.55.0",
    "@anthropic-ai/claude-code": "2.1.117",
    "@openai/codex": "0.135.0"
}
}
4

Register an agent

Agents are registered with the push command; specify the filename relative to your current working directory. All agents defined the file will be registered, however you can only register one file at a time.
blocks push .blocks/ci-ralph-loop/main.py
Image builds may take up to 10 minutes. They only happen once — subsequent pushes reuse the cached image unless your npm or pip dependencies change.

Project Structure

The .blocks directory is where agent source code is defined. A typical project structure looks like the following:
.blocks/
    agent-1/
        main.py
        requirements.txt
    agent-2/
        main.py
        requirements.txt
    agent-3.py
Dependencies are isolated to each agent, and there are no restrictions for supported pip packages.

Version Control

Ideally, your agents will be checked into some git provider for version control and storage, just like any other source code. We do preserve the state of registered agents, but do not implement git for version control. However, this is something we can add if requested.

Where do I get an API key?

API keys are created and managed in the dashboard.