Skip to content

feat(wizard): support context-aware wizard default suggestions in Opt… - #307

Open
Adityakk9031 wants to merge 1 commit into
robocurve:mainfrom
Adityakk9031:feature/303-context-aware-wizard-suggestions
Open

feat(wizard): support context-aware wizard default suggestions in Opt…#307
Adityakk9031 wants to merge 1 commit into
robocurve:mainfrom
Adityakk9031:feature/303-context-aware-wizard-suggestions

Conversation

@Adityakk9031

Copy link
Copy Markdown
Contributor

Summary

Resolves #303.

This PR updates the embodiment setup wizard's OptionSlot schema to support context-aware default suggestions. Instead of relying solely on a static fallback boolean when a configuration key is absent, an embodiment plugin can now provide a dynamic suggest callback:

suggest: Callable[[Mapping[str, str]], bool] | None = None

This enables plugins (such as inspect-robots-yaml) to recommend sensible defaults based on the existing configuration. For example, a plugin can automatically suggest enabling collision_guardrail when collision_left/right_base_pos is already configured in [embodiment.args].

Changes

  • conformance.py

    • Added a suggest callback field to the OptionSlot dataclass.
  • _setup.py

    • Updated _options_section to invoke suggest, passing the current [embodiment.args] mapping.
    • Explicit configuration values continue to take highest precedence over suggested defaults.
  • test_setup.py / test_conformance.py

    • Added tests verifying that:
      • Context-aware suggestions are applied when appropriate.
      • Static fallback behavior is preserved when no context is available.
      • Explicitly configured values override suggested defaults.
  • CHANGELOG.md

    • Documented support for context-aware suggestion callbacks.

Verification

Ran the setup and conformance test suites successfully:

python -m pytest tests/test_conformance.py tests/test_setup.py -o pythonpath=src

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@jeqcho have a look

@jeqcho jeqcho left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for picking this up, @Adityakk9031 — this lands exactly the shape proposed in #303, and the implementation gets the important things right: the suggest result is computed before the carried-value check, so an explicit stored bool keeps top precedence, and the three tests in tests/test_setup.py (no-context fallback, context-aware flip to [Y/n], explicit-config override) cover the precedence matrix nicely, including asserting on the rendered prompt suffix. Good call amending the existing unreleased OptionSlot changelog bullet rather than adding a new one.

A few things before this is ready to merge:

  1. Plugin-facing docs are missingdocs/guide/adapters.md (the OPTION_SLOTS section, ~lines 103–117) documents the plugin contract that this PR extends, but it isn't updated. Since suggest is exactly the kind of thing an adapter author discovers through that guide, please add a short mention (signature plus a one-line example, e.g. the collision_guardrail-from-geometry case from the issue).

  2. OptionSlot docstring not updated — the class docstring in src/inspect_robots/conformance.py describes each field (arg, label, default) but says nothing about suggest. A sentence noting it computes the suggestion from the carried [embodiment.args] and that its failures/absence fall back to default would keep the dataclass self-documenting, matching the style used elsewhere in this module.

  3. Non-bool returns from suggest flow through unvalidated — in _options_section (src/inspect_robots/_setup.py), contextlib.suppress(Exception) guards against a raising callback (good, and consistent with this codebase's "a plugin bug must never crash the wizard" posture), but a callback returning a non-bool (say the string "false", which is truthy) is assigned to suggested as-is and drives _ask_yes_no via truthiness — Enter would then write the wrong value. The sibling carried-value branch right below already guards with isinstance(parsed, bool), and option_slots / missing_runtime_requirements both type-filter plugin data the same way. Suggest mirroring that:

    if option.suggest is not None:
        try:
            computed = option.suggest(existing_args)
        except Exception:
            computed = None
        if isinstance(computed, bool):
            suggested = computed

    As a small optional hardening while you're there: existing_args is the live carried dict, so a buggy callback could mutate it; wrapping it in types.MappingProxyType (the declared type is already read-only Mapping[str, str]) would close that off cheaply.

None of these touch the core design, which looks right. Happy to re-review once the docs and the bool guard are in — thanks again for the clean tests!

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.

OPTION_SLOTS: context-aware wizard suggestions (plugin sees the carried config when suggesting a default)

2 participants