Skip to main content

gitaiflow

DjangoPlay icon DjangoPlay

Maintained by: [DjangoPlay](https://djangoplay.org)

Python PyPI Downloads Build Coverage License GitHub Release GitHub Stars

A standalone OpenID Connect (OIDC) identity microservice, built with FastAPI, plus a small Django client for services that need to talk to it.


Generate an AI change summary from your git diff -- as a single, timestamped JSON file that's ready to use as a commit title/body, pipe into a commit-msg hook, or feed to another tool/agent.

Works with any AI provider: a free Google Gemini API key, a fully local Ollama model, or any OpenAI-compatible endpoint (OpenAI, Groq, DeepSeek, OpenRouter, vLLM, LM Studio, ...). One config, one output format, no vendor lock-in.

$ gitaiflow --path mailer/ --print-commit

mailer: add retry backoff for failed sends

- Added exponential backoff retry logic in retry.py
- tasks.py now retries send_mail up to 3 times on failure
- No changes to public function signatures

Install

pip install gitaiflow

Configure an AI provider (required)

gitaiflow needs an AI model configured -- it will not run without one. Pick whichever fits:

1. Gemini (free tier, cloud, default)

export AI_PROVIDER=gemini
export AI_API_KEY=<your-key>          # https://aistudio.google.com/apikey

2. Ollama (local, no API key, no cost)

export AI_PROVIDER=ollama
export AI_MODEL=llama3.2:3b           # must match `ollama list` exactly

3. Any OpenAI-compatible provider (OpenAI, OpenRouter, Groq, self-hosted, ...)

export AI_PROVIDER=custom
export AI_BASE_URL=<endpoint>
export AI_API_KEY=<key>
export AI_MODEL=<model>

Any of these can also live in a .gitaiflow.env file in your repo root instead of real environment variables (same KEY=value format). If nothing is configured, gitaiflow fails fast with these same instructions rather than partway through a run.

Full config reference:

Variable Default Notes
AI_PROVIDER gemini gemini | ollama | openai | custom
AI_BASE_URL provider default override for any provider
AI_API_KEY (none) required for gemini/openai/custom; not needed for ollama
AI_MODEL provider default e.g. gemini-flash-lite-latest, llama3.2:3b, gpt-4.1-mini
AI_TEMPERATURE 0.2
AI_MAX_TOKENS 1024
AI_REQUEST_TIMEOUT 60 seconds

Usage

gitaiflow --path mailer/                        # summarize a directory
gitaiflow --path users/views/logout.py           # summarize a single file
gitaiflow --path . --skip migrations tests       # skip paths
gitaiflow --path . --remote upstream --base-branch develop
gitaiflow --path . -o artifacts/                 # custom output root
gitaiflow --path . --markdown                    # also write a .md view
gitaiflow --path . --print-commit                # print title+body to stdout

--print-commit is meant to be piped straight into git:

gitaiflow --path . --print-commit > /tmp/msg.txt && git commit -F /tmp/msg.txt

Output

Every run writes one JSON file to change-summary/json/<target>-<timestamp>.json:

{
  "generated_at": "2026-08-19T14:32:07+05:30",
  "target": "mailer",
  "target_type": "directory",
  "repository": "paystream",
  "branch": "feature/mailer-retry",
  "base": "origin/main",
  "author": { "name": "Merc", "email": "merc@example.com" },
  "change_window": {
    "first_change_at": "2026-08-18 09:12:03",
    "last_change_at": "2026-08-19 14:30:11"
  },
  "files_changed": [
    { "path": "mailer/tasks.py", "status": "modified" },
    { "path": "mailer/retry.py", "status": "added" }
  ],
  "model": { "provider": "gemini", "name": "gemini-flash-lite-latest" },
  "commit": {
    "title": "mailer: add retry backoff for failed sends",
    "body": "- Added exponential backoff retry logic in retry.py\n- tasks.py now retries send_mail up to 3 times on failure\n- No changes to public function signatures"
  },
  "summary": "(same content as commit.body)"
}

author, branch, base, change_window, and files_changed come straight from git -- never from the model -- so they're accurate even if the AI call fails or hallucinates. commit.title / commit.body are the only model-generated fields, and they're the ones designed to be commit-ready as-is.

--markdown renders a second, human-facing view from the same JSON into change-summary/markdown/ -- the JSON is always the source of truth.

Local usage log

Every run appends one line to ~/.gitaiflow/usage.jsonl -- timestamp, repo name, target type, model used, estimated token counts, duration, success. This file never leaves your machine. It exists so you can see your own usage and, optionally, set soft daily limits:

export GITAIFLOW_MAX_RUNS_PER_DAY=20
export GITAIFLOW_MAX_TOKENS_PER_DAY=50000

When set, gitaiflow prints a warning once you've crossed the threshold for the day. This is a courtesy guardrail against accidentally running up a cloud-model bill, not enforcement -- it's a local file, and any user can clear it.

Repository layout

telemetry_server/ lives inside this same repo, at the root, next to the gitaiflow/ package -- it is not a separate project and not something copied by hand onto the server. This matters because production deployment relies on git pull bringing it along automatically (see telemetry_server/DEPLOY.md).

gitaiflow/                    (repo root)
├── gitaiflow/                <- the PyPI package (this is what `pip install gitaiflow` installs)
│   ├── config/
│   ├── services/
│   ├── prompts/
│   └── generate_summary.py   <- CLI entry point
├── telemetry_server/         <- standalone Flask receiver, deployed separately to
│   │                            app.djangoplay.org -- see telemetry_server/DEPLOY.md
│   ├── app.py
│   ├── requirements.txt
│   ├── gitaiflow-telemetry.service
│   ├── nginx-conf.d-gitaiflow-telemetry-ratelimit.conf
│   ├── nginx-location-snippet.conf
│   └── DEPLOY.md
├── .gitlab-ci.yml
├── .gitlab/ci/
│   ├── pypi-release.yml      <- test -> build -> version-check -> publish (manual, main only)
│   ├── github-mirror.yml     <- mirrors main to GitHub on every push
│   └── deploy-telemetry.yml  <- deploys telemetry_server/ to production (manual, main only)
├── .github/workflows/gitlab-mirror.yml
├── pyproject.toml
└── README.md                 <- this file

Two independent things ship from this one repo: the gitaiflow PyPI package (what end users pip install), and the telemetry receiver (a small internal service you run, not part of the package). They share a repo and a CI pipeline but nothing else at runtime.

Telemetry (opt-in, off by default)

gitaiflow does not phone home by default. If you explicitly set:

export GITAIFLOW_TELEMETRY=true

then each run sends exactly this, to https://app.djangoplay.org/gitaiflow-telemetry/v1/events (the maintainer's self-hosted receiver -- see telemetry_server/ above and its DEPLOY.md for how it's run), and nothing else:

Field Example
install_id random UUID, generated once locally
event "run"
timestamp 2026-08-19T14:32:07Z
gitaiflow_version "1.0.0"
ai_provider "gemini"
model_name "gemini-flash-lite-latest"
target_type "file" | "directory"
files_changed_count 4
tokens_estimated_in / tokens_estimated_out 1832 / 210
duration_ms 2140
success true
os "linux"

Never sent, even with telemetry on: repository name, file paths, file contents, diff content, git author/branch, commit messages, or the AI-generated summary text. On the first telemetry-enabled run, gitaiflow prints the exact payload to stdout so this is verifiable, not just promised.

Limitations

  • An AI provider is mandatory -- gitaiflow does nothing without one configured, by design (see "Configure an AI provider" above).
  • Daily run/token limits are a local, deletable courtesy check, not real enforcement. There's no license/quota server behind them.
  • Secret redaction (.env, *_API_KEY, *_SECRET_KEY, etc.) is best-effort pattern matching on the diff -- always review generated summaries before sharing them outside your team.
  • Token/cost estimates in the usage log are a rough len(text) / 4 heuristic, not provider-accurate billing.

Roadmap (not yet built)

  • Hosted model-routing backend for a future paid tier.
  • Server-side license/quota enforcement.
  • PR-platform integration (auto-post summaries to GitHub/GitLab).
  • Diff/summary caching across runs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gitaiflow-1.0.0.tar.gz (29.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gitaiflow-1.0.0-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file gitaiflow-1.0.0.tar.gz.

File metadata

  • Download URL: gitaiflow-1.0.0.tar.gz
  • Upload date:
  • Size: 29.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for gitaiflow-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b5013c0766b6a8e20126d22146c849039598efe98e0306ca52c89b88d475bf57
MD5 751b54501624e728d017782794f85d7f
BLAKE2b-256 9f519039da6deb0dfcf7e3803426409a487c384e356abeb25da6b524778a6afd

See more details on using hashes here.

File details

Details for the file gitaiflow-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: gitaiflow-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for gitaiflow-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af73d5f8b2348ba56491769822e25ea073566fc82622a4664426d11dfeff82cc
MD5 b2b52acb541cdb93fa96373c34f8bb1b
BLAKE2b-256 dc8aa8ab8d25e362b2cb0052ced6970112498425656a4a4804570e29191b32f3

See more details on using hashes here.

Release history Release notifications | RSS feed

1.0.2

2 files

1.0.1

2 files

This release

1.0.0 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page