Different is a variant-analysis agentic tool built with DeepAgents. It does two things:
- First, it looks at an "inspiration" local Git repository and tries to extract recent bug fixes and security fixes, skipping docs/formatting/test/refactor-only commits unless the diff shows an actual bug fix. It outputs a structured JSON file with one entry per fix, including idea-level root causes and tags so matching can be flexible.
- Then, it takes that JSON and checks a “target” local Git repository to see if the same problems likely apply there. It outputs another JSON file with one entry per finding.
The logic is agentic: an LLM calls local Git tools (and optional GitHub API tools) in a loop to inspect commits, diffs, and related PR/issue context.
Each finding includes id, kind, severity, title, root_cause, fix_summary, evidence, and tags. For kind="bug" findings with a concrete severity (not "unknown"), it also includes main_file and exploit_risk (a short paragraph describing how an attacker could exploit the bug and what impact they could get).
The inspiration agent can fetch PR labels and review comments for richer context. The target agent can search commit messages (git_log_search) to check if a fix was already applied, and list tracked files (git_ls_files) to explore the project structure.
- You are fuzzing two parsers,
AandB, that should behave almost identically. Rundifferentto check that recent bug/vuln fixes from codebaseAdon't apply to codebaseB. - A CVE drops for library
X. You have an internal fork or a similar implementation. PointdifferentatXas inspiration and your codebase as target to quickly check if the same bug class affects you. - Before doing code review for codebase
B, rundifferentagainst a well-maintained sibling codebaseAto see what kinds of vulnerabilities are being fixed there and get inspiration from that. - Give it as context to an LLM/agentinc app when doing LLM-based bug-hunting, so that your agent has a context full of valid and fresh bugs.
The default config uses GPT-5.2 with xhigh reasonning. If you switch to a Claude model via --model, you need ANTHROPIC_API_KEY.
This repo includes a .pre-commit-config.yaml that runs ruff, ty, and shellcheck.
Use prek (or pre-commit) to run the hooks, for example:
uv sync --group lint
prek run --all-filesOr use the Makefile:
make lintpytestruns withpytest-cov.- Warnings are treated as errors. Run:
uv run pytestOr use the Makefile:
make testThe app reads different.toml. This is where you set the "recent" window (days + max commits), how many patch lines are fetched per commit, whether GitHub enrichment is enabled, whether HTML reports are generated, and the default model settings. You can also set extract.since_date (YYYY-MM-DD or ISO-8601) to scan from a fixed date; it overrides since_days.
You can override the model per run with --model.
Run the full workflow (extract -> check):
uv sync --all-groups
different-agent --inspiration /path/to/inspiration-repo --target /path/to/target-repoRun extraction only (skip target analysis):
uv sync --all-groups
different-agent --inspiration /path/to/inspiration-repo --extract-onlyOutputs are written under outputs/<project_name>/ and get a time-based suffix per run.
For example: outputs/my-target/target_assessment_01-12_22-12.json.
At the end of a run, the console also prints how many commits and PRs were analyzed.
Scan from a given date (overrides since_days):
different-agent --inspiration /path/to/inspiration-repo --target /path/to/target-repo --since-date 2024-01-01Limit GitHub PRs to a number range (inclusive):
different-agent --inspiration /path/to/inspiration-repo --extract-only --from-pr 3300 --to-pr 3350When a PR range is provided, the extractor skips commit and issue scanning and focuses on GitHub PRs only.