App-PythonToPerl
view release on metacpan or search on metacpan
lib/Python/Unknown.pm view on Meta::CPAN
my string::arrayref $stop_sequences = ['# Python to', 'Python:'];
# DEV NOTE: shorten error sequences to speed up matching and allow for new or different wording
my string::arrayref $error_sequences = [
'Sorry, ',
# 'Sorry, as an AI language model, I cannot see any Python source code to translate. Can you please provide the code so I can assist you better?',
# 'Sorry, I cannot perform this task as the provided Python source code is incomplete and does not provide enough information to be translated accurately. Please provide the complete code.',
];
# assemble "Python to Perl" message strings
my string::hashref::arrayref $messages = [
# DEV NOTE: save money by transmitting fewer tokens!
# { 'role' => 'system', 'content' => 'You are a helpful assistant with detailed knowledge of the Perl and Python computer programming languages, as well as modern software development best practices.' },
# { 'role' => 'user', 'content' => 'Translate the following Python source code to Perl:' . "\n" . $self->{python_source_code} . "\n" },
{ 'role' => 'user', 'content' => 'Translate this Python to Perl:' . "\n" . $self->{python_source_code} . "\n" },
];
print 'in Python::Unknown::python_preparsed_to_perl_source(), have $self->{python_source_code} =', "\n", $self->{python_source_code}, "\n";
print 'in Python::Unknown::python_preparsed_to_perl_source(), about to call python_preparsed_to_perl_source_api_call()...', "\n";
# call OpenAI API
my hashref $response = $self->python_preparsed_to_perl_source_api_call($openai, $stop_sequences, $messages);
print 'in Python::Unknown::python_preparsed_to_perl_source(), ret from call to python_preparsed_to_perl_source_api_call()', "\n";
#print 'in Python::Unknown::python_preparsed_to_perl_source(), received $response = ', Dumper($response), "\n";
#die 'TMP DEBUG, UNKNOWN';
# [[[ BEGIN FAILED API CALLS ]]]
# [[[ BEGIN FAILED API CALLS ]]]
# [[[ BEGIN FAILED API CALLS ]]]
# handle HTTP response status codes returned from LWP::UserAgent
if ((defined $EVAL_ERROR) and ($EVAL_ERROR ne '')) {
# NEED UPGRADE: accept any error code and just retry???
# NEED UPGRADE: accept any error code and just retry???
# NEED UPGRADE: accept any error code and just retry???
print 'in Python::Unknown::python_preparsed_to_perl_source(), received $EVAL_ERROR = \'', $EVAL_ERROR, '\'', "\n";
# Error retrieving 'completions': 400 Bad Request
if ($EVAL_ERROR =~ '400 Bad Request') {
croak 'ERROR EPYUN013a: received HTTP response status code 400 (bad request) instead of OpenAI::API response, croaking', "\n", $EVAL_ERROR, "\n";
}
# Error retrieving 'completions': 429 Too Many Requests
elsif ($EVAL_ERROR =~ '429 Too Many Requests') {
carp 'WARNING WPYUN013b: received HTTP response status code 429 (too many requests) instead of OpenAI::API response, carping', "\n", $EVAL_ERROR, "\n";
my integer $retries = 0;
# backoff algorithm; increase sleep time and retry
# https://help.openai.com/en/articles/5955604-how-can-i-solve-429-too-many-requests-errors
# https://platform.openai.com/docs/guides/rate-limits/error-mitigation
while ((defined $EVAL_ERROR) and ($EVAL_ERROR =~ '429 Too Many Requests')) {
print 'in Python::Unknown::python_preparsed_to_perl_source(), about to retry #', $retries, ' call python_preparsed_to_perl_source_api_call()...', "\n";
$retries++;
if ($retries >= $self->{retries_max}) {
croak 'ERROR EPYUN013b: received HTTP response status code 429 (too many requests) instead of OpenAI::API response, maximum retry limit ', $self->{retries_max}, ' reached, croaking';
}
# increase time to sleep by some percentage of current amount
$self->{sleep_seconds} *= $self->{sleep_retry_multiplier};
print 'in Python::Unknown::python_preparsed_to_perl_source(), about to retry #', $retries, ' call sleep(', $self->{sleep_seconds}, ')...', "\n";
# retry sleep before calling API
sleep($self->{sleep_seconds});
print 'in Python::Unknown::python_preparsed_to_perl_source(), ret from retry #', $retries, ' call to sleep(', $self->{sleep_seconds}, ')', "\n";
# retry call to OpenAI API
$response = $self->python_preparsed_to_perl_source_api_call($openai, $messages);
print 'in Python::Unknown::python_preparsed_to_perl_source(), ret from retry #', $retries, ' call to python_preparsed_to_perl_source_api_call()', "\n";
#print 'in Python::Unknown::python_preparsed_to_perl_source(), received $response = ', Dumper($response), "\n";
#die 'TMP DEBUG, UNKNOWN 429 TOO MANY REQUESTS';
}
}
# Error retrieving 'completions': 500 read timeout
elsif ($EVAL_ERROR =~ '500 read timeout') {
croak 'ERROR EPYUN013c: received HTTP response status code 500 (read timeout) instead of OpenAI::API response, croaking', "\n", $EVAL_ERROR, "\n";
# NEED SLEEP AND RETRY?
# NEED SLEEP AND RETRY?
# NEED SLEEP AND RETRY?
}
else {
croak 'ERROR EPYUN013d: received unrecognized HTTP response status code instead of OpenAI::API response, croaking', "\n", $EVAL_ERROR, "\n";
}
}
print 'in Python::Unknown::python_preparsed_to_perl_source(), ret from call to OpenAI completions(), received $response =', "\n", Dumper($response), "\n";
# DEV NOTE: sometimes the API returns an undefined or empty finish_reason, but still with valid 'text' field;
# carp & return dummy code if translation ends for any other reason than reaching a legitimate 'stop' condition
if (not defined $response) {
croak 'ERROR EPYUN014a: received undefined OpenAI::API response, croaking';
}
elsif ((not exists $response->{choices}) or (not defined $response->{choices}) or
(not defined $response->{choices}->[0])) {
croak 'ERROR EPYUN014b: received non-existent or undefined OpenAI::API response choice, croaking';
}
else {
# response choice is defined, check finish_reason and text
if ((not exists $response->{choices}->[0]->{finish_reason}) or (not defined $response->{choices}->[0]->{finish_reason})) {
carp 'WARNING WPYUN015a: received non-existent or undefined OpenAI::API response finish_reason, carping';
}
elsif ($response->{choices}->[0]->{finish_reason} ne 'stop') {
carp 'WARNING WPYUN015b: received OpenAI::API response finish_reason \'', $response->{choices}->[0]->{finish_reason}, '\', expected \'stop\', carping';
}
if ((not exists $response->{choices}->[0]->{message}) or (not defined $response->{choices}->[0]->{message})) {
croak 'ERROR EPYUN016a: received non-existent or undefined OpenAI::API response message, croaking';
}
elsif ((not exists $response->{choices}->[0]->{message}->{content}) or (not defined $response->{choices}->[0]->{message}->{content})) {
croak 'ERROR EPYUN016b: received non-existent or undefined OpenAI::API response message content, croaking';
}
else {
# retrieve Perl source code out of valid response choice
$self->{perl_source_code} = $response->{choices}->[0]->{message}->{content};
}
}
# translated Perl code must not start with any stop sequence,
( run in 2.196 seconds using v1.01-cache-2.11-cpan-13bb782fe5a )