lastorders 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lastorders-0.4.0/CHANGELOG.md +50 -0
- lastorders-0.4.0/MANIFEST.in +6 -0
- lastorders-0.4.0/PKG-INFO +212 -0
- lastorders-0.4.0/README.md +186 -0
- lastorders-0.4.0/lastorders.egg-info/PKG-INFO +212 -0
- lastorders-0.4.0/lastorders.egg-info/SOURCES.txt +32 -0
- lastorders-0.4.0/lastorders.egg-info/dependency_links.txt +1 -0
- lastorders-0.4.0/lastorders.egg-info/entry_points.txt +2 -0
- lastorders-0.4.0/lastorders.egg-info/requires.txt +8 -0
- lastorders-0.4.0/lastorders.egg-info/top_level.txt +1 -0
- lastorders-0.4.0/migration_kit/__init__.py +2 -0
- lastorders-0.4.0/migration_kit/__main__.py +3 -0
- lastorders-0.4.0/migration_kit/brand.py +27 -0
- lastorders-0.4.0/migration_kit/cli.py +365 -0
- lastorders-0.4.0/migration_kit/evaluator.py +526 -0
- lastorders-0.4.0/migration_kit/fixer/__init__.py +12 -0
- lastorders-0.4.0/migration_kit/fixer/callsite.py +65 -0
- lastorders-0.4.0/migration_kit/fixer/engine.py +463 -0
- lastorders-0.4.0/migration_kit/fixer/jsfix.py +373 -0
- lastorders-0.4.0/migration_kit/fixer/pyfix.py +260 -0
- lastorders-0.4.0/migration_kit/fixer/verify.py +292 -0
- lastorders-0.4.0/migration_kit/initevals.py +278 -0
- lastorders-0.4.0/migration_kit/licence.py +337 -0
- lastorders-0.4.0/migration_kit/pack_data/__init__.py +0 -0
- lastorders-0.4.0/migration_kit/pack_data/anthropic.json +271 -0
- lastorders-0.4.0/migration_kit/pack_data/openai.json +1230 -0
- lastorders-0.4.0/migration_kit/pack_data/pack.schema.json +615 -0
- lastorders-0.4.0/migration_kit/packs.py +299 -0
- lastorders-0.4.0/migration_kit/report.py +355 -0
- lastorders-0.4.0/migration_kit/scanner.py +398 -0
- lastorders-0.4.0/migration_kit/site.py +60 -0
- lastorders-0.4.0/migration_kit/swapper.py +127 -0
- lastorders-0.4.0/pyproject.toml +47 -0
- lastorders-0.4.0/setup.cfg +4 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0 (unreleased)
|
|
4
|
+
- **Renamed to Last Orders.** Package, CLI and PyPI name `lastorders`; env vars `LASTORDERS_*` (was the placeholder
|
|
5
|
+
`modelmigrate` / `MODELMIGRATE_*`); output marker `.lastorders-output`; Action `burntandtoast/lastorders@v0`;
|
|
6
|
+
Worker `lastorders-licence`, D1 database `lastorders-licences`, Stripe metadata product `lastorders-repo`.
|
|
7
|
+
- **Licence server** (`server/`). This is a Cloudflare Worker with D1:
|
|
8
|
+
- Stripe Checkout at £149 per repo (configurable);
|
|
9
|
+
- a signed webhook that issues `BTM-XXXX-XXXX-XXXX` keys, stores them with the buyer's email, and emails them through Resend (the email provider is pluggable);
|
|
10
|
+
- the repo is bound on first activation;
|
|
11
|
+
- full refunds revoke the licence;
|
|
12
|
+
- a success page and admin rebind/revoke tools;
|
|
13
|
+
- it also serves the pack site.
|
|
14
|
+
|
|
15
|
+
Not deployed. See docs/LICENCE-SERVER.md.
|
|
16
|
+
- **Real licence check in the CLI**, replacing the format-only placeholder:
|
|
17
|
+
- an online verify sends only the key and repo;
|
|
18
|
+
- a 7-day Ed25519-signed token is cached locally;
|
|
19
|
+
- a 14-day grace period applies if the server is unreachable;
|
|
20
|
+
- `--offline` uses the cached token only;
|
|
21
|
+
- the free `scan` is unaffected.
|
|
22
|
+
- New `licence status|buy|forget` command and the `LASTORDERS_REPO` fallback. New dependency: `cryptography`.
|
|
23
|
+
|
|
24
|
+
## 0.3.0 (unreleased)
|
|
25
|
+
- `fix`: automatic code fixes driven entirely by pack rules. It renames `max_tokens` per endpoint, adds
|
|
26
|
+
`reasoning_effort`/`reasoning.effort` "none" where the new model needs it, and flags legacy functions,
|
|
27
|
+
Assistants, legacy Completions, fine-tunes, fine-tuning jobs, LangChain, `**kwargs`/spread and unknown models
|
|
28
|
+
for a manual decision. Python uses libcst (lossless); JS/TS use a built-in lexer. Outputs `fix.diff`, `fix-plan.md` and `fix-plan.json`.
|
|
29
|
+
- `fix --verify`: applies the patch to a scratch copy, checks syntax and idempotence, and replays every fixed call
|
|
30
|
+
old vs new. With `--live` it also runs a control (unpatched arguments on the new model). `--evals` reruns the customer suite.
|
|
31
|
+
- `fix --apply` is gated behind the licence and refuses files with uncommitted changes unless `--force` is passed.
|
|
32
|
+
- Pack format: `signals[].call` (call-level detection) and structured `rules[].fix`
|
|
33
|
+
(`per_endpoint`, `requires_new_model`, `keep_model`). OpenAI pack 2026.10.15.4, Anthropic 2026.10.15.2.
|
|
34
|
+
- Live finding (15 Oct 2026): GPT-4o and GPT-4.1 reject `reasoning_effort`, so that fix must ship with the model switch.
|
|
35
|
+
- Client report: an "Automatic fixes" section with the verification results.
|
|
36
|
+
|
|
37
|
+
## 0.2.0 (unreleased)
|
|
38
|
+
- Free `scan` packaged for `pip`/`pipx` (entry point then called `modelmigrate`, a placeholder name); no licence or API key needed.
|
|
39
|
+
- Provider-neutral **migration packs** (JSON + JSON Schema): OpenAI (full), Anthropic (stub). Fetched from a
|
|
40
|
+
hosted URL at runtime with sha256 check, 24h cache and bundled offline fallback.
|
|
41
|
+
- Scanner, swap and report are generic engines driven by pack data (model IDs, aliases, families, shutdown dates,
|
|
42
|
+
replacements, SDK/call-site signals, parameter/endpoint/tool-calling rules).
|
|
43
|
+
- GitHub Action (`action.yml`, composite): job summary, PR annotations, artifact upload, optional fail on high risk.
|
|
44
|
+
- Placeholder licence gate for `swap --apply`, `eval` and `report` (`LASTORDERS_LICENCE` / `--licence`). One licence = one GitHub repo (monorepos included).
|
|
45
|
+
- `init-evals`: generate a starter regression suite from the scan's call sites (prompts, schemas, tools read statically).
|
|
46
|
+
- Network policy: only the pack fetch (and, later, the licence check) contacts us; no telemetry. `--offline` / `LASTORDERS_OFFLINE=1`.
|
|
47
|
+
- `packs list|validate|build-site`; deployable static pack site for Vercel / Cloudflare Pages.
|
|
48
|
+
|
|
49
|
+
## 0.1.0
|
|
50
|
+
- Internal migration kit: scan, swap, eval (mock + live), client report.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lastorders
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Free scanner for retiring AI model IDs (OpenAI, Anthropic, ...) in your code, with CI support.
|
|
5
|
+
Author: Burnt & Toast Studios
|
|
6
|
+
Project-URL: Homepage, https://burntandtoast.com
|
|
7
|
+
Keywords: openai,anthropic,llm,deprecation,migration,gpt-4o,scanner,github-action
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: pyyaml>=6
|
|
20
|
+
Requires-Dist: jsonschema>=4
|
|
21
|
+
Requires-Dist: libcst>=1.1
|
|
22
|
+
Requires-Dist: cryptography>=41
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
26
|
+
|
|
27
|
+
# Last Orders (working name)
|
|
28
|
+
|
|
29
|
+
**Find retiring AI model IDs in your code before they break.** One command scans your repo for OpenAI
|
|
30
|
+
(and, as a preview, Anthropic) model IDs that are being shut down. For each one it tells you the
|
|
31
|
+
shutdown date, the replacement the provider recommends, and the code changes the new model needs.
|
|
32
|
+
|
|
33
|
+
> **Heads-up:** OpenAI removes **GPT-4o, GPT-4o mini, GPT-4.1 and GPT-4.1 mini** from the API on
|
|
34
|
+
> **14 January 2027** and recommends `gpt-6-luna`. In our tests, `gpt-6-luna` rejects `max_tokens`, and it
|
|
35
|
+
> rejects tool calls on Chat Completions unless `reasoning_effort` is `"none"`. So changing the model name
|
|
36
|
+
> isn't enough. The scan flags both.
|
|
37
|
+
|
|
38
|
+
The scan is free. You don't need an account, a licence or an API key, and your code never leaves your machine.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pipx install lastorders # or: pip install lastorders
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You need Python 3.10 or later.
|
|
47
|
+
|
|
48
|
+
## Scan
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
lastorders scan . # scan the current repo
|
|
52
|
+
lastorders scan path/to/repo --out scan-results
|
|
53
|
+
lastorders scan . --offline # no network at all (uses the bundled migration pack)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You get `scan.md`, a readable report, and `scan.json`, the same data for tools. They go in `lastorders-out/`, or wherever `--out` points. Each finding includes:
|
|
57
|
+
|
|
58
|
+
- **File, line and model ID**, from code (Python, JS, TS), `.env` files, YAML, JSON, TOML and docs
|
|
59
|
+
- **Shutdown date and recommended replacement**, from the provider's published deprecations
|
|
60
|
+
- **Risk level**. High means the date is close or has passed, or the new model needs a code change your
|
|
61
|
+
code doesn't have yet, such as `max_tokens` becoming `max_completion_tokens`, `reasoning_effort` for tools
|
|
62
|
+
and `temperature`, or an unsupported endpoint
|
|
63
|
+
- **Fine-tuned models** (`ft:...`), listed separately. They shut down with their base model and can't be
|
|
64
|
+
swapped automatically.
|
|
65
|
+
- **Models chosen by environment variable** (`os.getenv("OPENAI_MODEL")`), so you can check the
|
|
66
|
+
values you have deployed
|
|
67
|
+
- **SDKs detected**: the official `openai` and `anthropic` clients, LangChain and plain HTTP
|
|
68
|
+
|
|
69
|
+
Useful flags:
|
|
70
|
+
|
|
71
|
+
| Flag | What it does |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `--fail-on-high` | exit code 2 if anything is high risk (for CI) |
|
|
74
|
+
| `--no-docs` | skip `.md` / `.txt` files |
|
|
75
|
+
| `--pack openai` | only use some providers' packs (default: all) |
|
|
76
|
+
| `--offline` | use the bundled pack only; makes no network calls |
|
|
77
|
+
| `--format json` | print the summary as JSON |
|
|
78
|
+
| `--summary-file F` / `--annotations` | CI outputs (used by the GitHub Action) |
|
|
79
|
+
|
|
80
|
+
## Fix (patch preview)
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
lastorders fix . # writes lastorders-out/fix.diff + fix-plan.md; changes nothing on disk
|
|
84
|
+
lastorders fix . --verify # also checks the patch on a scratch copy (see below)
|
|
85
|
+
git apply lastorders-out/fix.diff
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`fix` swaps the retiring model IDs and then makes the code changes the new model needs at each API call:
|
|
89
|
+
|
|
90
|
+
- **Renames `max_tokens`**, to `max_completion_tokens` on Chat Completions or `max_output_tokens` on Responses.
|
|
91
|
+
- **Adds `reasoning_effort: "none"`** where gpt-6-luna needs it: Chat Completions calls with tools, and
|
|
92
|
+
calls that set `temperature`, `top_p` or `logprobs`. On Responses it adds `reasoning.effort`.
|
|
93
|
+
- **Flags anything it can't decide safely** in `fix-plan.md`: legacy `functions` calls, Assistants and legacy
|
|
94
|
+
Completions calls (these stay on their current model in the patch), fine-tunes and fine-tuning jobs,
|
|
95
|
+
LangChain wrappers, calls that pass `**kwargs` or a spread object, conflicting values, and calls whose model
|
|
96
|
+
isn't visible in the code (use `--assume-model`).
|
|
97
|
+
|
|
98
|
+
Every change comes from the migration pack's rules. Python is edited with
|
|
99
|
+
[libcst](https://github.com/Instagram/LibCST), so your formatting and comments are kept. JS and TS are edited
|
|
100
|
+
with a built-in parser. Rules the pack marks `inferred` are only suggested unless you pass `--include-inferred`.
|
|
101
|
+
|
|
102
|
+
**Old models reject `reasoning_effort`.** We tested gpt-4o and gpt-4.1 against the live API, and both return
|
|
103
|
+
HTTP 400. Any fix that adds it has to ship together with the model switch. When the model comes from an
|
|
104
|
+
environment variable, the plan marks the fix "ship with the model switch". `--no-model-swap` applies only
|
|
105
|
+
the changes that are safe on the old model.
|
|
106
|
+
|
|
107
|
+
`--verify` applies the patch to a temporary copy of your repo, then:
|
|
108
|
+
|
|
109
|
+
1. checks the changed files still parse;
|
|
110
|
+
2. re-runs the fixer and checks it changes nothing more;
|
|
111
|
+
3. replays each fixed call twice: once as it was (old model, old arguments) and once as patched (new model,
|
|
112
|
+
new arguments).
|
|
113
|
+
|
|
114
|
+
Without `--live`, the replay uses simulated responses. With `--live` and your own `OPENAI_API_KEY` (licence),
|
|
115
|
+
the calls go straight to OpenAI. A control run also sends the unpatched arguments to the new model, to show
|
|
116
|
+
each fix was needed. `--evals evals/regression.yaml` reruns your own suite with the fixed arguments.
|
|
117
|
+
|
|
118
|
+
## GitHub Action
|
|
119
|
+
|
|
120
|
+
Add `.github/workflows/model-scan.yml`:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
name: Model retirement scan
|
|
124
|
+
on:
|
|
125
|
+
pull_request:
|
|
126
|
+
schedule: [{ cron: "0 7 * * 1" }] # weekly, so new deprecations show up without code changes
|
|
127
|
+
permissions:
|
|
128
|
+
contents: read
|
|
129
|
+
jobs:
|
|
130
|
+
scan:
|
|
131
|
+
runs-on: ubuntu-latest
|
|
132
|
+
steps:
|
|
133
|
+
- uses: actions/checkout@v4
|
|
134
|
+
- uses: burntandtoast/lastorders@v0 # available once the repo is published
|
|
135
|
+
with:
|
|
136
|
+
fail-on-high: "true"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The Action posts a summary table to the job page, marks findings inline on the PR and uploads `scan.json`
|
|
140
|
+
as an artifact. Inputs:
|
|
141
|
+
|
|
142
|
+
| Input | Default | |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `path` | `.` | folder to scan |
|
|
145
|
+
| `fail-on-high` | `false` | fail the job on high-risk findings |
|
|
146
|
+
| `include-docs` | `true` | scan `.md`/`.txt` |
|
|
147
|
+
| `annotations` | `true` | inline PR annotations |
|
|
148
|
+
| `packs` | all | e.g. `openai,anthropic` |
|
|
149
|
+
| `offline` | `false` | bundled pack only, no network |
|
|
150
|
+
| `packs-url` | built-in | override the pack URL |
|
|
151
|
+
| `version` | action source | install this version from PyPI instead |
|
|
152
|
+
| `python-version` | `3.12` | |
|
|
153
|
+
| `fix-preview` | `false` | also attach the automatic-fix patch + plan (simulated verify, no key) |
|
|
154
|
+
| `artifact-name` | `lastorders-scan` | |
|
|
155
|
+
|
|
156
|
+
Outputs: `total`, `high` and `report-dir`.
|
|
157
|
+
|
|
158
|
+
## Migration packs: where the data comes from
|
|
159
|
+
|
|
160
|
+
What the scanner knows lives in **migration packs**, versioned JSON files with one pack per provider. Each pack
|
|
161
|
+
holds the model IDs and aliases, shutdown dates, replacements, call-site patterns, and parameter and endpoint
|
|
162
|
+
rules. Every fact links to the provider's documentation and the date we checked it. Rules we confirmed
|
|
163
|
+
against the live API are marked `live-tested`, and anything we assumed is marked `inferred`.
|
|
164
|
+
|
|
165
|
+
- **OpenAI**: full pack
|
|
166
|
+
- **Anthropic**: preview (stub). It covers Claude API retirement dates from Anthropic's deprecations page.
|
|
167
|
+
Amazon Bedrock and Google Cloud dates are not covered yet.
|
|
168
|
+
- Gemini, Azure OpenAI and Bedrock: planned
|
|
169
|
+
|
|
170
|
+
The tool checks for a newer pack once a day and falls back to the copy bundled with the package.
|
|
171
|
+
`lastorders packs list` shows which version and source you're using. The format is documented in
|
|
172
|
+
[docs/PACKS.md](docs/PACKS.md), with a JSON Schema in `migration_kit/pack_data/pack.schema.json`.
|
|
173
|
+
|
|
174
|
+
## Privacy and network use
|
|
175
|
+
|
|
176
|
+
- The scan runs **entirely on your machine**. Your code and prompts are never uploaded.
|
|
177
|
+
- **The tool has no telemetry, analytics or tracking.** (Our website counts visits anonymously with Cloudflare Web Analytics: no cookies, no ads, no tracking across sites.)
|
|
178
|
+
- The tool only ever contacts us to **download the latest migration pack** (a plain GET of a static JSON file,
|
|
179
|
+
with no identifiers) and, for paid features, to **check a licence key**. That check sends only the key and the
|
|
180
|
+
repo name (`github.com/owner/repo`), and the signed answer is cached for a week, with a 14-day offline grace period after that.
|
|
181
|
+
- `--offline` (or `LASTORDERS_OFFLINE=1`) turns off all network access and uses the bundled pack.
|
|
182
|
+
- The paid `eval` command calls the AI provider directly **with your own API key**. Nothing goes through us.
|
|
183
|
+
|
|
184
|
+
## Paid features
|
|
185
|
+
|
|
186
|
+
| | Free | Licence (per repo) | Done for you |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| `scan`, GitHub Action, patch preview (`fix` / `swap` write a `.diff`), `fix --verify` (simulated replay) | ✓ | ✓ | ✓ |
|
|
189
|
+
| `fix --apply` / `swap --apply`, `fix --verify --live`, `init-evals` + `eval` regression testing, client-ready `report` | | ✓ | ✓ |
|
|
190
|
+
| We do the migration, evals and handoff | | | ✓ |
|
|
191
|
+
|
|
192
|
+
One licence covers **one GitHub repository, monorepos included**. It's bound to the repo the first time
|
|
193
|
+
you use it. Buy one with `lastorders licence buy` (it prints a Stripe Checkout link for this repo), then pass the key
|
|
194
|
+
with `LASTORDERS_LICENCE` (a repository secret in Actions) or `--licence`. `lastorders licence status` shows
|
|
195
|
+
whether it's verified. Paid commands work `--offline` from the cached check. Repos without an `origin` remote
|
|
196
|
+
can set `LASTORDERS_REPO=github.com/owner/repo`. The licence server lives in `server/`; see
|
|
197
|
+
[docs/LICENCE-SERVER.md](docs/LICENCE-SERVER.md).
|
|
198
|
+
|
|
199
|
+
`init-evals` reads the call sites the scan found, including prompts, JSON schemas and tool definitions where
|
|
200
|
+
they can be read from the code, and writes a starter `evals/regression.yaml`. You then edit it into 10 to 20
|
|
201
|
+
real examples. `eval` runs them against the old and new model with your own key.
|
|
202
|
+
|
|
203
|
+
## Limitations
|
|
204
|
+
|
|
205
|
+
- Detection uses pattern matching. Model names built at runtime or stored in a database won't be found;
|
|
206
|
+
env-var lookups are listed so you can check them.
|
|
207
|
+
- A pack is only as current as its `updated` date. Always check the provider's documentation before acting.
|
|
208
|
+
- The scan suggests changes; it doesn't decide them for you. Review every patch.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
Made by [Burnt & Toast Studios](https://burntandtoast.com). Not affiliated with OpenAI or Anthropic.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Last Orders (working name)
|
|
2
|
+
|
|
3
|
+
**Find retiring AI model IDs in your code before they break.** One command scans your repo for OpenAI
|
|
4
|
+
(and, as a preview, Anthropic) model IDs that are being shut down. For each one it tells you the
|
|
5
|
+
shutdown date, the replacement the provider recommends, and the code changes the new model needs.
|
|
6
|
+
|
|
7
|
+
> **Heads-up:** OpenAI removes **GPT-4o, GPT-4o mini, GPT-4.1 and GPT-4.1 mini** from the API on
|
|
8
|
+
> **14 January 2027** and recommends `gpt-6-luna`. In our tests, `gpt-6-luna` rejects `max_tokens`, and it
|
|
9
|
+
> rejects tool calls on Chat Completions unless `reasoning_effort` is `"none"`. So changing the model name
|
|
10
|
+
> isn't enough. The scan flags both.
|
|
11
|
+
|
|
12
|
+
The scan is free. You don't need an account, a licence or an API key, and your code never leaves your machine.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pipx install lastorders # or: pip install lastorders
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
You need Python 3.10 or later.
|
|
21
|
+
|
|
22
|
+
## Scan
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
lastorders scan . # scan the current repo
|
|
26
|
+
lastorders scan path/to/repo --out scan-results
|
|
27
|
+
lastorders scan . --offline # no network at all (uses the bundled migration pack)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You get `scan.md`, a readable report, and `scan.json`, the same data for tools. They go in `lastorders-out/`, or wherever `--out` points. Each finding includes:
|
|
31
|
+
|
|
32
|
+
- **File, line and model ID**, from code (Python, JS, TS), `.env` files, YAML, JSON, TOML and docs
|
|
33
|
+
- **Shutdown date and recommended replacement**, from the provider's published deprecations
|
|
34
|
+
- **Risk level**. High means the date is close or has passed, or the new model needs a code change your
|
|
35
|
+
code doesn't have yet, such as `max_tokens` becoming `max_completion_tokens`, `reasoning_effort` for tools
|
|
36
|
+
and `temperature`, or an unsupported endpoint
|
|
37
|
+
- **Fine-tuned models** (`ft:...`), listed separately. They shut down with their base model and can't be
|
|
38
|
+
swapped automatically.
|
|
39
|
+
- **Models chosen by environment variable** (`os.getenv("OPENAI_MODEL")`), so you can check the
|
|
40
|
+
values you have deployed
|
|
41
|
+
- **SDKs detected**: the official `openai` and `anthropic` clients, LangChain and plain HTTP
|
|
42
|
+
|
|
43
|
+
Useful flags:
|
|
44
|
+
|
|
45
|
+
| Flag | What it does |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `--fail-on-high` | exit code 2 if anything is high risk (for CI) |
|
|
48
|
+
| `--no-docs` | skip `.md` / `.txt` files |
|
|
49
|
+
| `--pack openai` | only use some providers' packs (default: all) |
|
|
50
|
+
| `--offline` | use the bundled pack only; makes no network calls |
|
|
51
|
+
| `--format json` | print the summary as JSON |
|
|
52
|
+
| `--summary-file F` / `--annotations` | CI outputs (used by the GitHub Action) |
|
|
53
|
+
|
|
54
|
+
## Fix (patch preview)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
lastorders fix . # writes lastorders-out/fix.diff + fix-plan.md; changes nothing on disk
|
|
58
|
+
lastorders fix . --verify # also checks the patch on a scratch copy (see below)
|
|
59
|
+
git apply lastorders-out/fix.diff
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`fix` swaps the retiring model IDs and then makes the code changes the new model needs at each API call:
|
|
63
|
+
|
|
64
|
+
- **Renames `max_tokens`**, to `max_completion_tokens` on Chat Completions or `max_output_tokens` on Responses.
|
|
65
|
+
- **Adds `reasoning_effort: "none"`** where gpt-6-luna needs it: Chat Completions calls with tools, and
|
|
66
|
+
calls that set `temperature`, `top_p` or `logprobs`. On Responses it adds `reasoning.effort`.
|
|
67
|
+
- **Flags anything it can't decide safely** in `fix-plan.md`: legacy `functions` calls, Assistants and legacy
|
|
68
|
+
Completions calls (these stay on their current model in the patch), fine-tunes and fine-tuning jobs,
|
|
69
|
+
LangChain wrappers, calls that pass `**kwargs` or a spread object, conflicting values, and calls whose model
|
|
70
|
+
isn't visible in the code (use `--assume-model`).
|
|
71
|
+
|
|
72
|
+
Every change comes from the migration pack's rules. Python is edited with
|
|
73
|
+
[libcst](https://github.com/Instagram/LibCST), so your formatting and comments are kept. JS and TS are edited
|
|
74
|
+
with a built-in parser. Rules the pack marks `inferred` are only suggested unless you pass `--include-inferred`.
|
|
75
|
+
|
|
76
|
+
**Old models reject `reasoning_effort`.** We tested gpt-4o and gpt-4.1 against the live API, and both return
|
|
77
|
+
HTTP 400. Any fix that adds it has to ship together with the model switch. When the model comes from an
|
|
78
|
+
environment variable, the plan marks the fix "ship with the model switch". `--no-model-swap` applies only
|
|
79
|
+
the changes that are safe on the old model.
|
|
80
|
+
|
|
81
|
+
`--verify` applies the patch to a temporary copy of your repo, then:
|
|
82
|
+
|
|
83
|
+
1. checks the changed files still parse;
|
|
84
|
+
2. re-runs the fixer and checks it changes nothing more;
|
|
85
|
+
3. replays each fixed call twice: once as it was (old model, old arguments) and once as patched (new model,
|
|
86
|
+
new arguments).
|
|
87
|
+
|
|
88
|
+
Without `--live`, the replay uses simulated responses. With `--live` and your own `OPENAI_API_KEY` (licence),
|
|
89
|
+
the calls go straight to OpenAI. A control run also sends the unpatched arguments to the new model, to show
|
|
90
|
+
each fix was needed. `--evals evals/regression.yaml` reruns your own suite with the fixed arguments.
|
|
91
|
+
|
|
92
|
+
## GitHub Action
|
|
93
|
+
|
|
94
|
+
Add `.github/workflows/model-scan.yml`:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
name: Model retirement scan
|
|
98
|
+
on:
|
|
99
|
+
pull_request:
|
|
100
|
+
schedule: [{ cron: "0 7 * * 1" }] # weekly, so new deprecations show up without code changes
|
|
101
|
+
permissions:
|
|
102
|
+
contents: read
|
|
103
|
+
jobs:
|
|
104
|
+
scan:
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/checkout@v4
|
|
108
|
+
- uses: burntandtoast/lastorders@v0 # available once the repo is published
|
|
109
|
+
with:
|
|
110
|
+
fail-on-high: "true"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The Action posts a summary table to the job page, marks findings inline on the PR and uploads `scan.json`
|
|
114
|
+
as an artifact. Inputs:
|
|
115
|
+
|
|
116
|
+
| Input | Default | |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `path` | `.` | folder to scan |
|
|
119
|
+
| `fail-on-high` | `false` | fail the job on high-risk findings |
|
|
120
|
+
| `include-docs` | `true` | scan `.md`/`.txt` |
|
|
121
|
+
| `annotations` | `true` | inline PR annotations |
|
|
122
|
+
| `packs` | all | e.g. `openai,anthropic` |
|
|
123
|
+
| `offline` | `false` | bundled pack only, no network |
|
|
124
|
+
| `packs-url` | built-in | override the pack URL |
|
|
125
|
+
| `version` | action source | install this version from PyPI instead |
|
|
126
|
+
| `python-version` | `3.12` | |
|
|
127
|
+
| `fix-preview` | `false` | also attach the automatic-fix patch + plan (simulated verify, no key) |
|
|
128
|
+
| `artifact-name` | `lastorders-scan` | |
|
|
129
|
+
|
|
130
|
+
Outputs: `total`, `high` and `report-dir`.
|
|
131
|
+
|
|
132
|
+
## Migration packs: where the data comes from
|
|
133
|
+
|
|
134
|
+
What the scanner knows lives in **migration packs**, versioned JSON files with one pack per provider. Each pack
|
|
135
|
+
holds the model IDs and aliases, shutdown dates, replacements, call-site patterns, and parameter and endpoint
|
|
136
|
+
rules. Every fact links to the provider's documentation and the date we checked it. Rules we confirmed
|
|
137
|
+
against the live API are marked `live-tested`, and anything we assumed is marked `inferred`.
|
|
138
|
+
|
|
139
|
+
- **OpenAI**: full pack
|
|
140
|
+
- **Anthropic**: preview (stub). It covers Claude API retirement dates from Anthropic's deprecations page.
|
|
141
|
+
Amazon Bedrock and Google Cloud dates are not covered yet.
|
|
142
|
+
- Gemini, Azure OpenAI and Bedrock: planned
|
|
143
|
+
|
|
144
|
+
The tool checks for a newer pack once a day and falls back to the copy bundled with the package.
|
|
145
|
+
`lastorders packs list` shows which version and source you're using. The format is documented in
|
|
146
|
+
[docs/PACKS.md](docs/PACKS.md), with a JSON Schema in `migration_kit/pack_data/pack.schema.json`.
|
|
147
|
+
|
|
148
|
+
## Privacy and network use
|
|
149
|
+
|
|
150
|
+
- The scan runs **entirely on your machine**. Your code and prompts are never uploaded.
|
|
151
|
+
- **The tool has no telemetry, analytics or tracking.** (Our website counts visits anonymously with Cloudflare Web Analytics: no cookies, no ads, no tracking across sites.)
|
|
152
|
+
- The tool only ever contacts us to **download the latest migration pack** (a plain GET of a static JSON file,
|
|
153
|
+
with no identifiers) and, for paid features, to **check a licence key**. That check sends only the key and the
|
|
154
|
+
repo name (`github.com/owner/repo`), and the signed answer is cached for a week, with a 14-day offline grace period after that.
|
|
155
|
+
- `--offline` (or `LASTORDERS_OFFLINE=1`) turns off all network access and uses the bundled pack.
|
|
156
|
+
- The paid `eval` command calls the AI provider directly **with your own API key**. Nothing goes through us.
|
|
157
|
+
|
|
158
|
+
## Paid features
|
|
159
|
+
|
|
160
|
+
| | Free | Licence (per repo) | Done for you |
|
|
161
|
+
|---|---|---|---|
|
|
162
|
+
| `scan`, GitHub Action, patch preview (`fix` / `swap` write a `.diff`), `fix --verify` (simulated replay) | ✓ | ✓ | ✓ |
|
|
163
|
+
| `fix --apply` / `swap --apply`, `fix --verify --live`, `init-evals` + `eval` regression testing, client-ready `report` | | ✓ | ✓ |
|
|
164
|
+
| We do the migration, evals and handoff | | | ✓ |
|
|
165
|
+
|
|
166
|
+
One licence covers **one GitHub repository, monorepos included**. It's bound to the repo the first time
|
|
167
|
+
you use it. Buy one with `lastorders licence buy` (it prints a Stripe Checkout link for this repo), then pass the key
|
|
168
|
+
with `LASTORDERS_LICENCE` (a repository secret in Actions) or `--licence`. `lastorders licence status` shows
|
|
169
|
+
whether it's verified. Paid commands work `--offline` from the cached check. Repos without an `origin` remote
|
|
170
|
+
can set `LASTORDERS_REPO=github.com/owner/repo`. The licence server lives in `server/`; see
|
|
171
|
+
[docs/LICENCE-SERVER.md](docs/LICENCE-SERVER.md).
|
|
172
|
+
|
|
173
|
+
`init-evals` reads the call sites the scan found, including prompts, JSON schemas and tool definitions where
|
|
174
|
+
they can be read from the code, and writes a starter `evals/regression.yaml`. You then edit it into 10 to 20
|
|
175
|
+
real examples. `eval` runs them against the old and new model with your own key.
|
|
176
|
+
|
|
177
|
+
## Limitations
|
|
178
|
+
|
|
179
|
+
- Detection uses pattern matching. Model names built at runtime or stored in a database won't be found;
|
|
180
|
+
env-var lookups are listed so you can check them.
|
|
181
|
+
- A pack is only as current as its `updated` date. Always check the provider's documentation before acting.
|
|
182
|
+
- The scan suggests changes; it doesn't decide them for you. Review every patch.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
Made by [Burnt & Toast Studios](https://burntandtoast.com). Not affiliated with OpenAI or Anthropic.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lastorders
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Free scanner for retiring AI model IDs (OpenAI, Anthropic, ...) in your code, with CI support.
|
|
5
|
+
Author: Burnt & Toast Studios
|
|
6
|
+
Project-URL: Homepage, https://burntandtoast.com
|
|
7
|
+
Keywords: openai,anthropic,llm,deprecation,migration,gpt-4o,scanner,github-action
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: pyyaml>=6
|
|
20
|
+
Requires-Dist: jsonschema>=4
|
|
21
|
+
Requires-Dist: libcst>=1.1
|
|
22
|
+
Requires-Dist: cryptography>=41
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
26
|
+
|
|
27
|
+
# Last Orders (working name)
|
|
28
|
+
|
|
29
|
+
**Find retiring AI model IDs in your code before they break.** One command scans your repo for OpenAI
|
|
30
|
+
(and, as a preview, Anthropic) model IDs that are being shut down. For each one it tells you the
|
|
31
|
+
shutdown date, the replacement the provider recommends, and the code changes the new model needs.
|
|
32
|
+
|
|
33
|
+
> **Heads-up:** OpenAI removes **GPT-4o, GPT-4o mini, GPT-4.1 and GPT-4.1 mini** from the API on
|
|
34
|
+
> **14 January 2027** and recommends `gpt-6-luna`. In our tests, `gpt-6-luna` rejects `max_tokens`, and it
|
|
35
|
+
> rejects tool calls on Chat Completions unless `reasoning_effort` is `"none"`. So changing the model name
|
|
36
|
+
> isn't enough. The scan flags both.
|
|
37
|
+
|
|
38
|
+
The scan is free. You don't need an account, a licence or an API key, and your code never leaves your machine.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pipx install lastorders # or: pip install lastorders
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You need Python 3.10 or later.
|
|
47
|
+
|
|
48
|
+
## Scan
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
lastorders scan . # scan the current repo
|
|
52
|
+
lastorders scan path/to/repo --out scan-results
|
|
53
|
+
lastorders scan . --offline # no network at all (uses the bundled migration pack)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You get `scan.md`, a readable report, and `scan.json`, the same data for tools. They go in `lastorders-out/`, or wherever `--out` points. Each finding includes:
|
|
57
|
+
|
|
58
|
+
- **File, line and model ID**, from code (Python, JS, TS), `.env` files, YAML, JSON, TOML and docs
|
|
59
|
+
- **Shutdown date and recommended replacement**, from the provider's published deprecations
|
|
60
|
+
- **Risk level**. High means the date is close or has passed, or the new model needs a code change your
|
|
61
|
+
code doesn't have yet, such as `max_tokens` becoming `max_completion_tokens`, `reasoning_effort` for tools
|
|
62
|
+
and `temperature`, or an unsupported endpoint
|
|
63
|
+
- **Fine-tuned models** (`ft:...`), listed separately. They shut down with their base model and can't be
|
|
64
|
+
swapped automatically.
|
|
65
|
+
- **Models chosen by environment variable** (`os.getenv("OPENAI_MODEL")`), so you can check the
|
|
66
|
+
values you have deployed
|
|
67
|
+
- **SDKs detected**: the official `openai` and `anthropic` clients, LangChain and plain HTTP
|
|
68
|
+
|
|
69
|
+
Useful flags:
|
|
70
|
+
|
|
71
|
+
| Flag | What it does |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `--fail-on-high` | exit code 2 if anything is high risk (for CI) |
|
|
74
|
+
| `--no-docs` | skip `.md` / `.txt` files |
|
|
75
|
+
| `--pack openai` | only use some providers' packs (default: all) |
|
|
76
|
+
| `--offline` | use the bundled pack only; makes no network calls |
|
|
77
|
+
| `--format json` | print the summary as JSON |
|
|
78
|
+
| `--summary-file F` / `--annotations` | CI outputs (used by the GitHub Action) |
|
|
79
|
+
|
|
80
|
+
## Fix (patch preview)
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
lastorders fix . # writes lastorders-out/fix.diff + fix-plan.md; changes nothing on disk
|
|
84
|
+
lastorders fix . --verify # also checks the patch on a scratch copy (see below)
|
|
85
|
+
git apply lastorders-out/fix.diff
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`fix` swaps the retiring model IDs and then makes the code changes the new model needs at each API call:
|
|
89
|
+
|
|
90
|
+
- **Renames `max_tokens`**, to `max_completion_tokens` on Chat Completions or `max_output_tokens` on Responses.
|
|
91
|
+
- **Adds `reasoning_effort: "none"`** where gpt-6-luna needs it: Chat Completions calls with tools, and
|
|
92
|
+
calls that set `temperature`, `top_p` or `logprobs`. On Responses it adds `reasoning.effort`.
|
|
93
|
+
- **Flags anything it can't decide safely** in `fix-plan.md`: legacy `functions` calls, Assistants and legacy
|
|
94
|
+
Completions calls (these stay on their current model in the patch), fine-tunes and fine-tuning jobs,
|
|
95
|
+
LangChain wrappers, calls that pass `**kwargs` or a spread object, conflicting values, and calls whose model
|
|
96
|
+
isn't visible in the code (use `--assume-model`).
|
|
97
|
+
|
|
98
|
+
Every change comes from the migration pack's rules. Python is edited with
|
|
99
|
+
[libcst](https://github.com/Instagram/LibCST), so your formatting and comments are kept. JS and TS are edited
|
|
100
|
+
with a built-in parser. Rules the pack marks `inferred` are only suggested unless you pass `--include-inferred`.
|
|
101
|
+
|
|
102
|
+
**Old models reject `reasoning_effort`.** We tested gpt-4o and gpt-4.1 against the live API, and both return
|
|
103
|
+
HTTP 400. Any fix that adds it has to ship together with the model switch. When the model comes from an
|
|
104
|
+
environment variable, the plan marks the fix "ship with the model switch". `--no-model-swap` applies only
|
|
105
|
+
the changes that are safe on the old model.
|
|
106
|
+
|
|
107
|
+
`--verify` applies the patch to a temporary copy of your repo, then:
|
|
108
|
+
|
|
109
|
+
1. checks the changed files still parse;
|
|
110
|
+
2. re-runs the fixer and checks it changes nothing more;
|
|
111
|
+
3. replays each fixed call twice: once as it was (old model, old arguments) and once as patched (new model,
|
|
112
|
+
new arguments).
|
|
113
|
+
|
|
114
|
+
Without `--live`, the replay uses simulated responses. With `--live` and your own `OPENAI_API_KEY` (licence),
|
|
115
|
+
the calls go straight to OpenAI. A control run also sends the unpatched arguments to the new model, to show
|
|
116
|
+
each fix was needed. `--evals evals/regression.yaml` reruns your own suite with the fixed arguments.
|
|
117
|
+
|
|
118
|
+
## GitHub Action
|
|
119
|
+
|
|
120
|
+
Add `.github/workflows/model-scan.yml`:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
name: Model retirement scan
|
|
124
|
+
on:
|
|
125
|
+
pull_request:
|
|
126
|
+
schedule: [{ cron: "0 7 * * 1" }] # weekly, so new deprecations show up without code changes
|
|
127
|
+
permissions:
|
|
128
|
+
contents: read
|
|
129
|
+
jobs:
|
|
130
|
+
scan:
|
|
131
|
+
runs-on: ubuntu-latest
|
|
132
|
+
steps:
|
|
133
|
+
- uses: actions/checkout@v4
|
|
134
|
+
- uses: burntandtoast/lastorders@v0 # available once the repo is published
|
|
135
|
+
with:
|
|
136
|
+
fail-on-high: "true"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The Action posts a summary table to the job page, marks findings inline on the PR and uploads `scan.json`
|
|
140
|
+
as an artifact. Inputs:
|
|
141
|
+
|
|
142
|
+
| Input | Default | |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `path` | `.` | folder to scan |
|
|
145
|
+
| `fail-on-high` | `false` | fail the job on high-risk findings |
|
|
146
|
+
| `include-docs` | `true` | scan `.md`/`.txt` |
|
|
147
|
+
| `annotations` | `true` | inline PR annotations |
|
|
148
|
+
| `packs` | all | e.g. `openai,anthropic` |
|
|
149
|
+
| `offline` | `false` | bundled pack only, no network |
|
|
150
|
+
| `packs-url` | built-in | override the pack URL |
|
|
151
|
+
| `version` | action source | install this version from PyPI instead |
|
|
152
|
+
| `python-version` | `3.12` | |
|
|
153
|
+
| `fix-preview` | `false` | also attach the automatic-fix patch + plan (simulated verify, no key) |
|
|
154
|
+
| `artifact-name` | `lastorders-scan` | |
|
|
155
|
+
|
|
156
|
+
Outputs: `total`, `high` and `report-dir`.
|
|
157
|
+
|
|
158
|
+
## Migration packs: where the data comes from
|
|
159
|
+
|
|
160
|
+
What the scanner knows lives in **migration packs**, versioned JSON files with one pack per provider. Each pack
|
|
161
|
+
holds the model IDs and aliases, shutdown dates, replacements, call-site patterns, and parameter and endpoint
|
|
162
|
+
rules. Every fact links to the provider's documentation and the date we checked it. Rules we confirmed
|
|
163
|
+
against the live API are marked `live-tested`, and anything we assumed is marked `inferred`.
|
|
164
|
+
|
|
165
|
+
- **OpenAI**: full pack
|
|
166
|
+
- **Anthropic**: preview (stub). It covers Claude API retirement dates from Anthropic's deprecations page.
|
|
167
|
+
Amazon Bedrock and Google Cloud dates are not covered yet.
|
|
168
|
+
- Gemini, Azure OpenAI and Bedrock: planned
|
|
169
|
+
|
|
170
|
+
The tool checks for a newer pack once a day and falls back to the copy bundled with the package.
|
|
171
|
+
`lastorders packs list` shows which version and source you're using. The format is documented in
|
|
172
|
+
[docs/PACKS.md](docs/PACKS.md), with a JSON Schema in `migration_kit/pack_data/pack.schema.json`.
|
|
173
|
+
|
|
174
|
+
## Privacy and network use
|
|
175
|
+
|
|
176
|
+
- The scan runs **entirely on your machine**. Your code and prompts are never uploaded.
|
|
177
|
+
- **The tool has no telemetry, analytics or tracking.** (Our website counts visits anonymously with Cloudflare Web Analytics: no cookies, no ads, no tracking across sites.)
|
|
178
|
+
- The tool only ever contacts us to **download the latest migration pack** (a plain GET of a static JSON file,
|
|
179
|
+
with no identifiers) and, for paid features, to **check a licence key**. That check sends only the key and the
|
|
180
|
+
repo name (`github.com/owner/repo`), and the signed answer is cached for a week, with a 14-day offline grace period after that.
|
|
181
|
+
- `--offline` (or `LASTORDERS_OFFLINE=1`) turns off all network access and uses the bundled pack.
|
|
182
|
+
- The paid `eval` command calls the AI provider directly **with your own API key**. Nothing goes through us.
|
|
183
|
+
|
|
184
|
+
## Paid features
|
|
185
|
+
|
|
186
|
+
| | Free | Licence (per repo) | Done for you |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| `scan`, GitHub Action, patch preview (`fix` / `swap` write a `.diff`), `fix --verify` (simulated replay) | ✓ | ✓ | ✓ |
|
|
189
|
+
| `fix --apply` / `swap --apply`, `fix --verify --live`, `init-evals` + `eval` regression testing, client-ready `report` | | ✓ | ✓ |
|
|
190
|
+
| We do the migration, evals and handoff | | | ✓ |
|
|
191
|
+
|
|
192
|
+
One licence covers **one GitHub repository, monorepos included**. It's bound to the repo the first time
|
|
193
|
+
you use it. Buy one with `lastorders licence buy` (it prints a Stripe Checkout link for this repo), then pass the key
|
|
194
|
+
with `LASTORDERS_LICENCE` (a repository secret in Actions) or `--licence`. `lastorders licence status` shows
|
|
195
|
+
whether it's verified. Paid commands work `--offline` from the cached check. Repos without an `origin` remote
|
|
196
|
+
can set `LASTORDERS_REPO=github.com/owner/repo`. The licence server lives in `server/`; see
|
|
197
|
+
[docs/LICENCE-SERVER.md](docs/LICENCE-SERVER.md).
|
|
198
|
+
|
|
199
|
+
`init-evals` reads the call sites the scan found, including prompts, JSON schemas and tool definitions where
|
|
200
|
+
they can be read from the code, and writes a starter `evals/regression.yaml`. You then edit it into 10 to 20
|
|
201
|
+
real examples. `eval` runs them against the old and new model with your own key.
|
|
202
|
+
|
|
203
|
+
## Limitations
|
|
204
|
+
|
|
205
|
+
- Detection uses pattern matching. Model names built at runtime or stored in a database won't be found;
|
|
206
|
+
env-var lookups are listed so you can check them.
|
|
207
|
+
- A pack is only as current as its `updated` date. Always check the provider's documentation before acting.
|
|
208
|
+
- The scan suggests changes; it doesn't decide them for you. Review every patch.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
Made by [Burnt & Toast Studios](https://burntandtoast.com). Not affiliated with OpenAI or Anthropic.
|