{"slug": "a-faster-dependency-check-using-the-githits-api", "title": "A faster dependency check using the GitHits API", "summary": "A dependency-check agent built on the GitHits API by an unnamed team finished checks in a median of 4.6 seconds at a mean model cost of $0.00015 per check in an October 14, 2026 session, with accuracy comparable to Codex's. The roughly 200-line Python agent fetches latest package versions from GitHits, sends one batched upgrade-review request, filters GitHub severity labels from OSV.dev for high and critical advisories, merges alias-linked records, and uses a single Gemma 4 31B model call to write the report. The test compared Codex alone against the GitHits agent across 35 pinned packages in four sets (two npm, one PyPI, one mixed) with 20 runs per setup and 80 runs total.", "body_md": "[Back to blog](https://githits.com/blog/)\n\nOctober 13, 2026 · 9 min read\n\n# A faster dependency check using the GitHits API\n\nWe compared Codex with a dependency check that retrieves package data through the GitHits API and uses one model call to write the report.\n\nWe built a dependency-check agent using the GitHits API. Code pulls the facts from the index, and one model call writes the report. In one session on October 14, 2026, the GitHits agent with Gemma 4 31B finished in a median of 4.6 seconds, at a mean model cost of $0.00015 per check. Its accuracy scores were comparable to Codex’s.\n\nA software factory changes dependencies all the time. An agent adds a package to finish a feature, and another bumps a version to fix a build. Each change raises the same questions. Is the upgrade a major version jump? Which known high and critical vulnerabilities does it fix? Does it introduce new ones?\n\nYou can ask a coding agent to do this. It looks up the latest versions, finds the advisories, matches them to version ranges, and checks their severity. Repeating that investigation after every dependency change takes time and uses tokens.\n\nWe wanted to know whether a narrower agent could do the same check fast and cheaply enough to run every time.\n\n## The question\n\nEvery run in this experiment answered the same question for a set of pinned dependencies:\n\nOur app is upgrading these dependencies to their latest versions: … For each: is it a major/breaking upgrade, how many high/critical advisories affect the current version, how many are fixed by the target, and does the target introduce any new high/critical advisories? Answer as a table.\n\nWe score “breaking” as a major version change. Checking whether an upgrade breaks the application’s code is a separate task.\n\n## How the agent works\n\nThe agent is about 200 lines of Python. It runs four steps before calling the model:\n\n1. Fetch the latest published version of each package from GitHits.\n2. Send one batched upgrade-review request comparing each current version with its target. The response includes security advisories for both versions.\n3. Read GitHub’s reviewed severity labels from OSV.dev and select the high and critical advisories.\n4. Group advisory records linked by aliases, then count which affect the current version, which the upgrade fixes, and which affect the target but not the current version.\n\nThe model then writes the report from the question and the computed results, with no tools available.\n\nHere is a condensed version of the code:\n\n``` python\ndef depcheck(pkgs, model):\n    # 1. latest version of each package, from the GitHits index\n    latest = [get(f\"/v1/packages/{reg}/{name}?fields=package\")\n              [\"package\"][\"latest_version\"] for reg, name, _ in pkgs]\n\n    # 2. one batched upgrade review: advisories for current and latest\n    batch = [{\"registry\": reg, \"name\": name,\n              \"current_version\": cur, \"target_version\": tgt}\n             for (reg, name, cur), tgt in zip(pkgs, latest)]\n    reviews = post(\"/v1/package-upgrade-reviews?fields=security.direct\",\n                   {\"packages\": batch})\n\n    # 3 + 4. GitHub severity labels from OSV.dev, aliases merged, counted\n    rows = count_high_critical(pkgs, latest, reviews[\"reviews\"], github_label)\n\n    # 5. the only model call: turn the computed table into the report\n    return model(prompt(question(pkgs), rows))\n```\n\nIf security data is unavailable, the agent retries once and then marks the row as unknown rather than returning a count of zero.\n\n## How we tested it\n\nWe compared Codex on its own with our GitHits agent, using two models for each. We tested 35 packages pinned to older versions, divided into four sets:\n\n- Two sets of ten npm packages.\n- One set of ten PyPI packages.\n- One mixed set: moment, node-fetch, and socket.io from npm, plus aiohttp and tornado from PyPI.\n\nEach of the four setups ran every set five times in shuffled order. That gave us 20 runs per setup and 80 runs in the October 14 session. The Codex-only setups had the GitHits MCP server disabled and no GitHits API key in their environment.\n\nWe prepared the answer key from npm, PyPI, and OSV.dev before the runs. A package’s answer counted as correct when all four fields matched: major version change, advisories affecting the current version, advisories fixed, and advisories new in the target. Each setup had 175 answers to score: 35 packages checked five times.\n\n## Time, cost, and token use\n\nWe first compared both approaches using gpt-6.1-sol. Codex looked up versions, advisories, affected version ranges, and severity labels during the run. The GitHits agent fetched and processed that data in code before calling the model.\n\nMedian time fell from 61.2 to 12.8 seconds, about 4.8 times faster. Mean model cost fell from $0.133 to $0.0093, about 14 times lower.\n\nWe also tested Codex with gpt-6-astra at high reasoning effort and with web search enabled. For the fourth setup, we replaced gpt-6.1-sol in the GitHits agent with Gemma 4 31B through OpenRouter.\n\nTimes are medians; costs and token counts are means per run.\n\n| Setup | Median time | Mean model cost | Total tokens | Input (of which cached) | Output | \n|---|---|---|---|---|---|\n| Codex alone, gpt-6.1-sol | 61.2 s | $0.133 | 312.1k | 309.6k (268.8k) | 2.5k | \n| Codex alone, gpt-6-astra, high effort, web search enabled | 100.2 s | $0.897 | 306.7k | 303.0k (257.7k) | 3.7k | \n| GitHits agent + Codex (gpt-6.1-sol) | 12.8 s | $0.0093 | 15.0k | 14.7k (12.3k) | 0.33k | \n| GitHits agent + Gemma 4 31B | 4.6 s | $0.00015 | 0.71k | 0.53k (0.13k) | 0.18k | \n\nThe Gemma setup completed the check in a median of 4.6 seconds, about 22 times faster than Codex with gpt-6-astra.\n\nThe Codex runs used a ChatGPT subscription, so we calculated model costs from logged token usage and list prices. Gemma’s cost came from OpenRouter.\n\nAlthough web search was enabled for gpt-6-astra, its logs recorded no web calls. It used shell tools instead, averaging 7.8 calls per run.\n\n## Why we scored the answers three ways\n\nTwo advisory records can describe the same vulnerability or disagree about which versions it affects. Whether we combine those records, and which version ranges we use, changes the expected answer.\n\nWe scored the same answers against three rules:\n\n- **Group linked records (“merged”).** Combine records linked by aliases and count them once. A GitHub Security Advisory identifier (GHSA) and a CVE identifier can refer to the same vulnerability.\n- **Count advisory IDs separately (“strict”).** Count distinct advisory IDs separately, even when they share aliases. For lodash, two GHSA IDs counted as two under this rule and one under the merged rule.\n- **Use GitHub’s affected versions (“GitHub ranges”).** Use GitHub’s reviewed version ranges to decide whether an advisory affects a package version. Those ranges can differ from the matches returned by OSV.\n\nThe scores below show correct package answers out of 175 under each rule.\n\n| Setup | Group linked records | Count IDs separately | Use GitHub’s affected versions | \n|---|---|---|---|\n| Codex alone, gpt-6.1-sol | 158/175 | 163/175 | 168/175 | \n| Codex alone, gpt-6-astra, high effort, web search enabled | 160/175 | 165/175 | 170/175 | \n| GitHits agent + Codex (gpt-6.1-sol) | 175/175 | 170/175 | 165/175 | \n| GitHits agent + Gemma 4 31B | 175/175 | 170/175 | 165/175 | \n\nBoth GitHits setups scored 175/175 under the merged rule, which is also the rule their code uses. They led under the merged and separate-ID rules; Codex with gpt-6-astra led under GitHub’s affected version ranges.\n\nFor cryptography and pillow, OSV matched an extra record that GitHub’s reviewed version ranges did not include. Along with lodash, these cases explain most of the score differences. Codex alone also made two isolated errors, one involving mongoose and one involving nuxt.\n\n## Index for knowledge, inference for reasoning\n\nWe want models to spend their time on decisions that require reasoning. Code can look up versions, fetch advisories, and count them. Moving those operations out of the agent loop reduced the number of model calls and tokens needed for this check.\n\nHere, the model only had to write the report, and Gemma was sufficient. Deciding which upgrades to make and how to adapt the application takes more reasoning. That is where we want the coding agent to focus.\n\nGitHits gives us version-aware access to the code, documentation, and package data needed for that work. We can let a coding agent choose its queries through MCP or the CLI, or write a fixed sequence of API calls for a recurring task like this one.\n\n## Where this fits in a factory\n\nWe designed this check to run after an agent changes a manifest or lockfile. The 4.6-second median makes it practical to pass the advisory report to the next agent step, so it can address a flagged dependency while working on the change.\n\n## Build it with the GitHits API\n\nThe upgrade-review endpoint accepts multiple packages in one request. Here is a comparison of two pinned dependencies and their target versions:\n\n```\ncurl -X POST https://api.githits.dev/v1/package-upgrade-reviews \\\n  -H \"Authorization: Bearer $GITHITS_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"packages\": [\n      {\n        \"registry\": \"npm\",\n        \"name\": \"lodash\",\n        \"current_version\": \"4.17.20\",\n        \"target_version\": \"4.18.1\"\n      },\n      {\n        \"registry\": \"pypi\",\n        \"name\": \"urllib3\",\n        \"current_version\": \"1.26.4\",\n        \"target_version\": \"2.8.0\"\n      }\n    ]\n  }'\n```\n\nSee the [API documentation](https://docs.githits.com/api/overview) for the full set of endpoints.\n\nIf you’re a software factory interested in using our API, we’d love for you to [book a call with us](https://calendly.com/d/dvxq-7dn-msq/meeting-with-githits-select-15-or-30-minutes) to discuss what it would look like.", "url": "https://wpnews.pro/news/a-faster-dependency-check-using-the-githits-api", "canonical_source": "https://githits.com/blog/dependency-check-agent-githits-api/", "published_at": "2026-10-13 00:00:00+00:00", "updated_at": "2026-10-16 03:31:35.766024+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models"], "entities": ["GitHits", "Codex", "Gemma 4 31B", "OSV.dev", "GitHub", "npm", "PyPI", "Python"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/a-faster-dependency-check-using-the-githits-api", "markdown": "https://wpnews.pro/news/a-faster-dependency-check-using-the-githits-api.md", "text": "https://wpnews.pro/news/a-faster-dependency-check-using-the-githits-api.txt", "jsonld": "https://wpnews.pro/news/a-faster-dependency-check-using-the-githits-api.jsonld"}}