summaryrefslogtreecommitdiff
path: root/src/providers/DeepSeek.cpp
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrik@mailbox.org>2025-12-27 17:25:41 +0100
committerAldrik Ramaekers <aldrik@mailbox.org>2025-12-27 17:25:41 +0100
commit7c3a271feea4b3693bf93a47924f7c682585e179 (patch)
treeb72a1f3f2780f9f22f679e18f5d1780541cc040b /src/providers/DeepSeek.cpp
parent28c730a2e35ce81634dd4d47bf8e92e4552ec17c (diff)
mail provider settings ui
Diffstat (limited to 'src/providers/DeepSeek.cpp')
-rw-r--r--src/providers/DeepSeek.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/providers/DeepSeek.cpp b/src/providers/DeepSeek.cpp
new file mode 100644
index 0000000..c34e299
--- /dev/null
+++ b/src/providers/DeepSeek.cpp
@@ -0,0 +1,120 @@
+/*
+* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#define CPPHTTPLIB_OPENSSL_SUPPORT
+#include "httplib.h"
+#include "strops.hpp"
+#include "memops.hpp"
+#include "logger.hpp"
+#include "importer.hpp"
+
+#define QUERY_BUFFER_SIZE 1000000
+
+char* query_buffer = 0;
+static bool _DeepSeek_query_with_file(const char* query, size_t query_length, char* file_id, char** response)
+{
+ (void)file_id;
+ (void)query_length;
+ assert(query_buffer);
+
+ const char *api_key = administration::get_ai_service().api_key_public;
+
+ httplib::SSLClient cli("api.deepseek.com");
+ //cli.enable_server_certificate_verification(false);
+
+ //char* query_escaped = strops::prep_str_for_json(query, query_length);
+ //memops::unalloc(query); // TODO why??
+
+ size_t file_size = strops::length(query_buffer);
+ sprintf(query_buffer + file_size, "%s", query);
+
+ char* query_escaped = strops::prep_str_for_json(query_buffer, strops::length(query_buffer));
+
+ size_t body_size = file_size + QUERY_BUFFER_SIZE;
+ char* body = (char*)memops::alloc(body_size);
+ strops::format(body, body_size,
+ "{\"model\":\"%s\", \"messages\": [ { \"role\": \"user\", \"content\": \"%s\" } ] }", administration::get_ai_service().model_name, query_escaped);
+
+ httplib::Headers headers;
+ headers.insert(std::make_pair("Authorization", std::string("Bearer ") + api_key));
+ headers.insert(std::make_pair("Content-Type", "application/json"));
+ headers.insert(std::make_pair("Accept", "application/json"));
+
+ httplib::Result res = cli.Post("/chat/completions", 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();
+ *response = (char*)memops::alloc(100000);
+ memops::zero(*response, 100000);
+ strops::copy(*response, response_body, 100000);
+
+ strops::get_json_value(*response, "content", *response, 100000);
+ *response = strops::unprep_str_from_json(*response);
+
+ return 1;
+}
+
+static bool _DeepSeek_upload_file(char* file_path, char* file_id, size_t file_id_len)
+{
+ (void)file_id;
+ (void)file_id_len;
+ const char *filename = strops::get_filename(file_path);
+
+ FILE* orig_file = fopen(file_path, "r");
+ if (orig_file == NULL) {
+ logger::error("ERROR: file to upload could not be opened.");
+ return 0;
+ }
+
+ fseek(orig_file, 0L, SEEK_END);
+ long sz = ftell(orig_file);
+ fseek(orig_file, 0, SEEK_SET);
+
+ size_t buffer_size = sz + QUERY_BUFFER_SIZE;
+ char* file_content_buffer = (char*)memops::alloc(buffer_size);
+ memops::zero(file_content_buffer, buffer_size);
+
+ query_buffer = file_content_buffer;
+
+ file_content_buffer += sprintf(file_content_buffer, "[file name]: %s\n", filename);
+ file_content_buffer += sprintf(file_content_buffer, "[file content begin]\n");
+
+ fread(file_content_buffer, sz, 1, orig_file);
+ file_content_buffer += sz;
+
+ for (int i = 0; i < file_content_buffer-query_buffer; i++) if (query_buffer[i] <= 0x1f) query_buffer[i] = ' ';
+
+ file_content_buffer += sprintf(file_content_buffer, "\n[file content end]\n");
+ file_content_buffer[0] = 0;
+
+ fclose(orig_file);
+
+ return 1;
+}
+
+importer::ai_provider_impl _deepseek_api_provider = {
+ "DeekSeek",
+ "deepseek-reasoner",
+ _DeepSeek_upload_file,
+ _DeepSeek_query_with_file,
+ 0,
+}; \ No newline at end of file