Skip to content

feat: searchControls walkthrough in init and fix spurious diff noise#11

Merged
chuckmeyer merged 2 commits into
mainfrom
feat/improve-searchcontrols-support
May 27, 2026
Merged

feat: searchControls walkthrough in init and fix spurious diff noise#11
chuckmeyer merged 2 commits into
mainfrom
feat/improve-searchcontrols-support

Conversation

@chuckmeyer
Copy link
Copy Markdown
Contributor

Summary

  • algolia-agent init: adds an optional searchControls walkthrough after the replica prompts, covering all five supported fields (hitsPerPage, page, attributesToRetrieve, facets, responseFields) — each skippable by leaving blank
  • _diff(): fixes spurious changes on every dry-run caused by the API expanding searchControls with default fields (query, page, responseFields, etc.) that were never in the original config — now only compares keys present in the new payload
  • README: expands the searchControls field table to list all five fields and updates the init example to show the new prompts

Test plan

  • pytest tests/test_cli.py -k init — 13 tests including test_init_with_search_controls and test_init_skip_search_controls
  • pytest tests/test_cli.py -k diff — 5 tests including test_diff_no_false_positive_when_api_expands_search_controls and test_diff_detects_change_despite_api_expansion
  • pytest tests/test_cli.py — full suite (49 tests)

🤖 Generated with Claude Code

Add optional searchControls prompts to `algolia-agent init` covering all
five supported fields (hitsPerPage, page, attributesToRetrieve, facets,
responseFields). Fix `_diff()` to only compare keys present in the new
payload, ignoring API-expanded defaults that caused a spurious change on
every dry-run. Update README to document all searchControls fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the CLI’s init workflow by adding an optional interactive walkthrough for configuring searchControls, and adjusts _diff() to reduce dry-run noise caused by the API returning expanded/default searchControls fields. It also updates documentation and tests to reflect the new prompts and diff behavior.

Changes:

  • Add an optional searchControls prompt flow to algolia-agent init (supports hitsPerPage, page, attributesToRetrieve, facets, responseFields).
  • Update _diff() to compare only searchControls keys present in the new payload to avoid false-positive diffs from API-expanded defaults.
  • Update README examples and extend tests to cover the new init prompts and diff behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/algolia_agent/cli.py Adds searchControls init walkthrough and changes _diff() searchControls comparison to ignore API-added default keys.
tests/test_cli.py Updates init-input fixtures and adds tests for the searchControls init flow and expanded-API diff behavior.
README.md Documents the new init prompts and expands the searchControls field table.
Comments suppressed due to low confidence (1)

src/algolia_agent/cli.py:327

  • _diff() filters the current agent's searchControls down to new_sc_keys. When the new payload has an explicitly empty searchControls object (or omits it entirely), new_sc_keys becomes empty and curr_sc_map is forced to {} for every index. That makes _diff() unable to report a real change where an existing non-empty searchControls would be cleared/removed. Consider tracking presence separately (missing vs {} vs None) and/or comparing per-index key sets instead of a global union so empty payloads can still surface a change when appropriate.
    # Only compare keys present in the new payload — the API expands searchControls
    # with default fields (query, page, responseFields, etc.) that we never sent,
    # which would otherwise cause a spurious diff on every dry-run.
    new_sc_keys = {
        k
        for t in new_payload.get("tools", [])
        for i in t.get("indices", [])
        for k in (i.get("searchControls") or {})
    }
    curr_sc_map = {
        i["index"]: {k: v for k, v in (i.get("searchControls") or {}).items() if k in new_sc_keys}
        for t in current.get("tools", [])
        for i in t.get("indices", [])
    }
    new_sc_map = {
        i["index"]: (i.get("searchControls") or {})
        for t in new_payload.get("tools", [])
        for i in t.get("indices", [])
    }
    if curr_sc_map != new_sc_map:
        curr_repr = json.dumps(next(iter(curr_sc_map.values()), None))
        new_repr = json.dumps(next(iter(new_sc_map.values()), None))
        lines.append(f"  searchControls: {curr_repr} → {new_repr}")


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/algolia_agent/cli.py Outdated
Comment on lines +648 to +661
max_hits = _ask(" Cap hitsPerPage? Enter max (or leave blank to skip)")
if max_hits:
try:
n = int(max_hits)
search_controls["hitsPerPage"] = {"exposed": False, "default": n, "constraint": {"max": n}}
except ValueError:
pass
max_page = _ask(" Cap page? Enter max (or leave blank to skip)")
if max_page:
try:
n = int(max_page)
search_controls["page"] = {"exposed": False, "default": 0, "constraint": {"max": n}}
except ValueError:
pass
Comment thread tests/test_cli.py
Comment on lines +908 to +949
def test_diff_no_false_positive_when_api_expands_search_controls():
"""API-added fields (query, page, responseFields, etc.) do not cause a spurious diff."""
sc_config = {"hitsPerPage": {"exposed": False, "default": 10, "constraint": {"max": 10}}}
# The API returns this config plus extra default fields we never sent
sc_api = {
"hitsPerPage": {"exposed": False, "default": 10, "constraint": {"max": 10}},
"query": {"exposed": True, "default": None},
"page": {"exposed": True, "default": 0},
"responseFields": {"exposed": False, "default": None},
"facets": {"exposed": False, "default": None},
"custom": None,
}
current = {
"name": "My Agent", "model": "gemini-2.5-flash", "instructions": "Hello.",
"tools": [{"type": "algolia_search_index", "indices": [{"index": "products", "searchControls": sc_api}]}],
}
new_payload = {
"name": "My Agent", "model": "gemini-2.5-flash", "instructions": "Hello.",
"tools": [{"type": "algolia_search_index", "indices": [{"index": "products", "searchControls": sc_config}]}],
}
assert not _diff(current, new_payload)


def test_diff_detects_change_despite_api_expansion():
"""A real change to a config-specified field is still reported even when the API expanded the object."""
sc_api = {
"hitsPerPage": {"exposed": False, "default": 10, "constraint": {"max": 10}},
"query": {"exposed": True, "default": None},
"page": {"exposed": True, "default": 0},
}
sc_new = {"hitsPerPage": {"exposed": False, "default": 5, "constraint": {"max": 5}}}
current = {
"name": "My Agent", "model": "gemini-2.5-flash", "instructions": "Hello.",
"tools": [{"type": "algolia_search_index", "indices": [{"index": "products", "searchControls": sc_api}]}],
}
new_payload = {
"name": "My Agent", "model": "gemini-2.5-flash", "instructions": "Hello.",
"tools": [{"type": "algolia_search_index", "indices": [{"index": "products", "searchControls": sc_new}]}],
}
changes = _diff(current, new_payload)
assert len(changes) == 1
assert "searchControls" in changes[0]
… clearing

Re-prompt instead of silently dropping hitsPerPage/page caps when the user
enters a non-integer. Fix _diff() to detect when searchControls is explicitly
cleared (searchControls: {}) by bypassing key-filtering in that branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chuckmeyer chuckmeyer merged commit dc2fe57 into main May 27, 2026
3 checks passed
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.

2 participants