File Coverage

blib/lib/DWIM/Block.pm
Criterion Covered Total %
statement 14 19 73.6
branch 0 2 0.0
condition 0 10 0.0
subroutine 5 6 83.3
pod n/a
total 19 37 51.3


line stmt bran cond sub pod time code
1             package DWIM::Block;
2              
3 2     2   547487 use 5.022;
  2         10  
4 2     2   12 use warnings;
  2         7  
  2         129  
5 2     2   1244 use Filter::Simple;
  2         40442  
  2         55  
6 2     2   2915 use PPR::X;
  2         181230  
  2         174  
7 2     2   1278 use AI::Chat;
  2         162403  
  2         981  
8              
9             # Look for DWIM {...} blocks in any source that loads this module...
10             FILTER {
11             my %dwim;
12              
13             # This is what code with embedded DWIM blocks looks like...
14             my $PERL_WITH_DWIM_BLOCKS = qr{
15             (?&PerlEntireDocument)
16              
17             (?(DEFINE)
18             (?
19             DWIM \b (?{ pos() - 4 }) (?>(?&PerlOWS))
20             (? \{ (?>(?&PPR_X_balanced_curlies_interpolated)) \} )
21             (?{ $dwim{ $^R } = { block => 1, len => pos() - $^R, request => $+{REQUEST} } })
22             |
23             (?>(?&PerlStdControlBlock))
24             )
25              
26             (?
27             DWIM \b (?{ pos() - 4 }) (?>(?&PerlOWS))
28             (? \{ (?>(?&PPR_X_balanced_curlies_interpolated)) \} )
29             (?{ $dwim{ $^R } = { len => pos() - $^R, request => $+{REQUEST} } })
30             |
31             (?>(?&PerlStdCall))
32             )
33             )
34              
35             $PPR::X::GRAMMAR
36             }xms;
37              
38             # If we find DWIM blocks...
39             if (/$PERL_WITH_DWIM_BLOCKS/) {
40             # Work backwards from the end of the source (so the replacements don't mess up pos info)...
41             for my $pos (sort {$b <=> $a} keys %dwim) {
42              
43             # Generate the replacement code...
44             my $code = "do { DWIM::Block::_DWIM( qq$dwim{$pos}{request}) }";
45              
46             # Substitute the replacement code into the source...
47             substr($_, $pos, $dwim{$pos}{len}) = $dwim{$pos}{block} ? "{$code}" : $code;
48             }
49             }
50             }
51              
52             our $VERSION = '0.000002';
53              
54             # This sub relays each request to the API and returns the result...
55             sub _DWIM {
56 0     0     my ($request) = @_;
57              
58             # Discover and remember the API key...
59             state $API_KEY = $ENV{'DWIM_API_KEY'}
60 0   0       // $ENV{'OPENAI_API_KEY'}
      0        
61             // die sprintf qq{Can't find API key at %s line %d\n}, (caller 0)[1,2];
62              
63             # Discover and remember the requested model...
64             state $MODEL = $ENV{'DWIM_MODEL'}
65 0   0       // $ENV{'OPENAI_MODEL'}
      0        
66             // q{};
67              
68             # Build and retain an API object...
69 0 0         state $GPT = AI::Chat->new( key => $API_KEY, $MODEL ? ( model => $MODEL ) : () );
70              
71             # Send the request and return the response...
72 0           return $GPT->prompt($request);
73             }
74              
75              
76             1; # Magic true value required at end of module
77             __END__