crilio
The CI/CD quality gate for AI — pytest for prompts.
If Crilio helps you, please ⭐ star this repo — it helps other devs find it and motivates me to keep building.
☁️ Join the Crilio Cloud Waitlist (Get 40% off team dashboards & analytics when we launch)
Crilio stops prompt regressions from reaching production. Version your prompts + natural-language rules in crilio.yaml — Crilio calls your model, judges every response with an LLM, and reports PASS / FAIL per rule.
✨ Features
- LLM-as-a-Judge — Strict Pydantic-verified verdicts (
rule_passed: bool), temp 0. No flaky free-text parsing. - BYOK — Your keys, your bill. OpenAI + Anthropic. Typically < $0.01 / test on
gpt-4o-mini. - CI/CD Native —
exit 1blocks PRs in GitHub Actions. Locally it warns but never blocks. - PR Comments — Auto-posts formatted failure details to the PR when running in Actions (
GITHUB_TOKEN, silent fail, never blocks gate). - Leak Guard — Rejects
crilio.yamlcontainingsk-.../api_key— keys must be in.env/Secrets, never committed. - Local Bots —
target: {command: "python bot.py '{{prompt}}'"}runs any local model (Ollama/vLLM) via stdout → Judge,$0target. - Budget Guard —
max_monthly_budget_usdhalts the run when cost exceeds cap. Delete the line or leave it blank for unlimited.
🚀 Quick Start
pip install crilio
export OPENAI_API_KEY="sk-proj-..." # or ANTHROPIC_API_KEY — .env also works
crilio init # creates crilio.yaml
crilio run --dry-run # validate without API calls
crilio run # Target → Judge → gate
criliowith no args shows status, budget, and next steps.
⚙️ Usage
| Command | Description |
|---|---|
crilio init [--force] [--yes] |
Create crilio.yaml + optional GitHub Actions workflow |
crilio run [-c FILE] [-m MODEL] [--judge-model MODEL] [--verbose] [--json] [--dry-run] [--tag TAG] |
Run gate — 0 pass, 1 fail (only in CI) · --tag filters to tags: [TAG] tests |
crilio validate [-c FILE] [--json] |
Validate config without API calls — 0 valid, 2 invalid |
crilio --version / crilio --docs |
Version / full interactive guide |
| Variable | Description |
|---|---|
OPENAI_API_KEY |
OpenAI — default target gpt-4o-mini, judge gpt-4o-mini |
ANTHROPIC_API_KEY |
Anthropic — default target claude-3-5-sonnet-latest, judge claude-3-5-haiku-latest |
Provider is inferred from env if not set in crilio.yaml. Keys are never flags — env only.
crilio.yaml
settings:
target_model: gpt-4o
judge_model: gpt-4o-mini
max_monthly_budget_usd: 10.0 # delete or leave blank for unlimited
tests:
- name: Refund Policy Check
prompt: How long do I have to return a product?
rules:
- Must mention the 30-day return window.
- Must NOT mention competitor names.
tags: ["smoke", "critical"]
- name: JSON Format Check
prompt: |
Return ONLY this JSON and nothing else: {"status": "shipped", "order_id": "12345"}
rules:
- Must return valid JSON with keys 'status' and 'order_id'.
- Must NOT include apologies or extra prose.
- name: Local Bot Check
prompt: How long do I have to return a product?
target:
command: "python bot.py '{{prompt}}'"
rules:
- "Must mention the 30-day return window."
tags: ["local"]
Per-test overrides: provider, model, judge_model, system, tags, target can be set per test. Use crilio run --tag smoke to run only tagged tests. target.command runs local CLI ({{prompt}} → shlex.quote, no placeholder → stdin, 30s timeout).
🔄 CI/CD Integration
crilio init can scaffold this for you. Or drop in .github/workflows/crilio.yml:
name: Crilio AI Tests
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.10' }
- run: pip install crilio
- run: crilio run
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # for PR failure comments (auto-provided)
Add the secret matching your provider. A FAIL gate exits 1 and blocks the PR. On failure in Actions, Crilio posts a 🛑 Crilio AI Test Failed comment with test, rule, AI response and reason — requires permissions: pull-requests: write (or default GITHUB_TOKEN), fails silently locally or on API error and never blocks the gate.
📄 License
AGPL-3.0 — see LICENSE.
Metadata
Release files for crilio 0.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crilio-0.0.4.tar.gz | 50.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crilio-0.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 90.3 kB
Release files / crilio-0.0.4.tar.gz
| Download URL | crilio-0.0.4.tar.gz |
|---|---|
| Size | 50.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
999a9075f17c3640554c2cc4fc15360ceaa8fede1cf28dd9ff6e58dcf9aa387f
|
|
BLAKE2b-256 checksum How to use checksums |
bd89c5053feef9b88695b61191d9064f71269ac1f141029d18958817cd428bae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / crilio-0.0.4-py3-none-any.whl
| Download URL | crilio-0.0.4-py3-none-any.whl |
|---|---|
| Size | 40.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3035608842faf0cccbcc46201e4a9902c22466eb98675dd7d4c680d21bc17d65
|
|
BLAKE2b-256 checksum How to use checksums |
0c35fc57ece8f426d2616734bd34ea7ca86e197d1bdca275c56510d1b3b00008
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|