Skip to content

[Feature] Make it.contextType() discoverable to the AI rule agent (avoid respondsTo() in generated rules) #756

Description

@tangcent

Is your feature request related to a problem? Please describe.

When the AI rule-authoring assistant generates custom-framework rules (a Dubbo provider project in this case), it discriminates between class-context and method-context evaluation with Groovy meta-programming instead of the built-in discriminator:

// from the generated custom.method.is.api / custom.http.method / custom.path rules
def isMethod = !it.respondsTo('containingClass').isEmpty()
if (!isMethod) {
    return it.hasAnn('org.apache.dubbo.config.annotation.DubboService')
    // ...
}

The rules work at runtime — Groovy MOP respondsTo('containingClass') returns a non-empty list on method contexts and an empty list on class contexts — but the pattern is non-idiomatic and fragile: it encodes the implicit assumption "only method contexts expose containingClass()" rather than asking the context what it is.

Root cause (traced in source): the official discriminator exists but is invisible to the model.

  • ScriptItContext.contextType() returns "class" / "method" / "field" / "param", and built-in extension config already relies on it (jackson.config: if(it.contextType()!="field")).
  • RuleScriptContextCatalog.objectApi() reflects context methods into ScriptMethodApi, which carries only name/returns/parameters — no description. So the model sees a bare contextType(): String signature buried among 100+ methods in a ~32KB JSON payload.
  • The agent system prompt (agent-base.md) documents containingClass() / defineClass() in detail with examples — but never mentions contextType(). Neither do the knowledge-base docs.
  • No agent tool surfaces built-in extension scripts (e.g. jackson.config) as working examples.
  • Meanwhile get_rule_context reports itKinds = [METHOD, CLASS] for custom.method.is.api / custom.http.method / custom.path, with the binding description "Its concrete type depends on this rule key" — the contract requires the model to discriminate the context kind but never says how.
  • RuleProposalValidator has no warning for respondsTo( usage.

So when the model must answer "is it a class or a method right now?", it combines the most salient method-only API in its context (containingClass()) with the Groovy MOP idiom from its training data. Notably, this happens even when the agent follows the recommended workflow — the logs show it called get_rule_context for all three keys before proposing.

Describe the solution you'd like

  1. Highest value / one-line change: in RuleScriptContextCatalog, when a key's itKinds contains more than one kind, make the it binding description state the discriminator explicitly — e.g. "Discriminate with it.contextType() — returns 'class'/'method'/'field'/'param'."
  2. Document contextType() in the agent-base.md "Class identity in Groovy is context-sensitive" section.
  3. Add a soft warning in RuleProposalValidator when a proposal uses respondsTo(, suggesting contextType().
  4. Longer term: give ScriptMethodApi a description field (or a curated override for key methods), and/or expose built-in extension scripts as few-shot examples via an agent tool.

Describe alternatives you've considered

  • Do nothing: generated rules are functionally correct today, but the respondsTo heuristic breaks silently if a class context ever grows a method named containingClass(), and the generated files are harder for users to read and maintain.
  • Hard-reject respondsTo( in the validator: too strict while nothing teaches the model the alternative.

Additional context

  • Reproduction: run the AI rule assistant against a project whose framework is not built-in (custom class.is.api / method.is.api / path rules requiring class-vs-method discrimination).
  • Verified on current main (v3.0 rewrite); the generated rules were functionally correct — the issue is the idiom/robustness of AI output, not a runtime failure.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions