summaryrefslogtreecommitdiff
path: root/src/ai_providers
diff options
context:
space:
mode:
Diffstat (limited to 'src/ai_providers')
-rw-r--r--src/ai_providers/openAI.cpp78
1 files changed, 72 insertions, 6 deletions
diff --git a/src/ai_providers/openAI.cpp b/src/ai_providers/openAI.cpp
index fa2cc05..64e7a6a 100644
--- a/src/ai_providers/openAI.cpp
+++ b/src/ai_providers/openAI.cpp
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <threads.h>
+
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
@@ -22,9 +24,77 @@
#include "logger.hpp"
#include "importer.hpp"
+static bool _openAI_batch_query_with_file(char** queries, size_t query_count, char* file_id, invoice* buffer, importer::batch_query_response_handler response_handler)
+{
+ const char *api_key = administration::get_ai_service().api_key_public;
+ httplib::SSLClient cli("api.openai.com", 443);
+
+ thrd_t threads[20];
+
+ for (u32 i = 0; i < query_count; i++)
+ {
+ auto* func = new auto([&api_key, &cli, i, &file_id, &response_handler, &buffer, &queries]() {
+ char* query_escaped = strops::prep_str_for_json(queries[i], 1000);
+
+ size_t body_size = 1000; // Ballpark
+ char* body = (char*)memops::alloc(body_size);
+ strops::format(body, body_size,
+ "{ \"model\":\"%s\", "
+ " \"input\": [ "
+ " { \"role\": \"user\", "
+ " \"content\": [ "
+ " { \"type\": \"input_file\", \"file_id\": \"%s\" }, "
+ " { \"type\": \"input_text\", \"text\": \"%s\" } "
+ " ] "
+ " }"
+ "], "
+ " \"text\": { \"format\": { \"type\": \"json_object\" } } "
+ "}", administration::get_ai_service().model_name, file_id, query_escaped);
+
+ httplib::Headers headers;
+ headers.insert(std::make_pair("Authorization", std::string("Bearer ") + api_key));
+
+ httplib::Result res = cli.Post("/v1/responses", headers, body, "application/json");
+ memops::unalloc(body);
+
+ if (!res || res->status != 200) {
+ logger::error("ERROR Failed to query API.");
+ logger::error(res->body.c_str());
+ return 0;
+ }
+
+ char* response_body = (char*)res->body.c_str();
+ char* response = (char*)memops::alloc(5000);
+ memops::zero(response, 5000);
+ strops::copy(response, response_body, 5000);
+
+ strops::get_json_value(response, "text", response, 5000);
+ strops::unprep_str_from_json(response);
+
+ response_handler(buffer, response);
+
+ memops::unalloc(response);
+ memops::unalloc(query_escaped);
+ return 1;
+ });
+
+ auto trampoline = [](void* arg) -> int {
+ auto* f = static_cast<decltype(func)>(arg);
+ (*f)();
+ delete f;
+ return 0;
+ };
+
+ thrd_create(&threads[i], trampoline, func);
+ }
+
+ for (u32 i = 0; i < query_count; i++) thrd_join(threads[i], nullptr);
+
+ return 1;
+}
+
static bool _openAI_query_with_file(char* query, size_t query_length, char* file_id, char** response)
{
- #if 1
const char *api_key = administration::get_ai_service().api_key_public;
httplib::SSLClient cli("api.openai.com", 443);
@@ -58,11 +128,6 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
strops::get_json_value(*response, "text", *response, 100000);
*response = strops::unprep_str_from_json(*response);
- #else
- *response = (char*)memops::alloc(100000);
- memops::zero(*response, 100000);
- strops::copy(*response, "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\"> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ID>492043632</cbc:ID> <cbc:IssueDate>2024-09-01</cbc:IssueDate> <cbc:DueDate>2024-09-01</cbc:DueDate> <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode>USD</cbc:DocumentCurrencyCode> <cac:DespatchDocumentReference> <cbc:ID>Final invoice</cbc:ID> </cac:DespatchDocumentReference> <cac:AdditionalDocumentReference> <cbc:ID></cbc:ID> <cbc:DocumentDescription></cbc:DocumentDescription> </cac:AdditionalDocumentReference> <cac:OrderReference> <cbc:ID></cbc:ID> </cac:OrderReference> <cac:ProjectReference> <cbc:ID>do:team:67840ecb-44e2-472e-bc45-801bd4e1f1fe</cbc:ID> </cac:ProjectReference> <cbc:AccountingCost></cbc:AccountingCost> <cac:AccountingSupplierParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>DigitalOcean LLC</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>101 Avenue of the Americas</cbc:StreetName> <cbc:AdditionalStreetName>2nd Floor</cbc:AdditionalStreetName> <cbc:CityName>New York</cbc:CityName> <cbc:PostalZone>10013</cbc:PostalZone> <cbc:CountrySubentity>NY</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>US</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>EU528002224</cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName>DigitalOcean LLC</cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail></cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingSupplierParty> <cac:AccountingCustomerParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>My Team</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>Keerderstraat 81</cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName>Maastricht</cbc:CityName> <cbc:PostalZone>6226 XW</cbc:PostalZone> <cbc:CountrySubentity>LI</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>NL</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID></cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail>aldrikboy@gmail.com</cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingCustomerParty> <cac:Delivery> <cbc:ActualDeliveryDate></cbc:ActualDeliveryDate> <cac:DeliveryLocation> <cac:Address> <cbc:StreetName></cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode></cbc:IdentificationCode> </cac:Country> </cac:Address> </cac:DeliveryLocation> <cac:DeliveryParty> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> </cac:DeliveryParty> </cac:Delivery> <cac:PaymentMeans> <cbc:PaymentMeansCode></cbc:PaymentMeansCode> <cbc:PaymentID>492043632</cbc:PaymentID> <cac:PayeeFinancialAccount> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> <cac:FinancialInstitutionBranch> <cac:FinancialInstitution> <cbc:ID></cbc:ID> </cac:FinancialInstitution> </cac:FinancialInstitutionBranch> </cac:PayeeFinancialAccount> <cac:PayerFinancialAccount> <cbc:ID></cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMeans> <cac:TaxTotal> <cbc:TaxAmount currencyID=\"USD\">3.49</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">15.60</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">3.28</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">1.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">0.21</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID=\"USD\">16.60</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID=\"USD\">20.09</cbc:TaxInclusiveAmount> <cbc:PayableAmount currencyID=\"USD\">20.09</cbc:PayableAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode=""></cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason> <cbc:MultiplierFactorNumeric></cbc:MultiplierFactorNumeric> <cbc:Amount currencyID=\"USD\"></cbc:Amount> <cbc:BaseAmount currencyID=\"USD\"></cbc:BaseAmount> </cac:AllowanceCharge> <cac:Item> <cbc:Name>Product Usage Charges</cbc:Name> <cac:AdditionalItemProperty> <cbc:Name>Internal Tax Rate ID</cbc:Name> <cbc:Value></cbc:Value> </cac:AdditionalItemProperty> <cac:ClassifiedTaxCategory> <cbc:ID></cbc:ID> <cbc:Percent></cbc:Percent> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> <cac:Price> <cbc:PriceAmount currencyID=\"USD\"></cbc:PriceAmount> </cac:Price> </cac:InvoiceLine></Invoice>", 100000);
- #endif
return 1;
}
@@ -205,5 +270,6 @@ importer::ai_provider_impl _chatgpt_api_provider = {
"gpt-5-nano",
_openAI_upload_file,
_openAI_query_with_file,
+ _openAI_batch_query_with_file,
_openAI_get_available_models,
}; \ No newline at end of file