Perl 6 multi methods never match expected signature

I see two issues.

One is that you have two methods that are identical except for the name of one named parameter.

Named parameters can have aliases:

#                       V--------------V
multi method submit(Str :name(:$message)!, MODEL :@models = TOXICITY) {
    my $score = $perspective-api.analyze(:@models, :comment($message));
    say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
}

Note that :$message is really short for :message($message)


Now on the problem which actually prevents your code from working.

@models is a Positional, but you are assigning it a singular value in the signature.

Assign it a Positional, and it works:
(In this case it has to be of type Array[MODEL] because of the MODEL type declaration.)

#                                                           V---------------------V
multi method submit(Str :name(:$message)!, MODEL :@models = Array[MODEL](TOXICITY,)) {
    my $score = $perspective-api.analyze(:@models, :comment($message));
    say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
}

Multiple dispatch works in two phases:

  • Considering the number of positional parameters and their types
  • If there are any where clauses, named parameters, or sub-signatures, doing a test bind of the signature to see if it would match

The second phase will reject the candidate if it fails to bind for any reason. One such reason, and I believe the cause of the issue here, is that the default value is wrongly typed. For example, in:

multi m(:@x = "not-an-array") { }
m()

We get an error:

Cannot resolve caller m(...); none of these signatures match:
    (:@x = "not-an-array")
  in block <unit> at -e line 1

But changing it to:

multi m(:@x = ["an-array"]) { }
m()

Works fine. (Note that while a default value uses =, it's actually a binding, not an assignment.)

In the case in the question there's this:

MODEL :@models = TOXICITY

Looking at the module source the code is taken from, I see:

enum MODEL is export (
        <TOXICITY SEVERE_TOXICITY TOXICITY_FAST IDENTITY_ATTACK
        INSULT PROFANITY SEXUALLY_EXPLICIT THREAT FLIRTATION
        ATTACK_ON_AUTHOR ATTACK_ON_COMMENTER INCOHERENT INFLAMMATORY
        LIKELY_TO_REJECT OBSCENE SPAM UNSUBSTANTIAL>
);

Thus TOXICITY is just an Int, but what's expected is a typed array of MODEL values.

Thus, if you do this:

multi method submit(Str :$message!, MODEL :@models = Array[MODEL](TOXICITY)) {

It should work.