From a4d0b7a781b589de91676838c50a1d93b43a51b9 Mon Sep 17 00:00:00 2001 From: mikkel <7003+mikkel@users.noreply.github.com> Date: Wed, 21 Oct 2026 18:19:03 -0600 Subject: [PATCH] docs(changelog): generateDiff gains a working fallback; smartapply failure was model-path only --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b97d7..6a64031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [0.3.1] — Unreleased -Stricter UTF-8 tail handling, a guard against Python-style option names in `filterRelevant`, a typed `SmartApplyError` for smartapply refusals, and a new default model to replace a retired one. No change to `generateDiff` or to what `smartapply` writes. +Stricter UTF-8 tail handling, a guard against Python-style option names in `filterRelevant`, a typed `SmartApplyError` for smartapply refusals, and a new default model to replace a retired one. `generateDiff` now has a working fallback model: with no `model` and no `GPTDIFF_MODEL` it uses `DEFAULT_MODEL` (`deepseek/deepseek-v4.1-flash-1017`) instead of the retired id, which failed with HTTP 410. What `smartapply` writes is unchanged. ### Behavior changes @@ -10,7 +10,7 @@ Stricter UTF-8 tail handling, a guard against Python-style option names in `filt - **A truncated UTF-8 tail keeps its valid prefix at any file length.** In 0.3.0 an incomplete trailing sequence was tolerated only when the buffer was exactly 8192 bytes; any other length took the binary path. Now a file that ends in a legal partial character is text with the partial character dropped (`0x61 0xC3` and `0x61 0xE0 0xA0` are `"a"`). Tails that can never become a legal character stay binary (`0x61 0xE0 0x80`, `0x61 0xED 0xA0`, `0x61 0xF0 0x80`, `0x61 0xF4 0x90`; leads C0, C1, F5-FF). Some short files that 0.3.0 skipped as binary are now sent to the decision model. - **`smartapply` refusals throw `SmartApplyError` instead of a plain `Error`.** When smartapply refuses a model rewrite (it changed lines the diff did not add or remove, and the edit could not be replayed from the `+`/`-` lines), the thrown object is now a `SmartApplyError`, exported from the package root and matching patchling-py. What changed: the error's class and constructor (`err.constructor === SmartApplyError`, `instanceof SmartApplyError` is true; it is still `instanceof Error`), `err.name` (`'SmartApplyError'`, was `'Error'`), and therefore how it prints (`String(err)` and the first line of `err.stack` read `SmartApplyError: smartapply: refusing to write …` instead of `Error: …`). Code that checks `err.name === 'Error'`, `err.constructor === Error`, or snapshots the printed error will see the difference. What did not change: the message text (`smartapply: refusing to write "": the model changed lines the diff did not add or remove`, so matching on `err.message` keeps working), when a refusal happens, and provider/LLM errors, which still propagate as the original error object and are never wrapped. -- **Default model is now `deepseek/deepseek-v4.1-flash-1017`.** The 0.3.0 default, `xiaomi/mimo-v2.5-pro-ultraspeed`, has been retired by NanoGPT and returns HTTP 410, so `generateDiff` and `smartapply` failed whenever `GPTDIFF_MODEL` was unset and no `model` was passed. `DEFAULT_MODEL` (and its `.d.ts` literal type) is now `deepseek/deepseek-v4.1-flash-1017`, the October 17, 2026 snapshot of DeepSeek V4.1 Flash as listed on NanoGPT ($0.10 / $0.60 per 1M input / output tokens, 1M context). NanoGPT lists no non-Flash V4.1 model. patchling-py uses the same default. Calls that pass `model` or set `GPTDIFF_MODEL` are unchanged. The `filterRelevant` default (`xiaomi/mimo-v2.6-flash`) is unchanged. The verified catalog snapshot (`test/fixtures/demo-models.json`) adds the new id and was re-checked on 2026-10-21. +- **Default model is now `deepseek/deepseek-v4.1-flash-1017`.** The 0.3.0 default, `xiaomi/mimo-v2.5-pro-ultraspeed`, has been retired by NanoGPT and returns HTTP 410. So whenever `GPTDIFF_MODEL` was unset and no `model` was passed, `generateDiff` failed, and so did `smartapply` on its model-backed path: files whose patch could not be applied deterministically from the `+`/`-` lines. Patches that applied deterministically, and file deletions, never called the model and were unaffected. `DEFAULT_MODEL` (and its `.d.ts` literal type) is now `deepseek/deepseek-v4.1-flash-1017`, the October 17, 2026 snapshot of DeepSeek V4.1 Flash as listed on NanoGPT ($0.10 / $0.60 per 1M input / output tokens, 1M context). NanoGPT lists no non-Flash V4.1 model. patchling-py uses the same default. Calls that pass `model` or set `GPTDIFF_MODEL` are unchanged. The `filterRelevant` default (`xiaomi/mimo-v2.6-flash`) is unchanged. The verified catalog snapshot (`test/fixtures/demo-models.json`) adds the new id and was re-checked on 2026-10-21. ### Docs and tests