DEV Community

Cover image for How We Built an Autonomous AI Agent That Audited 187 Subprojects and Got PRs Merged by Google Cloud Engineers
Morad Moqbel
Morad Moqbel

Posted on

How We Built an Autonomous AI Agent That Audited 187 Subprojects and Got PRs Merged by Google Cloud Engineers

Every developer building with AI frameworks in 2026 knows the pain: fast-moving dependencies break existing code constantly.

A library releases v0.2, changes an import path, deprecates a decorator, or alters a dictionary response into an object. Suddenly, your production app throws NameError, ImportError, or silent runtime failures.

We got tired of spending hours hunting through changelogs to fix broken API signatures. So we built ApiPatch — an autonomous AI agent engineered specifically to detect and repair deprecated API calls across codebases, verify them against syntax and AST integrity shields, and automatically generate clean, partitioned pull requests.

To put ApiPatch to the ultimate test, we pointed it at one of the largest and most popular GenAI repositories on GitHub: Shubhamsaboo/awesome-llm-apps (15,000+ stars), containing over 180 independent LLM subprojects.

Here is the story of how ApiPatch audited the monorepo, generated automated fixes, and got its first Pull Request merged by a Google Cloud AI engineer.


The Problem: The Modern Dependency Churn

Frameworks like CrewAI, LangChain, FastAPI, and Google GenAI SDK are evolving at breakneck speed:

  • FastAPI deprecated @app.on_event("startup") in favor of asynchronous lifespan context managers.
  • Google deprecated google.generativeai in favor of the new unified google-genai SDK, changing function signatures from content= to contents= and returning vector objects rather than raw dictionaries.
  • LLM routers moved from legacy configuration keys to updated provider schemas.

In a monorepo with 180+ standalone tutorials, keeping every subproject up-to-date manually is nearly impossible.


Enter ApiPatch: How It Works

ApiPatch is not a generic code re-writer. It combines deterministic AST analysis with targeted LLM reasoning:

  1. Monorepo Discovery: Scans project trees, automatically detecting subproject roots (directories with their own requirements.txt or pyproject.toml).
  2. Proactive Audit: Analyzes call sites against known deprecation patterns across major frameworks.
  3. AST Integrity & Syntax Shield: Before proposing any change, ApiPatch compiles the modified code through AST validation and checks for import ordering and syntax regressions.
  4. Isolated Branching & PR Generation: Automatically partitions fixes into dedicated Git branches and opens surgical Pull Requests on GitHub.

The Real-World Test: Merged PRs on awesome-llm-apps

We ran ApiPatch on awesome-llm-apps using subproject-level isolation. Here are the patches it generated:

1. Modernizing RouteLLM Config (PR #1148 — MERGED 🎉)

Migrated legacy controller configurations to modern RouteLLM API parameters. Verified clean runtime execution and was promptly merged by maintainer @Shubhamsaboo:

- controller = Controller(config="legacy_router.yaml")
+ controller = Controller(model_pair="gpt-4o:claude-4-5-sonnet")
Enter fullscreen mode Exit fullscreen mode

2. FastAPI Startup to Modern Lifespan (PR #1149)

Replaced the deprecated startup event with FastAPI's official asynccontextmanager pattern, ensuring clean app initialization:

- @app.on_event("startup")
- def startup_event():
-     initialize_indexes()

+ @asynccontextmanager
+ async def lifespan(app: FastAPI):
+     initialize_indexes()
+     yield
+
+ app = FastAPI(lifespan=lifespan)
Enter fullscreen mode Exit fullscreen mode

3. Google Generative AI to Unified google-genai SDK (PR #1150)

Upgraded legacy google.generativeai embed calls to the new google-genai types and response structures:

- response = genai.embed_content(model="models/embedding-001", content=text)
- return response['embedding']
+ response = client.models.embed_content(
+     model="text-embedding-004",
+     contents=text,
+     config=types.EmbedContentConfig(task_type="RETRIEVAL_DOCUMENT")
+ )
+ return response.embeddings[0].values
Enter fullscreen mode Exit fullscreen mode

Key Lessons from Open-Source Code Audits

  1. Import Order Matters: When refactoring decorators (like FastAPI lifespan), the instance creation app = FastAPI(...) must precede any route definitions (@app.get), or Python will fail at import time with NameError.
  2. Synchronize Dependencies: Upgrading an SDK in code without updating requirements.txt breaks clean container environments. ApiPatch now aligns requirements files alongside code diffs.
  3. Maintainer Etiquette: Large repos hate 50-file mega-PRs. Grouping fixes per subproject with clear explanations is what earns maintainer respect.

Try ApiPatch in Your CI/CD or CLI

ApiPatch is open-source and available both on PyPI and as an official GitHub Action on the GitHub Marketplace:

1. Run it locally:

pip install apipatch
apipatch run . --mode fix
Enter fullscreen mode Exit fullscreen mode

2. Add it to your GitHub Actions:

name: ApiPatch Auto-Migration
on: [push, pull_request]

jobs:
  modernize:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: MoradMoqbel/apipatch@v0.9.0
        with:
          mode: 'fix'
          api_key: ${{ secrets.GEMINI_API_KEY }}
          auto_pr: 'true'
Enter fullscreen mode Exit fullscreen mode

Resources & Links

Have you encountered breaking API changes in your stack recently? Let us know in the comments below!

Top comments (0)