> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blocks.team/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

## Prerequisites

* An environment with [Python 3.11](https://www.python.org/downloads/) and [Node.js 22](https://nodejs.org/en/download) installed.
* [Blocks account and API key](https://blocks.team/signup).

<Note>
  If you'd like to use Blocks with other providers such as GitLab or Bitbucket, please reach out: [dev@blocks.team](mailto:dev@blocks.team).
</Note>

<Steps>
  <Step title="Install Blocks">
    <CodeGroup>
      ```bash bash theme={null}
      pip install blocks-sdk
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize Blocks">
    <CodeGroup>
      ```bash bash theme={null}
      blocks init --key <your-api-key>
      ```
    </CodeGroup>

    We'll verify your API key and create a `.blocks` directory in the current working directory.
  </Step>

  <Step title="Create a Ralph Loop Code Automation">
    The easiest way to create an agent is to use the `create` command.

    <CodeGroup>
      ```bash bash theme={null}
      blocks create ci-ralph-loop
      ```
    </CodeGroup>

    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.

    <CodeGroup>
      ```bash ./blocks/ci-ralph-loop/main.py theme={null}
      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)
      ```
    </CodeGroup>

    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.

    <CodeGroup>
      ```bash ./blocks/ci-ralph-loop/requirements.txt theme={null}
      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
      ```

      ```json ./blocks/ci-ralph-loop/package.json theme={null}
      {
      "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"
      }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="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.

    <CodeGroup>
      ```bash bash theme={null}
      blocks push .blocks/ci-ralph-loop/main.py
      ```
    </CodeGroup>

    <Note>
      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.
    </Note>
  </Step>
</Steps>

## 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](https://blocks.team/signup).
