File Coverage

blib/lib/App/Greple/xlate/gpt3.pm
Criterion Covered Total %
statement 26 70 37.1
branch 0 16 0.0
condition 0 12 0.0
subroutine 9 14 64.2
pod 0 4 0.0
total 35 116 30.1


line stmt bran cond sub pod time code
1             package App::Greple::xlate::gpt3;
2              
3             our $VERSION = "1.01";
4              
5 1     1   1497 use v5.14;
  1         4  
6 1     1   7 use warnings;
  1         2  
  1         56  
7 1     1   6 use utf8;
  1         3  
  1         7  
8 1     1   31 use Encode;
  1         2  
  1         120  
9 1     1   7 use Data::Dumper;
  1         2  
  1         77  
10              
11 1     1   7 use List::Util qw(sum);
  1         2  
  1         78  
12 1     1   7 use Command::Run;
  1         2  
  1         45  
13              
14 1     1   6 use App::Greple::xlate qw(opt);
  1         2  
  1         95  
15 1     1   6 use App::Greple::xlate::Lang qw(%LANGNAME);
  1         53  
  1         1515  
16              
17             our $lang_from //= 'ORIGINAL';
18             our $lang_to //= 'JA';
19             our $auth_key;
20             our $method = __PACKAGE__ =~ s/.*://r;
21              
22             my %param = (
23             gpt3 => { engine => 'gpt-3.5-turbo', temp => '0.0', max => 3000, sub => \&gpty,
24             prompt => 'Translate following entire text into %s, line-by-line.',
25             },
26             gpt4 => { engine => 'gpt-4-1106-preview', temp => '0.0', max => 3000, sub => \&gpty,
27             prompt => 'Translate following entire text into %s, line-by-line.',
28             },
29             );
30              
31             sub initialize {
32 0     0 0   my($mod, $argv) = @_;
33 0           $mod->setopt(default => "-Mxlate --xlate-engine=$method");
34             }
35              
36             sub gpty {
37 0     0 0   state $gpty = Command::Run->new;
38 0           my $text = shift;
39 0           my $param = $param{$method};
40 0   0       my $prompt = opt('prompt') || $param->{prompt};
41 0           my @vars = do {
42 0 0         if ($prompt =~ /%s/) {
43 0   0       $LANGNAME{$lang_to} // die "$lang_to: unknown lang.\n"
44             } else {
45 0           ();
46             }
47             };
48 0           my $system = sprintf($prompt, @vars);
49             my @command = (
50             'gpty',
51             -e => $param->{engine},
52             -t => $param->{temp},
53 0           -s => $system,
54             '-',
55             );
56 0 0         warn Dumper \@command if opt('debug');
57 0           $gpty->command(@command)->with(stdin => $text)->update->data;
58             }
59              
60             sub _progress {
61 0 0   0     print STDERR @_ if opt('progress');
62             }
63              
64             sub xlate_each {
65 0   0 0 0   my $call = $param{$method}->{sub} // die;
66 0           my @count = map { int tr/\n/\n/ } @_;
  0            
67 0           _progress("From:\n", map s/^/\t< /mgr, @_);
68 0           my $to = $call->(join '', @_);
69 0           my @out = $to =~ /^.+\n/mg;
70 0           _progress("To:\n", map s/^/\t> /mgr, @out);
71 0 0         if (@out < sum @count) {
72 0           die "Unexpected response:\n\n$to\n";
73             }
74 0           map { join '', splice @out, 0, $_ } @count;
  0            
75             }
76              
77             sub xlate {
78 0 0   0 0   my @from = map { /\n\z/ ? $_ : "$_\n" } @_;
  0            
79 0           my @to;
80 0   0       my $max = $App::Greple::xlate::max_length || $param{$method}->{max} // die;
      0        
81 0 0         if (my @len = grep { $_ > $max } map length, @from) {
  0            
82 0           die "Contain lines longer than max length (@len > $max).\n";
83             }
84 0           while (@from) {
85 0           my @tmp;
86 0           my $len = 0;
87 0           while (@from) {
88 0           my $next = length $from[0];
89 0 0         last if $len + $next > $max;
90 0           $len += $next;
91 0           push @tmp, shift @from;
92             }
93 0 0         @tmp > 0 or die "Probably text is longer than max length ($max).\n";
94 0           push @to, xlate_each @tmp;
95             }
96 0           @to;
97             }
98              
99             1;
100              
101             __DATA__