Langertha-Knarr

 view release on metacpan or  search on metacpan

lib/Langertha/Knarr/CLI.pm  view on Meta::CPAN

package Langertha::Knarr::CLI;
# ABSTRACT: CLI entry point for Knarr LLM Proxy
use Moo;
use MooX::Cmd;
use MooX::Options protect_argv => 0;


our $VERSION = '1.103';

option config => (
  is      => 'ro',
  format  => 's',
  short   => 'c',
  doc     => 'Config file path (default: ./knarr.yaml)',
  default => sub { './knarr.yaml' },
);


option verbose => (
  is      => 'ro',
  short   => 'v',
  doc     => 'Enable verbose logging (or set KNARR_DEBUG=1)',
  default => sub { $ENV{KNARR_DEBUG} ? 1 : 0 },
  negativable => 1,
);


# MooX::Options maps a dashed long option (--log-file) to its underscore
# attribute (log_file), but its argv rewrite takes the token after a
# boolean flag as that flag's value and passes it through unmapped — so
# `--from-env --log-file X` reached Getopt::Long as `--log-file` and died
# with "Unknown option". Map every long option name up front; arguments
# not starting with `--` and everything after a bare `--` are left alone.
around new_with_cmd => sub {
  my ( $orig, $class, @args ) = @_;
  local @ARGV = $class->normalize_argv(@ARGV);
  return $class->$orig(@args);
};

sub normalize_argv {
  my ( $class, @argv ) = @_;
  my @out;
  while (@argv) {
    my $arg = shift @argv;
    if ( $arg eq '--' ) {
      push @out, $arg, @argv;
      last;
    }
    if ( my ( $neg, $name, $value ) = $arg =~ /\A--(no-)?([A-Za-z][A-Za-z0-9_-]*)(=.*)?\z/s ) {
      $name =~ tr/-/_/;
      $arg = '--'.( $neg // '' ).$name.( $value // '' );
    }
    push @out, $arg;
  }
  return @out;
}


sub execute {
  my ($self) = @_;
  print _banner();
  print "\n";
  print "USAGE\n";
  print "  knarr <command> [options]\n\n";
  print "COMMANDS\n";
  print "  start       Start the proxy server\n";
  print "  init        Scan environment and generate configuration\n";
  print "  models      List configured models and their backends\n";
  print "  check       Validate configuration file\n\n";
  print "GLOBAL OPTIONS\n";
  print "  -c, --config <path>   Config file (default: ./knarr.yaml)\n";
  print "  -v, --verbose         Enable verbose logging\n\n";
  print "QUICK START (Docker)\n";
  print "  docker run -e OPENAI_API_KEY=sk-... -p 8080:8080 raudssus/langertha-knarr\n\n";
  print "QUICK START (Local)\n";
  print "  knarr init > knarr.yaml\n";
  print "  knarr start\n\n";
  print "EXAMPLES\n";
  print "  knarr start                              # Start with ./knarr.yaml\n";
  print "  knarr start -c production.yaml -p 9090   # Custom config and port\n";
  print "  knarr start --from-env                   # Auto-detect from ENV\n";
  print "  knarr start --from-env -p 8080 -p 11434  # ENV config, custom ports\n";
  print "  knarr init > knarr.yaml                   # Generate config\n";
  print "  knarr models                              # List configured models\n";
  print "  knarr check                               # Validate config\n\n";
  print "ENVIRONMENT\n";
  print "  OPENAI_API_KEY        OpenAI API key\n";
  print "  ANTHROPIC_API_KEY     Anthropic API key\n";
  print "  LANGFUSE_PUBLIC_KEY   Langfuse public key (enables tracing)\n";
  print "  LANGFUSE_SECRET_KEY   Langfuse secret key\n";
  print "  LANGFUSE_URL          Langfuse URL (default: https://cloud.langfuse.com)\n";
  print "  KNARR_API_KEY         Proxy authentication key (optional)\n\n";
  print "Version $VERSION | https://github.com/Getty/langertha-knarr\n";
}

sub _banner {



( run in 1.230 second using v1.01-cache-2.11-cpan-145b269f2f3 )