AI-Embedding
view release on metacpan or search on metacpan
0.1_3 8th June 2023
NOTE - This is still a development release - DO NOT USE IN PRODUCTION
Changed the implementation of the 'comparator' method so it can be used multiple times
Corrected typos in POD
Updated POD to reflect changes
Added new tests to test updated 'camparator' method
0.1_2 2nd June 2023
NOTE - This is still a development release - DO NOT USE IN PRODUCTION
Added 'test_embedding' method to allow code testing without calling the chargable API
Corrected authentication issues with OpenAI
Corrected issues causing CPAN Tests to fail
0.1_1 30th May 2023
First development version, released on an unsuspecting world.
Changes
lib/AI/Embedding.pm
Makefile.PL
MANIFEST This list of files
README
t/00-load.t
t/01-openai.t
t/02-test.t
t/manifest.t
t/pod-coverage.t
t/pod.t
t/version.t
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
}
},
"runtime" : {
"requires" : {
"Data::CosineSimilarity" : "0.02",
"HTTP::Tiny" : "0.014",
"JSON::PP" : "2.00",
"perl" : "5.010"
}
},
"test" : {
"requires" : {
"Test::More" : "0"
}
}
},
"release_status" : "stable",
"version" : "1.11",
"x_serialization_backend" : "JSON::PP version 4.06"
}
Makefile.PL view on Meta::CPAN
'JSON::PP' => '2.00',
'HTTP::Tiny' => '0.014',
'Data::CosineSimilarity' => '0.02',
},
dist => { COMPRESS => q{perl -MIO::Compress::Gzip=gzip,:constants -e"my $$in = $$ARGV[0]; gzip($$in => qq($$in.gz), q(Level) => Z_BEST_COMPRESSION, q(BinModeIn) => 1) or die q(gzip failed); unlink $$in;"}, SUFFIX => 'gz', },
clean => { FILES => 'AI-Embedding-*' },
);
# Compatibility with old versions of ExtUtils::MakeMaker
unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires;
}
unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires;
}
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
delete $WriteMakefileArgs{MIN_PERL_VERSION}
to provide version information here so that people can decide whether
fixes for the module are worth downloading.
INSTALLATION
To install this module, run the following commands:
perl Makefile.PL
make
make test
make install
SUPPORT AND DOCUMENTATION
After installing, you can find documentation for this module with the
perldoc command.
perldoc AI::Embedding
You can also look for information at:
lib/AI/Embedding.pm view on Meta::CPAN
if ($response->{'content'} =~ 'invalid_api_key') {
die 'Incorrect API Key - check your API Key is correct';
}
return $response;
}
# TODO:
# Make 'headers' use $header{$self->{'api'}}
# Currently hard coded to OpenAI
# Added purely for testing - IGNORE!
sub _test {
my $self = shift;
# return $self->{'api'};
return $header{$self->{'api'}};
}
# Return Embedding as a CSV string
sub embedding {
my ($self, $text, $verbose) = @_;
my $response = $self->_get_embedding($text);
lib/AI/Embedding.pm view on Meta::CPAN
if ($response->{'success'}) {
my $embedding = decode_json($response->{'content'});
return @{$embedding->{'data'}[0]->{'embedding'}};
}
$self->{'error'} = 'HTTP Error - ' . $response->{'reason'};
return $response if defined $verbose;
return undef;
}
# Return Test Embedding
sub test_embedding {
my ($self, $text, $dimension) = @_;
$self->{'error'} = '';
$dimension = 1536 unless defined $dimension;
if ($text) {
srand scalar split /\s+/, $text;
}
my @vector;
lib/AI/Embedding.pm view on Meta::CPAN
=head1 SYNOPSIS
use AI::Embedding;
my $embedding = AI::Embedding->new(
api => 'OpenAI',
key => 'your-api-key'
);
my $csv_embedding = $embedding->embedding('Some sample text');
my $test_embedding = $embedding->test_embedding('Some sample text');
my @raw_embedding = $embedding->raw_embedding('Some sample text');
my $cmp = $embedding->comparator($csv_embedding2);
my $similarity = $cmp->($csv_embedding1);
my $similarity_with_other_embedding = $embedding->compare($csv_embedding1, $csv_embedding2);
=head1 DESCRIPTION
The L<AI::Embedding> module provides an interface for working with text embeddings using various APIs. It currently supports the L<OpenAI|https://www.openai.com> L<Embeddings API|https://platform.openai.com/docs/guides/embeddings/what-are-embeddings>...
lib/AI/Embedding.pm view on Meta::CPAN
=head2 raw_embedding
my @raw_embedding = $embedding->raw_embedding('Some text passage', [$verbose]);
Generates an embedding for the given text and returns it as an array. The C<raw_embedding> method takes a single parameter, the text to generate the embedding for.
It is not normally necessary to use this method as the Embedding will almost always be used as a single homogeneous unit.
If the method call fails it sets the L</"error"> message and returns C<undef>. If the optional C<verbose> parameter is true, the complete L<HTTP::Tiny> response object is also returned to aid with debugging issues when using this module.
=head2 test_embedding
my $test_embedding = $embedding->test_embedding('Some text passage', $dimensions);
Used for testing code without making a chargeable call to the API.
Provides a CSV string of the same size and format as L<embedding> but with meaningless random data.
Returns a random embedding. Both parameters are optional. If a text string is provided, the returned embedding will always be the same random embedding otherwise it will be random and different every time. The C<dimension> parameter controls the n...
=head2 comparator
$embedding->comparator($csv_embedding2);
Sets a vector as a C<comparator> for future comparisons and returns a reference to a method for using the C<comparator>.
lib/AI/Embedding.pm view on Meta::CPAN
=item * Search CPAN
L<https://metacpan.org/release/AI::Embedding>
=back
=head1 ACKNOWLEDGEMENTS
Thanks to the help and support provided by members of Perl Monks L<https://perlmonks.org/>.
Especially L<Ken Cotterill (KCOTT)|https://metacpan.org/author/KCOTT> for assistance with unit tests and L<Hugo van der Sanden (HVDS)|https://metacpan.org/author/HVDS> for suggesting the current C<comparator> implementaion.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2023 by Ian Boddison.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
t/00-load.t view on Meta::CPAN
#!perl
use 5.006;
use strict;
use warnings;
use Test::More tests => 1;
#plan tests => 2;
BEGIN {
use_ok( 'AI::Embedding' ) || print "Bail out!\n";
}
diag( "Testing AI::Embedding $AI::Embedding::VERSION, Perl $], $^X" );
t/01-openai.t view on Meta::CPAN
my $cmp = $embed_pass->comparator('-0.6,-0.5,-0.4,-0.3,-0.2,0.0,0.2,0.3,0.4,0.5');
ok( $embed_pass->success, "Comparator created" );
ok( defined $cmp, "Comparator exists" );
my $comp_pass2 = $cmp->('-0.6,-0.5,-0.4,-0.3,-0.2,0.0,0.2,0.3,0.4,0.5');
is( $comp_pass2, 1, "Compare to comparator got $comp_pass2");
done_testing(12);
t/02-test.t view on Meta::CPAN
use AI::Embedding;
my $embed_pass = AI::Embedding->new(
'key' => '0123456789',
'api' => 'OpenAI',
);
ok( $embed_pass->isa( 'AI::Embedding' ), 'Instantiation' );
ok( $embed_pass->success, 'Successful object creation' );
my $test_string1 = 'The cat sat on the mat';
my $test_string2 = 'Hickory dickory dock';
my $embed1 = $embed_pass->test_embedding($test_string1);
is( scalar split (/,/, $embed1), 1536, "Correct first embed length");
my $embed2 = $embed_pass->test_embedding($test_string2);
is( scalar split (/,/, $embed2), 1536, "Correct second embed length");
my $embed3 = $embed_pass->test_embedding($test_string2);
ok( $embed2 eq $embed3, "Same text - same test embedding" );
ok( $embed2 ne $embed1, "Different text - different test embedding" );
done_testing(6);
t/manifest.t view on Meta::CPAN
#!perl
use 5.006;
use strict;
use warnings;
use Test::More;
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required for installation" );
}
my $min_tcm = 0.9;
eval "use Test::CheckManifest $min_tcm";
plan skip_all => "Test::CheckManifest $min_tcm required" if $@;
ok_manifest();
t/pod-coverage.t view on Meta::CPAN
#!perl
use 5.006;
use strict;
use warnings;
use Test::More;
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required for installation" );
}
# Ensure a recent version of Test::Pod::Coverage
my $min_tpc = 1.08;
eval "use Test::Pod::Coverage $min_tpc";
plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
if $@;
# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
# but older versions don't recognize some common documentation styles
my $min_pc = 0.18;
eval "use Pod::Coverage $min_pc";
plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
if $@;
all_pod_coverage_ok();
#!perl
use 5.006;
use strict;
use warnings;
use Test::More;
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required for installation" );
}
# Ensure a recent version of Test::Pod
my $min_tp = 1.22;
eval "use Test::Pod $min_tp";
plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
all_pod_files_ok();
t/version.t view on Meta::CPAN
#!/usr/bin/perl
use warnings;
use strict;
use Test::More;
use AI::Embedding;
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required for installation" );
}
my $code_version = $AI::Embedding::VERSION;
ok($code_version, 'version set');
ok(open(my $source, '<', $INC{'AI/Embedding.pm'}), 'open the source');
my $in_version;
while (<$source>) {
if (/^=head1 VERSION/) {
$in_version = 1;
} elsif (/^=head1/) {
undef $in_version;
}
if ($in_version && /^Version ([0-9.]+)/) {
is($code_version, $1, 'pod version');
}
}
done_testing();
( run in 0.351 second using v1.01-cache-2.11-cpan-87723dcf8b7 )