Skip to content

Team-Atlanta/crs-gemini-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

crs-gemini-cli

A CRS (Cyber Reasoning System) that uses Gemini CLI to autonomously find and patch vulnerabilities in open-source projects.

Given any boot-time subset of vulnerability evidence (POVs, bug-candidate reports, diff files, and/or seeds), the agent analyzes the inputs, edits source code, builds, tests, iterates, and writes one final patch for submission.

How it works

┌─────────────────────────────────────────────────────────────────────┐
│ patcher.py (orchestrator)                                           │
│                                                                     │
│  1. Fetch startup inputs & source                                    │
│     crs.fetch(POV/BUG_CANDIDATE/DIFF/SEED)                           │
│     crs.download(src)                                                │
│         │                                                            │
│         ▼                                                            │
│  2. Launch Gemini CLI agent with fetched paths + GEMINI.md           │
│     gemini -m <model> --approval-mode yolo -d -p <prompt>           │
└─────────┬───────────────────────────────────────────────────────────┘
          │ -d: prompt with startup evidence paths
          ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Gemini CLI (autonomous agent)                                       │
│                                                                     │
│  ┌──────────┐    ┌──────────┐    ┌──────────────┐                   │
│  │ Analyze  │───▶│   Fix    │───▶│   Verify     │                   │
│  │          │    │          │    │              │                   │
│  │ Read     │    │ Edit src │    │ apply-patch  │──▶ Builder        │
│  │ startup  │    │ git diff │    │   -build     │    sidecar        │
│  │ evidence │    │          │    │              │◀── rebuild_id     │
│  │          │    │          │    │              │                   │
│  └──────────┘    └──────────┘    │ run-pov ────│──▶ Runner         │
│                                  │   (all POVs)│◀── retcode        │
│                       ▲          │ apply-patch │──▶ Builder        │
│                       │          │   -test     │◀── retcode        │
│                       │          └──────┬───────┘                   │
│                       │                 │                           │
│                       └── retry ◀── fail?                           │
│                                         │ pass                      │
│                                         ▼                           │
│                              Write .diff to /patches/               │
└─────────────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────┐
│ patcher.py               │
│ submit(first patch) ───▶ oss-crs framework
└─────────────────────────┘
  1. run_patcher fetches available startup inputs (POV, BUG_CANDIDATE, DIFF, SEED) once, downloads source, and passes the fetched paths to the agent.
  2. The evidence is handed to Gemini CLI in a single session with generated GEMINI.md instructions. No additional inputs are fetched after startup.
  3. The agent autonomously analyzes evidence, edits source, and uses libCRS tools (apply-patch-build, run-pov, apply-patch-test) to iterate as needed through the builder sidecar.
  4. When the first final .diff is written to /patches/, the patcher submits that single file with crs.submit(DataType.PATCH, patch_path) and exits. Later patch files or modifications are ignored.

The agent is language-agnostic — it edits source and generates diffs while the builder sidecar handles compilation. The sanitizer type (address only in this CRS) is passed to the agent for context.

Project structure

patcher.py             # Patcher module: one-time fetch of optional inputs → agent → first-patch submit
pyproject.toml         # Package config (run_patcher entry point)
bin/
  compile_target       # Builder phase: compiles the target project
agents/
  gemini_cli.py        # Gemini CLI agent (default)
  gemini_cli.md        # GEMINI.md template with libCRS tool docs
  sections/            # Dynamic GEMINI.md section partial templates
  template.py          # Stub for creating new agents
oss-crs/
  crs.yaml             # CRS metadata (supported languages, models, etc.)
  example-compose.yaml # Example crs-compose configuration
  base.Dockerfile      # Base image: Ubuntu + Node.js + Gemini CLI + Python
  builder.Dockerfile   # Build phase image
  patcher.Dockerfile   # Run phase image
  docker-bake.hcl      # Docker Bake config for the base image
  sample-litellm-config.yaml  # LiteLLM proxy config template

Prerequisites

  • oss-crs — the CRS framework (crs-compose CLI)

Builder and runner sidecars are injected automatically by the framework — no separate builder setup is needed.

Quick start

1. Configure crs-compose.yaml

Copy oss-crs/example-compose.yaml and update the paths:

crs-gemini-cli:
  source:
    local_path: /path/to/crs-gemini-cli
  cpuset: "2-7"
  memory: "16G"
  llm_budget: 10
  additional_env:
    CRS_AGENT: gemini_cli
    GEMINI_MODEL: gemini-3-pro-preview

llm_config:
  # Optional: uncomment if you want OSS-CRS to inject an external LiteLLM endpoint.
  # litellm:
  #   mode: external
  #   external:
  #     url_env: EXTERNAL_LITELLM_API_BASE
  #     key_env: EXTERNAL_LITELLM_API_KEY

2. Optional LiteLLM setup

If you want OSS-CRS to inject an external LiteLLM endpoint, uncomment the llm_config block and make sure EXTERNAL_LITELLM_API_BASE and EXTERNAL_LITELLM_API_KEY are set. oss-crs/sample-litellm-config.yaml remains available as a reference template for LiteLLM-backed setups.

3. Run with oss-crs

crs-compose up -f crs-compose.yaml

Configuration

Environment variable Default Description
CRS_AGENT gemini_cli Agent module name (maps to agents/<name>.py)
GEMINI_MODEL gemini-3-pro-preview Model passed to gemini -m (strips gemini/ prefix if present)
AGENT_TIMEOUT 0 (no limit) Agent timeout in seconds (0 = run until budget exhausted)

Available models:

  • gemini-3-pro-preview
  • gemini-3-flash-preview

Runtime behavior

  • Execution: gemini --approval-mode yolo (auto-approve all tool use)
  • Instruction file: GEMINI.md generated per run in the target repo
  • LiteLLM proxy: Configured via GOOGLE_GEMINI_BASE_URL + GEMINI_API_KEY env vars

Debug artifacts:

  • Log directory: /root/.gemini (registered via register-log-dir)
  • Per-run logs: /work/agent/gemini_stdout.log, /work/agent/gemini_stderr.log

Patch submission

The agent is instructed to satisfy these criteria before writing a patch:

  1. Builds — compiles successfully
  2. POVs don't crash — all provided POV variants pass (if POVs were provided)
  3. Tests pass — project test suite passes (or skipped if none exists)
  4. Semantically correct — fixes the root cause with a minimal patch

Runtime remains trust-based: the patcher does not re-run final verification. Once the first .diff is written to /patches/, the patcher submits that single file and exits. Submitted patches cannot be edited or resubmitted, so the agent should only write to /patches/ when it considers the patch final.

Adding a new agent

  1. Copy agents/template.py to agents/my_agent.py.
  2. Implement setup() and run().
  3. Set CRS_AGENT=my_agent.

The agent receives:

  • setup(source_dir, config) config keys:
    • llm_api_url — optional LiteLLM base URL
    • llm_api_key — optional LiteLLM key
    • gemini_home — path for Gemini CLI state/logs
  • source_dir — clean git repo of the target project
  • pov_dir — boot-time POV input directory (may be empty)
  • bug_candidate_dir — boot-time bug-candidate directory (may be empty)
  • diff_dir — boot-time diff directory (may be empty)
  • seed_dir — boot-time seed directory (may be empty)
  • harness — harness name for run-pov
  • patches_dir — write exactly one final .diff here
  • work_dir — scratch space
  • language — target language (c, c++, jvm)
  • sanitizer — sanitizer type (address only) All optional inputs are boot-time only. The patcher fetches them once and passes directory paths to the agent; no new POVs, bug-candidates, diff files, or seeds appear during the run.

The agent has access to three libCRS commands (builder/runner sidecars are resolved automatically via BUILDER_MODULE env var set by the framework):

  • libCRS apply-patch-build <patch.diff> <response_dir> — build a patch
  • libCRS run-pov <pov> <response_dir> --harness <h> [--rebuild-id <id>] — test against a POV (omit --rebuild-id for base build)
  • libCRS apply-patch-test <patch.diff> <response_dir> — run the project's test suite

For transparent diagnostics, always inspect response_dir logs:

  • Build: stdout.log, stderr.log, retcode
  • POV: stdout.log, stderr.log, retcode
  • Test: stdout.log, stderr.log, retcode

About

Gemini Cli sandbox agent for autonomous vulnerability patching in oss-crs

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors