Need to add to git to run tests

This commit is contained in:
Ryan Voots 2023-11-19 14:32:17 -05:00
parent f177f02e27
commit aa842df3cf
7 changed files with 224 additions and 72 deletions

103
.vstags Normal file
View file

@ -0,0 +1,103 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
OpenAIAsync::Types lib/OpenAIAsync/Types.pm 1;" p
OpenAIAsync::Types::Requests .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/latest/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests .build/previous/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests:: .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 1;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 170;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/latest/lib/OpenAIAsync/Types/Requests.pm 170;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 170;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 170;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union .build/previous/lib/OpenAIAsync/Types/Requests.pm 169;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union lib/OpenAIAsync/Types/Requests.pm 170;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 94;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/latest/lib/OpenAIAsync/Types/Requests.pm 94;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 94;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 94;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion .build/previous/lib/OpenAIAsync/Types/Requests.pm 93;" p
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion lib/OpenAIAsync/Types/Requests.pm 94;" p
OpenAIAsync::Types::Results .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/4DgDOdekNW/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/_pSCu227xy/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/latest/blib/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/latest/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/nb3podVIwj/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/previous/blib/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results .build/previous/lib/OpenAIAsync/Types/Results.pm 1;" p
OpenAIAsync::Types::Results lib/OpenAIAsync/Types/Results.pm 1;" p
new .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 173;" s
new .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 97;" s
new .build/latest/lib/OpenAIAsync/Types/Requests.pm 173;" s
new .build/latest/lib/OpenAIAsync/Types/Requests.pm 97;" s
new .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 173;" s
new .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 97;" s
new .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 173;" s
new .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 97;" s
new .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
new .build/previous/lib/OpenAIAsync/Types/Requests.pm 172;" s
new .build/previous/lib/OpenAIAsync/Types/Requests.pm 96;" s
new lib/OpenAIAsync/Types/Requests.pm 173;" s
new lib/OpenAIAsync/Types/Requests.pm 97;" s
ontent::new .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 173;" s
ontent::new .build/latest/lib/OpenAIAsync/Types/Requests.pm 173;" s
ontent::new .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 173;" s
ontent::new .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 173;" s
ontent::new .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new .build/previous/lib/OpenAIAsync/Types/Requests.pm 172;" s
ontent::new lib/OpenAIAsync/Types/Requests.pm 173;" s
y::new .build/4DgDOdekNW/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/4DgDOdekNW/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/NfFNPyy4iR/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/_pSCu227xy/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/_pSCu227xy/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/latest/blib/lib/OpenAIAsync/Types/Requests.pm 97;" s
y::new .build/latest/lib/OpenAIAsync/Types/Requests.pm 97;" s
y::new .build/nb3podVIwj/blib/lib/OpenAIAsync/Types/Requests.pm 97;" s
y::new .build/nb3podVIwj/lib/OpenAIAsync/Types/Requests.pm 97;" s
y::new .build/previous/blib/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new .build/previous/lib/OpenAIAsync/Types/Requests.pm 96;" s
y::new lib/OpenAIAsync/Types/Requests.pm 97;" s

7
lib/OpenAIAsync.pm Normal file
View file

@ -0,0 +1,7 @@
package OpenAIAsync;
our $VERSION="0.01";
# ABSTRACT: OpenAI style Client and Server for processing various AI tasks
1;

View file

@ -6,6 +6,10 @@ use Future::AsyncAwait;
use OpenAIAsync::Types::Results;
use OpenAIAsync::Types::Requests;
our $VERSION="v0.1.0";
# ABSTRACT: Async client for OpenAI style REST API for various AI systems (LLMs, Images, Video, etc.)
class OpenAIAsync::Client :repr(HASH) :isa(IO::Async::Notifier) {
use JSON::MaybeXS qw//;
use Net::Async::HTTP;
@ -13,17 +17,16 @@ class OpenAIAsync::Client :repr(HASH) :isa(IO::Async::Notifier) {
use URI;
field $_json = JSON::MaybeXS->new(utf8 => 1, convert_blessed => 1);
field $http;
# TODO document these directly, other options gets mixed in BEFORE all of these
field $_http_max_in_flight :param(http_max_in_flight) = 2;
field $_http_max_redirects :param(http_max_redirects) = 3;
field $_http_max_connections_per_host :param(http_max_connections_per_host) = 2;
field $_http_timeout :param(http_timeout) = 120; # My personal server is kinda slow, use a generous default
field $_http_stall_timeout :param(http_stall_timeout) = 600; # generous for my slow personal server
field $_http_proxy_host :param(http_proxy_host) = undef;
field $_http_proxy_port :param(http_proxy_port) = undef;
field $_http_proxy_path :param(http_proxy_path) = undef;
field $http;
field $_http_other :param(http_other_options) = {};
field $_http_user_agent = __PACKAGE__." Perl/$VERSION (Net::Async::HTTP/".$Net::Async::HTTP::VERSION." IO::Async/".$IO::Async::VERSION." Perl/$])";
field $api_base :param(api_base) = $ENV{OPENAI_API_BASE} // "https://api.openai.com/v1";
field $api_key :param(api_key) = $ENV{OPENAI_API_KEY};
@ -31,15 +34,17 @@ class OpenAIAsync::Client :repr(HASH) :isa(IO::Async::Notifier) {
field $api_org_name :param(api_org_name) = undef;
method configure(%params) {
# We require them to go this way
# We require them to go this way, so that there is no conflicts
# TODO document this
my %io_async_params = ($params{io_async_notifier_params} // {})->%*;
IO::Async::Notifier::configure($self, );
IO::Async::Notifier::configure($self, %io_async_params);
}
method __make_http() {
die "Missing API Key for OpenAI" unless $api_key;
return Net::Async::HTTP->new(
$_http_other->%*,
user_agent => "SNN OpenAI Client 1.0",
+headers => {
"Authorization" => "Bearer $api_key",
@ -53,7 +58,6 @@ class OpenAIAsync::Client :repr(HASH) :isa(IO::Async::Notifier) {
max_in_flight => $_http_max_in_flight,
timeout => $_http_timeout,
stall_timeout => $_http_stall_timeout,
# TODO proxy stuff
)
}

11
lib/OpenAIAsync/Types.pm Normal file
View file

@ -0,0 +1,11 @@
package OpenAIAsync::Types;
use v5.38.0;
use Object::Pad;
use Object::PadX::Role::AutoMarshal;
use Object::PadX::Role::AutoJSON;
use Object::Pad::ClassAttr::Struct;
# Base role for all the types to simplify things later
role OpenAIAsync::Types::Base :does(Object::PadX::Role::AutoJSON) :does(Object::PadX::Role::AutoMarshal) :Struct {
}

View file

@ -1,38 +1,95 @@
package OpenAIAsync::Types::Requests::;
package OpenAIAsync::Types::Requests;
use v5.38.0;
use Object::Pad;
use Object::PadX::Role::AutoMarshal;
use Object::PadX::Role::AutoJSON;
use Object::Pad::ClassAttr::Struct;
use OpenAIAsync::Types;
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::ToolCall :does(AutoMarshal) :does(AutoJSON) :Struct {
role OpenAIAsync::Types::Requests::Base :does(OpenAIAsync::Types::Base) :Struct {
requires _endpoint; # How the client finds where to send the request
}
#### Base Request Types
class OpenAIAsync::Types::Requests::ChatCompletion :does(OpenAIAsync::Types::Requests::Base) {
method _endpoint() {...}
field $messages :MarshalTo([OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union]);
}
class OpenAIAsync::Types::Requests::Completion :does(OpenAIAsync::Types::Requests::Base) {
method _endpoint() {...}
use JSON::MaybeXS; # TODO make a role that does this better?
field $model :JSONStr = "gpt-3.5-turbo"; # This is how 99% of everyone else seems to default this
field $prompt :JSONStr;
field $max_tokens :JSONNum = undef; # use the platform default usually
field $temperature :JSONNum = undef;
field $top_p :JSONNum = undef;
field $seed :JSONNum = undef;
field $echo :JSONBool = undef; # true or false only
field $suffix :JSONStr = undef;
field $stop :JSONStr = undef; # array of stop tokens
field $user :JSONStr = undef; # used for tracking purposes later
field $frequency_penalty :JSONNum = undef;
field $presence_penalty :JSONNum = undef;
field $logit_bias = undef; # TODO make this work
field $log_probs = undef; # TODO
field $n :JSONNum = undef; # Danger will robinson! easy to cause $$$$$$$ costs
field $best_of :JSONNum = undef;
field $stream :JSONBool = undef; # TODO FALSE ALWAYS RIGHT NOW
ADJUST {
# Type assertions here
die "Streaming unsupported" if $self->stream;
}
}
class OpenAIAsync::Types::Requests::Embedding :does(OpenAIAsync::Types::Requests::Base) {
method _endpoint() {...}
field $input :JSONStr;
field $model :JSONStr;
field $encoding_format :JSONStr = undef;
field $user :JSONStr = undef;
}
### Request Subtypes
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::ToolCall :does(OpenAIAsync::Types::Base) {
field $id :JSONStr;
field $arguments :JSONStr;
field $type :JSONStr;
field $function :MarshalTo(OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::FunctionCall);
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::FunctionCall :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::FunctionCall :does(OpenAIAsync::Types::Base) {
field $arguments :JSONStr;
field $name :JSONStr;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::Text :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::Text :does(OpenAIAsync::Types::Base) {
field $type :JSONStr;
field $text :JSONStr;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ImageUrl :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ImageUrl :does(OpenAIAsync::Types::Base) {
field $url :JSONStr;
field $detail :JSONStr = undef;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::Image :does(AutoJSON) :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::Image :does(OpenAIAsync::Types::Base) {
field $type :JSONStr;
field $image_url :MarshalTo(OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ImageUrl);
}
# TODO, why have two of these? just shove it into the big one below
package
OpenAIAsync::Types::Requests::ChatCompletion::Messages::User::ContentUnion {
# This guy does some additional checks to give us the right type here
@ -53,7 +110,7 @@ package
}
};
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User :does(OpenAIAsync::Types::Base) {
# This particular type is more complicated than AutoMarshal can handle, so we need to
# do this in a custom manner.
field $role;
@ -82,7 +139,7 @@ class OpenAIAsync::Types::Requests::ChatCompletion::Messages::User :does(AutoJSO
}
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant :does(AutoMarshal) :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant :does(OpenAIAsync::Types::Base) {
field $role :JSONStr;
field $content :JSONStr;
field $name = undef;
@ -90,19 +147,19 @@ class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant :does(Au
field $function_call :MarshalTo(OpenAIAsync::Types::Requests::ChatCompletion::Messages::Assistant::FunctionCall) = undef;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Function :does(AutoMarshal) :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Function :does(OpenAIAsync::Types::Base) {
field $role :JSONStr;
field $content :JSONStr;
field $name :JSONStr;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Tool :does(AutoMarshal) :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::Tool :does(OpenAIAsync::Types::Base) {
field $role :JSONStr;
field $content :JSONStr;
field $tool_call_id :JSONStr;
}
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::System :does(AutoMarshal) :does(AutoJSON) :Struct {
class OpenAIAsync::Types::Requests::ChatCompletion::Messages::System :does(OpenAIAsync::Types::Base) {
field $role :JSONStr;
field $name :JSONStr = undef;
field $content :JSONStr;
@ -133,46 +190,3 @@ package
}
};
class OpenAIAsync::Types::Requests::ChatCompletion :does(AutoMarshal) :does(AutoJSON) :Struct {
field $messages :MarshalTo([OpenAIAsync::Types::Requests::ChatCompletion::Messages::Union]);
}
class OpenAIAsync::Types::Requests::Completion :does(AutoJSON) :Struct {
use JSON::MaybeXS; # TODO make a role that does this better?
field $model :JSONStr = "gpt-3.5-turbo"; # This is how 99% of everyone else seems to default this
field $prompt :JSONStr;
field $max_tokens :JSONNum = undef; # use the platform default usually
field $temperature :JSONNum = undef;
field $top_p :JSONNum = undef;
field $seed :JSONNum = undef;
field $echo :JSONBool = undef; # true or false only
field $suffix :JSONStr = undef;
field $stop :JSONStr = undef; # array of stop tokens
field $user :JSONStr = undef; # used for tracking purposes later
field $frequency_penalty :JSONNum = undef;
field $presence_penalty :JSONNum = undef;
field $logit_bias = undef; # TODO make this work
field $log_probs = undef; # TODO
field $n :JSONNum = undef; # Danger will robinson! easy to cause $$$$$$$ costs
field $best_of :JSONNum = undef;
field $stream :JSONBool = undef; # TODO FALSE ALWAYS RIGHT NOW
ADJUST {
# Type assertions here
die "Streaming unsupported" if $self->stream;
}
}
class OpenAIAsync::Types::Requests::Embedding :does(AutoJSON) :Struct {
field $input :JSONStr;
field $model :JSONStr;
field $encoding_format :JSONStr = undef;
field $user :JSONStr = undef;
}

View file

@ -2,34 +2,36 @@ package OpenAIAsync::Types::Results;
use v5.38.0;
use Object::Pad;
use OpenAIAsync::Types;
use Object::PadX::Role::AutoMarshal;
use Object::PadX::Role::AutoJSON;
use Object::Pad::ClassAttr::Struct;
class OpenAIAsync::Types::Results::ToolCall :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ToolCall :does(OpenAIAsync::Types::Base) {
field $id;
field $type; # always "function" right now, may get expanded in the future
field $function :MarshalTo(OpenAIAsync::Types::Results::FunctionCall);
}
class OpenAIAsync::Types::Results::FunctionCall :Struct {
class OpenAIAsync::Types::Results::FunctionCall :does(OpenAIAsync::Types::Base) {
field $arguments; # TODO decode the json from this directly?
field $name;
}
class OpenAIAsync::Types::Results::ChatMessage :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChatMessage :does(OpenAIAsync::Types::Base) {
field $content;
field $tool_calls :MarshalTo([OpenAIAsync::Types::Results::ToolCall]) = undef; # don't think my local server provides this
field $role;
field $function_call :MarshalTo(OpenAIAsync::Types::Results::FunctionCall) = undef; # Depcrecated, might still happen
}
class OpenAIAsync::Types::Results::ChatCompletionChoices :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChatCompletionChoices :does(OpenAIAsync::Types::Base) {
field $finish_reason;
field $index;
field $message :MarshalTo(OpenAIAsync::Types::Results::ChatMessage);
}
class OpenAIAsync::Types::Results::ChatCompletion :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChatCompletion :does(OpenAIAsync::Types::Base) {
field $id;
field $choices :MarshalTo([OpenAIAsync::Types::Results::ChatCompletionChoices]);
field $created;
@ -39,21 +41,21 @@ class OpenAIAsync::Types::Results::ChatCompletion :does(AutoMarshal) :Struct {
field $object;
}
class OpenAIAsync::Types::Results::ChunkDelta :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChunkDelta :does(OpenAIAsync::Types::Base) {
field $content;
field $function_call :MarshalTo(OpenAIAsync::Types::Results::FunctionCall);
field $tool_cass :MarshalTo([OpenAIAsync::Types::Results::ToolCall]);
field $role;
}
class OpenAIAsync::Types::Results::ChatCompletionChunkChoices :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChatCompletionChunkChoices :does(OpenAIAsync::Types::Base) {
field $delta :MarshalTo(OpenAIAsync::Types::Results::ChunkDelta);
field $finish_reason;
field $index;
}
# This is part of the streaming API
class OpenAIAsync::Types::Results::ChatCompletionChunk :does(AutoMarshal) :Struct {
class OpenAIAsync::Types::Results::ChatCompletionChunk :does(OpenAIAsync::Types::Base) {
field $id;
field $choices :MarshalTo(OpenAIAsync::Types::Results::ChatCompletionChunkChoices);
field $created;
@ -62,13 +64,13 @@ class OpenAIAsync::Types::Results::ChatCompletionChunk :does(AutoMarshal) :Struc
field $object;
}
class OpenAIAsync::Types::Results::Usage :Struct {
class OpenAIAsync::Types::Results::Usage :does(OpenAIAsync::Types::Base) {
field $total_tokens;
field $prompt_tokens;
field $completion_tokens; # look at chat completions, is this the same
}
class OpenAIAsync::Types::Results::LogProbs :Struct {
class OpenAIAsync::Types::Results::LogProbs :does(OpenAIAsync::Types::Base) {
field $text_offset = undef;
field $token_logprobs = undef;
field $tokens = undef;

11
t/01-use-ok.t Normal file
View file

@ -0,0 +1,11 @@
use strict;
use warnings;
use Test::More;
require_ok('OpenAIAsync::Client');
require_ok('OpenAIAsync::Types');
require_ok('OpenAIAsync::Types::Requests');
require_ok('OpenAIAsync::Types::Results');
done_testing();