unrent 发布:扫描代码中依赖的闭源 AI 服务与即将下线的模型
stringcutter/unrent
开源工具 unrent 发布,可扫描代码库中依赖的闭源 AI 服务、可替代的开源项目,以及厂商已下线或即将下线的模型,并定位到具体文件与行号。它覆盖 357 个闭源 AI 服务、139 个托管模型提供商和 381 条来自 OpenAI、Anthropic、Google 及 Azure、Bedrock、Vertex 的模型下线记录,每周核对厂商弃用页面。
See which AI services your code depends on, what open source can replace them, and which models are about to stop working.
uvx unrent .What each row means
╎ cut |
You use a closed AI service. The best open source replacement is on the row. |
│ held |
You use a closed AI service with no open source replacement yet. |
┆ snapped |
Your code asks for a model the vendor has shut down. Those calls fail today. |
┆ snaps |
Your code asks for a model the vendor shuts down on the date shown. |
│ runs |
Open source AI you already run, and how it ranks. |
Every row points to a file and line. --why shows all of them, and what to use instead:
Note
unrent runs on your machine. No account, no upload, no telemetry.
Install
uv tool install unrent # or: pipx install unrentPython 3.11+.
Use
unrent . # scan the current directory unrent src/llm.py # one file unrent . --why openai # every line behind one row unrent . -o report.md # a Markdown report for an issue or PR unrent . --format json # for scripts unrent . --skip-tests # ignore test code unrent . --exclude "examples/" # .gitignore syntax, or a .unrentignore file
unrent scan --help lists the rest.
Use it from an AI agent
In Claude Code, as a plugin:
/plugin marketplace add stringcutter/unrent
/plugin install unrent@stringcutter
You get the MCP tools, the skill, and a hook that tells the agent when it writes a model id that is retired or about to be.
Other MCP clients (Cursor, Copilot, …): command uvx, args
["--from", "unrent[mcp]", "unrent", "mcp"].
Only the skill, with a workflow for what unrent can't see on its own:
npx skills add stringcutter/unrent
Use it in CI
On GitHub, the action annotates each line that selects a retiring model (and each closed service, as a note) in code scanning, and fails the build on what you name:
permissions: contents: read security-events: write # for the annotations steps: - uses: actions/checkout@v5 - uses: stringcutter/unrent@v0.4.0 with: fail-on: snapped,snaps # snapped, snaps, closed within: 30 # snaps only within 30 days
On pull requests from forks, and in private repositories without code scanning, add
upload-sarif: false: the build still fails on what you name.
Anywhere else:
unrent . --fail-on snaps --within 30 -o unrent.md # exit 1, and one line saying why unrent . --format sarif -o unrent.sarif # SARIF 2.1.0 for code scanning
How it works
What it finds
- 357 closed AI services in 21 categories: LLM APIs and gateways, embeddings, vector databases, RAG, document parsing, observability, speech, image generation, search, scraping, browser automation, sandboxes, agents and agent memory. 139 hosted model providers come from models.dev, regenerated weekly.
- 381 model retirements from OpenAI, Anthropic and Google, and from Azure, Bedrock and Vertex for the models they serve, with dates and the vendor's replacement, checked weekly against their deprecation pages. A model counts when the code picks it (a default, a config value, a call), not when it is only listed in a menu or price table, and on the schedule of the platform the code calls: gpt-4o through Azure retires on Azure's date. An Azure deployment name is not taken for the model.
- 89 open source projects you may already run: vector databases, inference servers, gateways, RAG frameworks, document parsers, observability, evals, speech.
- Unknown candidates: API hosts and keys that look like a hosted AI service the catalog doesn't know yet. Listed for you to check, never counted.
It reads packages (Python, npm, Go, Cargo, Maven, Gradle, NuGet, RubyGems, Composer, pub, SwiftPM), imports, install commands, container images, and API hosts, model ids, env vars and SDK calls in code and config.
What it ignores
- Local servers behind a compatible SDK:
OpenAI(base_url="http://localhost:11434/v1")is Ollama, not OpenAI. - Comments, docs, lockfiles,
node_modulesand anything.gitignoreexcludes. - Generic names: your
perplexity.pyisn't Perplexity. - Open-weight models:
gpt-oss,deepseek-v3.2and Ollama tags aren't closed.
Secrets in the output are masked (OPENAI_API_KEY=****). Files too large to scan are
listed, never skipped silently.
How alternatives are ranked
- Projects two ways: established, the biggest by GitHub stars, and rising, the most stars gained in the last 30 days (at least 2% of their own), from unrent's own daily snapshots. Rising is where attention moves, not a verdict on quality.
- Besides the projects listed by hand, a daily search finds new ones on GitHub (1,000 stars or more, open licence, active); Jev (TypeSafe) judges each once against its pool, and what it lets in is marked "found by unrent".
- Models by Hugging Face trending: labs' own releases under an open licence.
- Open source only: an OSI licence for code; Apache, MIT, BSD or CC-BY for weights. Archived projects are dropped, and open core is marked.
The CLI uses the rankings shipped with its release. The MCP server fetches the latest
from this repo, and the CLI, the MCP server and the hook fetch the latest model
retirements, all cached for six hours (UNRENT_OFFLINE=1 turns that off). Only these
public lists come in; your code never goes out.
How accurate it is
Every rule has a test that fails without it. A golden corpus of 54 real repos, labelled by hand, runs in CI: closed services precision 0.993, recall 0.957; models that stop working precision 0.939, recall 0.886.
With ripgrep installed, a 5,500-file repo scans in about 6 s.
来源:GitHub · github.com