Skip to content

rust(fix): keep unmatched fields visible when list output is truncated - #847

Draft
alexa-sift wants to merge 1 commit into
mainfrom
rust/unmatched-fields-before-items
Draft

alexa-sift wants to merge 1 commit into
mainfrom
rust/unmatched-fields-before-items

Conversation

@alexa-sift

@alexa-sift alexa-sift commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Every list_* MCP tool builds its response through list_body. A caller can pass fields: ["name", "asset_id"] to keep only those keys on each row. If a requested name matches nothing on any row (a typo like nmae), list_body adds unmatched_fields: ["nmae"]. Without that key, a typo would quietly return rows with that field missing, and the agent could report the data as empty when the field name was wrong. unmatched_fields lets the agent catch the mistake and retry, or at least tell the user.

The problem: serde_json sorts keys alphabetically, so unmatched_fields comes after the items array. The agent output guard cuts large responses from the end, so the warning disappears on exactly the big responses where it matters most.

To resolve this, this PR renames the list tools' unmatched_fields key to _unmatched_fields so it sorts ahead of the items and survives head truncation of large responses. We also, document the key in each list tool's Output section and add tests for the ordering and the descriptions.

Verification

Automated (run locally on d64a0d7f9):

  • cargo test -p sift_mcp: 602 passed.
  • cargo fmt --all -- --check: clean.
  • cargo clippy -p sift_mcp --all-targets --all-features: no new warnings (the 7 existing ones are in untouched files).
  • New tests:
    • list_body_writes_unmatched_fields_before_the_items: the warning is serialized ahead of the items for all 14 list keys.
    • list_body_unmatched_fields_survive_head_truncation: a 500-row body keeps the warning in its first 200 characters.
    • every_fields_tool_documents_unmatched_fields: every tool that accepts fields names _unmatched_fields in its fields bullet and Output section, and never the old key.
  • Confirmed the tests catch regressions: with the key set back to unmatched_fields, the ordering, truncation, and existing projection tests fail; with one description set back, the docs guard flags list_runs.

Manual (dev org, local sift-cli build):

  • Raw MCP output: list_channels with a mistyped field returns text starting with {"_unmatched_fields":[...].
  • Correct field names: no _unmatched_fields key in the response.
  • Agent behavior: Sift Agent on local kind, with the agents image built from this branch's sift-cli, sees _unmatched_fields after a mistyped field (including on a large, truncated listing) and retries with the correct name.

Rename the list tools' unmatched_fields key to _unmatched_fields so it
sorts ahead of the items and survives head truncation of large
responses. Document the key in each list tool's Output section and add
tests for the ordering and the descriptions.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant