Repository navigation
Description
Part of #1620 / #1795. Estimate: 2 points.
User-visible change
A dataset has three items with url and title fields.
Past the end, offset=100
- Before: "Fetched 0 of 3 items; no more pages."
- After: "Offset 100 is past the last item: the dataset has 3 items (offsets 0 to 2)." Next step: "get-dataset-items with offset=0 returns the first page."
Unknown fields, fields="price,rating"
- Before: "Fetched all 3 items." The items are [{},{},{}], with no explanation.
- After: "Fetched all 3 items. None of them has the requested fields (price, rating)."
- With get-dataset loaded: "get-dataset with datasetId= lists the dataset's fields."
- Without it: "An item read without
fieldsshows its field names."
These are descriptions of results, not commands. Text and structured summary/nextStep must agree.
Agent instructions
In src/tools/storage/storage_helpers.ts, extend buildDatasetItemsSummaryNextStep with fields: readonly string[] and hasOnlyEmptyItems: boolean.
- First, if totalItemCount > 0 and offset >= totalItemCount, return the past-end summary and first-page hint above. Use singular "item" for total=1.
- Otherwise compute the existing summary and nextStep. Remove the nonfinal-page early return so the next rule runs on every page.
- If fields.length > 0, itemCount > 0, and hasOnlyEmptyItems, append the field warning and replace nextStep with the field-list hint or fallback above. Gate get-dataset through suggestTool; use HELPER_TOOLS for names.
In get_dataset_items.ts, pass the already-parsed fields and compute hasOnlyEmptyItems from returned items: every item is a non-null, non-array object with zero keys. Update existing helper-test calls for the new parameters.
Keep items and pagination metadata unchanged. Zero-item datasets keep their existing text. No omit/flatten redesign.
Tests
In tests/unit/tools.storage_helpers.test.ts, cover: offset equal to total and beyond total; singular total; empty projection on a terminal and nonfinal page; sibling-tool fallback; no warning without fields or when returned items have content; zero-item dataset unchanged. Reuse existing cases where they already cover a branch.
In tools.get_dataset_items.test.ts, add one wiring pair using the real tool and a fake dataset API: requested fields with empty objects versus items with content. Assert the fields passed to the API and whether the warning appears. No mock of storage_helpers; do not repeat the helper's pagination matrix.
Only the two edge-case texts change. Flag that served-text contract change in the PR.
Checks and delivery
Read AGENTS.md, CONTRIBUTING.md, TOOL_GUIDELINES.md, tests/UNIT_TESTING_GUIDE.md, and applicable child AGENTS.md files. Work in an isolated worktree on fix/dataset-items-paging-text from current origin/master. Follow the tool and unit-test guidelines; fake external calls only. Write the regression first and confirm it fails; control cases may already pass.
Run all five:
pnpm run type-check
pnpm run lint
pnpm run test:unit
pnpm run format
pnpm run check:agentsReview the final diff. Use this issue’s title for the PR. Fix failures caused by this change; report unrelated failures without cleanup. No integration tests.
For the probes below, set APIFY_TOKEN, run pnpm run build, then mcpc. If @stdio-full exists, mcpc @stdio-full restart; otherwise mcpc connect .mcp.json:stdio-full @stdio-full. Never paste credentials.
Done: scoped change, passing checks, and probe evidence in a PR against master with Closes #1801, a tool-text contract-change note, and disclosure naming the AI tool actually used. Request review from @jirispilka; post no comments. Stop and report if the named code is missing, the behavior is already fixed, or a different design is needed.
mcpc probes
Create a fresh fixture and retain the exact returned ID:
apify datasets create --json
apify datasets push-items <id> '[{"url":"a","title":"A"},{"url":"b","title":"B"},{"url":"c","title":"C"}]'
mcpc @stdio-full tools-call get-dataset-items datasetId:='"<id>"' offset:=100
mcpc @stdio-full tools-call get-dataset-items datasetId:='"<id>"' fields:='"price,rating"'Expect both After results. Also run the fields call in default @stdio (restart/connect as above), which lacks get-dataset: expect the unnamed fallback. Use apify datasets get-items for ground truth. After recording results, delete only the fixture created here with apify datasets rm --yes.
Spec revised with Codex from the original Claude Code draft.
Activity
[-]fix: Say when get-dataset-items pages past the end or no item has the requested fields[/-][+]fix: Explain empty dataset pages and field projections[/+]