App-Greple-xlate

 view release on metacpan or  search on metacpan

lib/App/Greple/xlate/llm.pm  view on Meta::CPAN

        push @command, '-o', @$kv;
    }
    push @command, '--no-stream', '--no-log';
    @command;
}

sub _llm_in_path {
    grep { -x "$_/llm" } split /:/, $ENV{PATH} // '';
}

sub _not_found {
    "llm: command not found.\n" .
    "Install llm <https://llm.datasette.io/> with " .
    "\"pip install llm\" or \"pipx install llm\".\n";
}

sub run_llm {
    state $run = Command::Run->new;
    my($param, $text) = @_;
    ##
    ## Check PATH before forking: Command::Run's forked child has no
    ## exit guard after a failed exec, so reaching that path would let
    ## the child escape into the caller's code.
    ##
    _llm_in_path() or die _not_found();
    my @command = llm_command($param, build_system($param));
    warn Dumper \@command if opt('debug');
    my $result = $run->command(@command)
                     ->run(stdin => $text, stderr => 'capture');
    if ($result->{result} != 0) {
        die diagnose($param, $result);
    }
    print STDERR $result->{error} if $result->{error};
    $result->{data};
}

##
## Called when the llm command fails: figure out why and return a
## message useful to the user.
##
sub diagnose {
    my($param, $result) = @_;
    my $stderr = $result->{error} // '';
    if (! _llm_in_path()) {
        return _not_found();
    }
    my $model = $param->{model};
    my $models = Command::Run->new->command('llm', 'models')
        ->run(stderr => 'capture')->{data} // '';
    if ($models !~ /\Q$model\E/) {
        return "llm does not know model \"$model\".\n" .
               "Upgrade llm (\"pip install -U llm\") or register the model " .
               "in extra-openai-models.yaml.\n" .
               ($stderr ? "\n$stderr" : "");
    }



( run in 1.273 second using v1.01-cache-2.11-cpan-9581c071862 )