ai@7.0.94 is a patch release that reshapes the experimental batch API. Seven names leave the package and nine arrive in their place: a batch is no longer text-specific, and the model it runs against is now named per request rather than once for the whole batch. The package’s changelog files the work under “feat: support per-request models in batch.” Only code that imports one of the seven removed names from ai is affected.

What changed

Before and after

The import Emendant’s matchers look for, one per removed name:

import { experimental_startTextBatch } from 'ai';
export { experimental_startTextBatch };

No transform can write any of the seven, so there is no rewritten file to show. An assisted patch is offered for each, and what it has to work out follows from the two option types. In ai@7.0.93, the model and the tools belonged to the batch:

type StartTextBatchOptions<TOOLS extends ToolSet = ToolSet> = {
model: BatchLanguageModel;
requests: ReadonlyArray<TextBatchRequest>;
tools?: TOOLS;
toolChoice?: ToolChoice<NoInfer<TOOLS>>;
providerOptions?: ProviderOptions;
webhookUrl?: string;
} & BatchRequestOptions;

In ai@7.0.94, the batch names a provider and each request names its own model:

type StartBatchOptions<TOOLS extends ToolSet = ToolSet, PROVIDER extends BatchProvider = BatchProvider> = {
provider?: PROVIDER;
requests: ReadonlyArray<BatchRequest<InferBatchModelIds<PROVIDER>, TOOLS>>;
providerOptions?: ProviderOptions;
webhookUrl?: string;
} & BatchCallOptions;

Migration guidance and its limits

The seven removed names carry an assisted fix. Name a model provider on the command line or in emendant.json and emendant fix tries each one; without one they are reported with their guidance and nothing is sent anywhere. Expect declines among them: the guidance names the construct that went and tells the model to set fixed to false rather than invent a replacement, and several of these have no replacement that is a rename. Experimental_BatchLanguageModel has no direct successor at all, and experimental_startTextBatch becomes a differently shaped call rather than a differently spelled one. A patch that is written is proved in a copy of your repository moved to 7.0.94 and put through whichever of your own typecheck and tests it finds there, and withheld if it fails.

The two findings on experimental_getBatchStatus and experimental_getBatchResults are report only. Both fire at the options literal rather than at an import, because the model key those calls took is the thing that went, and what belongs there instead is a provider on a differently named type rather than a key to rename.

Rename the call and the two option types, then move what the batch used to hold down onto the requests. Each entry in requests takes type: 'text' and a model, plus the tools, toolChoice, toolOrder and toolsContext that used to sit beside requests. Drop Experimental_BatchLanguageModel from your own signatures and use the model id string the request expects.

Persisted references do not survive the upgrade. A batch reference stored by ai@7.0.93 is version 1 and carries type and modelId; the code reading it in 7.0.94 expects version 2 and neither field. A batch started before the upgrade has to be drained before it, or its reference migrated by hand.

The matchers fire on the import statement alone. Two things a scan therefore stays quiet about: Experimental_BatchReference and Experimental_TextBatchRequest kept their names while changing shape, so importing either is not a finding even though the code around it may no longer compile. A clean scan says a file does not import these seven names from ai, and nothing more about the release.

What Emendant detects, fixes and verifies

9 changes in ai 7.0.94. 0 patched by a transform, 7 patched only with a model provider you name, 2 report only. Every patch is proved in a copy of your repository before it is offered, and its header names the checks that passed. This table is generated from the feed entry, so it cannot claim more than the entry does.

ChangeSeverityDetectsFixVerified by
Removed Experimental_BatchLanguageModel
ai-npm-7.0.94-experimental-batch-language-model-removed
Breaking
  • Experimental_BatchLanguageModel imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed Experimental_BatchOperationOptions
ai-npm-7.0.94-experimental-batch-operation-options-removed
Breaking
  • Experimental_BatchOperationOptions imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed Experimental_StartTextBatchOptions
ai-npm-7.0.94-experimental-start-text-batch-options-removed
Breaking
  • Experimental_StartTextBatchOptions imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed Experimental_StartTextBatchResult
ai-npm-7.0.94-experimental-start-text-batch-result-removed
Breaking
  • Experimental_StartTextBatchResult imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed Experimental_TextBatch
ai-npm-7.0.94-experimental-text-batch-removed
Breaking
  • Experimental_TextBatch imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed Experimental_TextBatchReference
ai-npm-7.0.94-experimental-text-batch-reference-removed
Breaking
  • Experimental_TextBatchReference imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed experimental_startTextBatch
ai-npm-7.0.94-experimental-start-text-batch-removed
Breaking
  • experimental_startTextBatch imported from ai
Patch, only when you name a model providerYour typecheck and tests
Removed model from the first argument of experimental_getBatchResults()
ai-npm-7.0.94-experimental-get-batch-results-argument-1-model-removed
Breaking
  • the model key in the object passed to experimental_getBatchResults imported from ai
Report onlyNot applicable
Removed model from the first argument of experimental_getBatchStatus()
ai-npm-7.0.94-experimental-get-batch-status-argument-1-model-removed
Breaking
  • the model key in the object passed to experimental_getBatchStatus imported from ai
Report onlyNot applicable

emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.

Coverage

Snapshot
2026-09-20.1, sequence 27, signed 20 September 2026
Minimum CLI
emendant@0.1.4
Feed entry
feed/npm/ai/7.0.94.json

emendant feed status shows the snapshot your machine holds, and emendant feed update fetches the latest.

Primary sources

Every claim above was checked against these, each pinned to the release rather than to a default branch.

Scan your repository

Runs locally, reads your lockfile and source, sends nothing anywhere.

npx emendant scan

Then npx emendant fix writes the patches the table says exist. The getting started guide covers the flags and the patch grades.