Skip to content

FIX: Only advertise converter_target when the converter declares it - #3382

Open
Chen Yufeiyang (feiiiiii5) wants to merge 2 commits into
microsoft:mainfrom
feiiiiii5:fix/converter-target-seam
Open

Chen Yufeiyang (feiiiiii5) wants to merge 2 commits into
microsoft:mainfrom
feiiiiii5:fix/converter-target-seam

Conversation

@feiiiiii5

Copy link
Copy Markdown
Contributor

Description

Fixes #3341.

Clearing (or leaving at the placeholder) the converter_target select for a converter like ArabiziConverter failed with ArabiziConverter.converter_target: '' not found in DefaultInstanceRegistry … — an error that neither matches the converter's actual contract nor tells the user what to do.

Two root causes:

  • A phantom target in the derived contract. ConverterIdentifier promotes every constructor parameter named converter_target to a TARGET reference. Eight converters only inherit Converter.__init__'s converter_target=None — a seam the base validates and discards so subclasses can forward a target to super().__init__() — yet the derived contract advertised a target for them, including the LLM badge projected from it: ArabiziConverter, ArabicPresentationFormConverter, BrailleConverter, CharacterSpaceConverter, FlipConverter, JsonStringConverter, UrlConverter, ZeroWidthConverter.
  • An empty selection resolved as a registry name. A cleared field sends converter_target: "", and resolve_constructor_args looked "" up as a registry name.

The fix, along the lines Richard Lundeen (@richlundeen) described in #3038 ("a separate check of the converter's constructor requirements and registry metadata, plus a clearer validation error"):

  • derive_parameters gains seam_base_type: a non-required reference declared by that base is a construction seam, excluded from a subclass's contract unless the subclass redeclares it. Required base references and class-declared optional ones stay. Registry._seam_base_type() defaults to None, and only ConverterRegistry opts in — deliberately per-registry, since for example the Scorer base also declares an optional chat_target that is not a seam.
  • resolve_constructor_args treats an empty-string reference value as an unsupplied selection: the constructor default applies (including apply_defaults-registered defaults, the FEAT: Default converter targets to the adversarial target #3038 feature) instead of an empty-name lookup.

Metadata and creation derive through the same path, so the advertised contract and the build contract cannot drift.

scenario base 85d4f0c3 head 8f3b1a21
ArabiziConverter metadata target param + LLM badge no target param, is_llm_based=False
ArabiziConverter + converter_target="" '' not found in DefaultInstanceRegistry Unknown parameter 'converter_target' for 'ArabiziConverter'
PuzzledConverter + converter_target="" '' not found … builds; _converter_target is None
TranslationConverter + converter_target="" '' not found … converter_target is required for TranslationConverter …

Related: #3038 (merged) added default-target behavior for genuinely LLM-backed converters; this fixes the different seam path that made eight non-LLM converters advertise a target at all.

Tests and Documentation

15 new unit tests in tests/unit/registry/ cover the seam exclusion (optional base reference dropped; required and subclass-redeclared references kept), the metadata of the eight converters, the class-declared targets staying advertised, an invariant that no advertised target comes from the base seam, and the create paths above. Verified red at base where applicable: the seam tests fail without seam_base_type, and each cleared-target build fails on base with the registry-lookup error.

tests/unit/registry + tests/unit/converter: identical 53 pre-existing environment failures on base and head; 3414 → 3429 passing. tests/unit/backend: identical outcomes base/head (2736 passing). ruff 0.17.0 check/format clean. No documentation change applies; the dialog renders whatever the registry publishes, so the field and badge disappear structurally.

Environment notes for the runs above
  • The 53 pre-existing failures are pinyin/seeded-determinism tests needing model/data deps absent from my environment; base and head failure sets were compared item by item.
  • tests/unit/registry/test_attack_technique_registry.py does not collect locally (no pyrit distribution metadata) on base either; excluded from both runs.
  • JupyText/docs-build were not run locally.

…icrosoft#3341)

Converter.__init__ accepts converter_target only so subclasses can forward a
target to it for validation. Eight converters inherit that parameter without
declaring it, so the derived contract (and the registry UI, including the
LLM badge projected from it) claimed a target input they do not have, and a
cleared target selection was resolved as a registry name and failed with an
empty-name not-found error.

- derive_parameters gains seam_base_type: a non-required reference the base
  declares is excluded from a subclass's contract unless the subclass
  redeclares it; required base references and class-declared optional ones
  are kept. ConverterRegistry opts in; other registries are unchanged.
- resolve_constructor_args treats an empty-string reference value as a
  cleared selection: the constructor default (or an apply_defaults-registered
  default) applies instead of an empty-name lookup.

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.

BUG: Creating new registered target without target fails with unspecified error

1 participant