Versions follow MAJOR.MINOR.PATCH (src/version.py); Apify shows MAJOR.MINOR from .actor/actor.json.
Every run logs its version and records it in the RUN_STATS key-value record.
- A run that returns nothing (every input bad, private, blocked or unreachable, or an empty input) now ends
SUCCEEDED with an empty dataset and the reason as its status message and in the log, instead of FAILED. Only an
unexpected error still fails the run.
RUN_STATS keeps the reason as before.
- No change to output fields or price.
- Fixed: one flagged row no longer stops the run. When the model provider's moderation flags a row's text,
OpenRouter answers with HTTP 403, the same status as a refused token, and the run stopped there and failed. That
row now comes back with the reason, uncharged, and the other rows carry on. A refused token or account still stops
the run at once.
- A model that declines to answer now says so, with its reason, instead of "the model's answer isn't JSON: (empty)".
- A run no longer fails when the store it remembers earlier runs in can't be opened (403: the account already has
a store of that name that this actor didn't create). It falls back to
humble-echidna-<name>, and if that is
refused too it runs without memory for that run. Users' existing memory is untouched: the usual name is tried first.
First release: an LLM on every row of a dataset or an inline JSON list, one call per row.
- Rows from
rows (inline JSON; a plain string is {"text": ...}) or any Apify dataset (datasetId, read with the
run's own token, only the top-level fields it needs; up to 20,000 rows per run).
- Only
textFields are sent to the model, each as "field: value"; keepFields are copied to the output (kept)
for joins, with sourceIndex.
- What comes back: one label from
labels (data.label, a strict enum), plain-English fields, or a JSON schema
(precedence schema > fields > labels). Every answer validated; invalid, empty and failed rows are rows with the
reason, never charged.
- Model through Apify's OpenRouter proxy with the run's own token (the shared
mms_llm client, also used by
ai-extract 1.0.5): retries on 429/5xx, strict mode retried as a hint when a provider refuses it, a refusing proxy
stops the run.
onlyNew: skips rows whose text the same setup (schema, instructions, model, text fields) already answered
validly; text hashes in the user's own ai-rows-seen store, remembered only after the row is in the dataset.
- Charged per valid row (
row-processed), after the push; the max cost per run is honoured before a row is sent.
maxRows and maxTokensPerRow cap the token spend. A run near its timeout stops starting rows, saves the
memory and RUN_STATS, and ends cleanly.
- No source is fetched (no robots.txt or terms gate applies): the only requests are to Apify's own API (the user's
dataset) and to Apify's OpenRouter proxy, both on the user's token.