Formatting.

This commit is contained in:
retoor 2025-03-28 06:56:36 +01:00
parent 1e62665d43
commit bff6e758bc
21 changed files with 2614 additions and 2351 deletions

24
auth.h
View File

@ -1,35 +1,30 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This source code retrieves an API key from environment variables or defaults to a hardcoded key if none are found. // This source code retrieves an API key from environment variables or defaults
// to a hardcoded key if none are found.
// Uses the C standard library functions from stdlib.h for environment management and stdio.h for error handling. // Uses the C standard library functions from stdlib.h for environment
// management and stdio.h for error handling.
// MIT License // MIT License
#ifndef R_AUTH_H #ifndef R_AUTH_H
#define R_AUTH_H #define R_AUTH_H
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
enum AUTH_TYPE { enum AUTH_TYPE { AUTH_TYPE_NONE, AUTH_TYPE_API_KEY, AUTH_TYPE_FREE };
AUTH_TYPE_NONE,
AUTH_TYPE_API_KEY,
AUTH_TYPE_FREE
};
int auth_type = AUTH_TYPE_NONE; int auth_type = AUTH_TYPE_NONE;
void auth_free(){ void auth_free() { auth_type = AUTH_TYPE_FREE; }
auth_type = AUTH_TYPE_FREE;
}
void auth_init() { void auth_init() {
char *api_key = NULL; char *api_key = NULL;
if (auth_type != AUTH_TYPE_FREE) { if (auth_type != AUTH_TYPE_FREE) {
api_key = getenv("R_KEY"); api_key = getenv("R_KEY");
if (api_key) { if (api_key) {
auth_type = AUTH_TYPE_API_KEY; auth_type = AUTH_TYPE_API_KEY;
@ -61,9 +56,10 @@ const char *resolve_api_key() {
} }
} }
auth_type = AUTH_TYPE_FREE; auth_type = AUTH_TYPE_FREE;
api_key = "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"; api_key = "sk-proj-d798HLfWYBeB9HT_o7isaY0s88631IaYhhOR5IVAd4D_fF-"
"SQ5z46BCr8iDi1ang1rUmlagw55T3BlbkFJ6IOsqhAxNN9Zt6ERDBnv2p2HCc2fDgc"
"5DsNhPxdOzYb009J6CNd4wILPsFGEoUdWo4QrZ1eOkA";
return api_key; return api_key;
} }
#endif #endif

View File

@ -1,21 +1,20 @@
#include <string.h> #include "http_curl.h"
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <json-c/json.h> #include <json-c/json.h>
#include <json-c/json_util.h> #include <json-c/json_util.h>
#include "http_curl.h" #include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *url_encode(char *s) { return curl_easy_escape(NULL, s, 0); }
char * url_encode(char *s){
return curl_easy_escape(NULL, s, 0);
}
char *web_search_news(char *q) { char *web_search_news(char *q) {
char *news = malloc(4096); char *news = malloc(4096);
news[0] = 0; news[0] = 0;
char *q_encoded = url_encode(q); char *q_encoded = url_encode(q);
sprintf(news, "https://search.molodetz.nl/search?q=%s&format=json&categories=news",q_encoded); sprintf(news,
"https://search.molodetz.nl/search?q=%s&format=json&categories=news",
q_encoded);
free(q_encoded); free(q_encoded);
char *ret = curl_get(news); char *ret = curl_get(news);
free(news); free(news);
@ -36,7 +35,8 @@ char * web_search(char * q){
char *news = (char *)malloc(4096); char *news = (char *)malloc(4096);
news[0] = 0; news[0] = 0;
char *q_encoded = url_encode(q); char *q_encoded = url_encode(q);
sprintf(news, "https://search.molodetz.nl/search?q=%s&format=json",q_encoded); sprintf(news, "https://search.molodetz.nl/search?q=%s&format=json",
q_encoded);
free(q_encoded); free(q_encoded);
char *ret = curl_get(news); char *ret = curl_get(news);
free(news); free(news);

30
chat.h
View File

@ -1,8 +1,8 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This code defines functionality for creating and managing JSON-based chat prompts // This code defines functionality for creating and managing JSON-based chat
// using a specific AI model configuration, providing easy integration with message handling // prompts using a specific AI model configuration, providing easy integration
// and HTTP communication for dynamic applications. // with message handling and HTTP communication for dynamic applications.
// Non-standard imports: json-c library for handling JSON objects. // Non-standard imports: json-c library for handling JSON objects.
@ -15,8 +15,8 @@
// copies of the Software, and to permit persons to whom the Software is // copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: // furnished to do so, subject to the following conditions:
// //
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in
// copies or substantial portions of the Software. // all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@ -26,19 +26,19 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
#ifndef R_PROMPT_H #ifndef R_PROMPT_H
#define R_PROMPT_H #define R_PROMPT_H
#include "tools.h"
#include "auth.h" #include "auth.h"
#include <json-c/json.h>
#include "messages.h" #include "messages.h"
#include "r.h" #include "r.h"
#include "tools.h"
#include <json-c/json.h>
static json_object *_prompt = NULL; static json_object *_prompt = NULL;
void chat_free() { void chat_free() {
if (_prompt == NULL) return; if (_prompt == NULL)
return;
json_object_put(_prompt); json_object_put(_prompt);
_prompt = NULL; _prompt = NULL;
} }
@ -46,7 +46,8 @@ void chat_free() {
char *chat_json(const char *role, const char *message) { char *chat_json(const char *role, const char *message) {
chat_free(); chat_free();
json_object *root_object = json_object_new_object(); json_object *root_object = json_object_new_object();
json_object_object_add(root_object, "model", json_object_new_string(get_prompt_model())); json_object_object_add(root_object, "model",
json_object_new_string(get_prompt_model()));
if (role != NULL && message != NULL) { if (role != NULL && message != NULL) {
message_add(role, message); message_add(role, message);
@ -54,10 +55,13 @@ char *chat_json(const char *role, const char *message) {
} }
json_object_object_add(root_object, "messages", message_list()); json_object_object_add(root_object, "messages", message_list());
// json_object_object_add(root_object, "max_tokens", json_object_new_int(prompt_max_tokens)); // json_object_object_add(root_object, "max_tokens",
json_object_object_add(root_object, "temperature", json_object_new_double(PROMPT_TEMPERATURE)); // json_object_new_int(prompt_max_tokens));
json_object_object_add(root_object, "temperature",
json_object_new_double(PROMPT_TEMPERATURE));
return (char *)json_object_to_json_string_ext(root_object, JSON_C_TO_STRING_PRETTY); return (char *)json_object_to_json_string_ext(root_object,
JSON_C_TO_STRING_PRETTY);
} }
#endif #endif

View File

@ -1,5 +1,5 @@
#include <stdio.h>
#include "db_utils.h" #include "db_utils.h"
#include <stdio.h>
void db_initialize() { void db_initialize() {
sqlite3 *db; sqlite3 *db;
@ -10,7 +10,8 @@ void db_initialize() {
return; return;
} }
const char *sql = "CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);"; const char *sql =
"CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);";
rc = sqlite3_exec(db, sql, 0, 0, &err_msg); rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {

View File

@ -2,12 +2,9 @@
#define DB_UTILS_H #define DB_UTILS_H
#include "r.h" #include "r.h"
#include <sqlite3.h>
#include <json-c/json.h>
#include "utils.h" #include "utils.h"
#include <json-c/json.h>
#include <sqlite3.h>
json_object *db_execute(const char *query); json_object *db_execute(const char *query);
@ -25,7 +22,6 @@ json_object * db_set(const char *key, const char *value);
json_object *db_get(const char *key); json_object *db_get(const char *key);
json_object *db_query(const char *query); json_object *db_query(const char *query);
void db_initialize() { void db_initialize() {
sqlite3 *db; sqlite3 *db;
char *err_msg = 0; char *err_msg = 0;
@ -35,7 +31,8 @@ void db_initialize() {
return; return;
} }
const char *sql = "CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);"; const char *sql =
"CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);";
rc = sqlite3_exec(db, sql, 0, 0, &err_msg); rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
@ -45,7 +42,6 @@ void db_initialize() {
sqlite3_close(db); sqlite3_close(db);
} }
json_object *db_set(const char *key, const char *value) { json_object *db_set(const char *key, const char *value) {
sqlite3 *db; sqlite3 *db;
char *err_msg = 0; char *err_msg = 0;
@ -55,7 +51,10 @@ json_object * db_set(const char *key, const char *value) {
return NULL; return NULL;
} }
char *sql = sqlite3_mprintf("INSERT INTO kv_store (key, value) VALUES (%Q, %Q) ON CONFLICT(key) DO UPDATE SET value = %Q WHERE key = %Q", key, value, value,key); char *sql =
sqlite3_mprintf("INSERT INTO kv_store (key, value) VALUES (%Q, %Q) ON "
"CONFLICT(key) DO UPDATE SET value = %Q WHERE key = %Q",
key, value, value, key);
rc = sqlite3_exec(db, sql, 0, 0, &err_msg); rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
sqlite3_free(sql); sqlite3_free(sql);
@ -91,7 +90,8 @@ json_object* db_get(const char *key) {
if (value) { if (value) {
json_object_object_add(result, "value", json_object_new_string(value)); json_object_object_add(result, "value", json_object_new_string(value));
} else { } else {
json_object_object_add(result, "error", json_object_new_string("Key not found")); json_object_object_add(result, "error",
json_object_new_string("Key not found"));
} }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
@ -120,16 +120,25 @@ json_object* db_query(const char *query) {
const char *col_name = sqlite3_column_name(stmt, i); const char *col_name = sqlite3_column_name(stmt, i);
switch (sqlite3_column_type(stmt, i)) { switch (sqlite3_column_type(stmt, i)) {
case SQLITE_INTEGER: case SQLITE_INTEGER:
json_object_object_add(row, col_name, json_object_new_int64(sqlite3_column_int64(stmt, i))); json_object_object_add(
row, col_name,
json_object_new_int64(sqlite3_column_int64(stmt, i)));
break; break;
case SQLITE_FLOAT: case SQLITE_FLOAT:
json_object_object_add(row, col_name, json_object_new_double(sqlite3_column_double(stmt, i))); json_object_object_add(
row, col_name,
json_object_new_double(sqlite3_column_double(stmt, i)));
break; break;
case SQLITE_TEXT: case SQLITE_TEXT:
json_object_object_add(row, col_name, json_object_new_string((const char *)sqlite3_column_text(stmt, i))); json_object_object_add(
row, col_name,
json_object_new_string((const char *)sqlite3_column_text(stmt, i)));
break; break;
case SQLITE_BLOB: case SQLITE_BLOB:
json_object_object_add(row, col_name, json_object_new_string_len((const char *)sqlite3_column_blob(stmt, i), sqlite3_column_bytes(stmt, i))); json_object_object_add(row, col_name,
json_object_new_string_len(
(const char *)sqlite3_column_blob(stmt, i),
sqlite3_column_bytes(stmt, i)));
break; break;
case SQLITE_NULL: case SQLITE_NULL:
default: default:
@ -146,7 +155,6 @@ json_object* db_query(const char *query) {
return result; return result;
} }
json_object *db_execute(const char *query) { json_object *db_execute(const char *query) {
sqlite3 *db; sqlite3 *db;
char *err_msg = 0; char *err_msg = 0;
@ -154,7 +162,8 @@ json_object* db_execute(const char *query) {
json_object *result = json_object_new_object(); json_object *result = json_object_new_object();
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
json_object_object_add(result, "error", json_object_new_string("Cannot open database")); json_object_object_add(result, "error",
json_object_new_string("Cannot open database"));
return result; return result;
} }
@ -163,14 +172,17 @@ json_object* db_execute(const char *query) {
json_object_object_add(result, "error", json_object_new_string(err_msg)); json_object_object_add(result, "error", json_object_new_string(err_msg));
sqlite3_free(err_msg); sqlite3_free(err_msg);
} else { } else {
json_object_object_add(result, "success", json_object_new_string("Query executed successfully")); json_object_object_add(
result, "success",
json_object_new_string("Query executed successfully"));
} }
sqlite3_close(db); sqlite3_close(db);
return result; return result;
} }
char *db_get_schema() { char *db_get_schema() {
json_object * tables =db_query("SELECT * FROM sqlite_master WHERE type='table'"); json_object *tables =
db_query("SELECT * FROM sqlite_master WHERE type='table'");
char *result = strdup(json_object_get_string(tables)); char *result = strdup(json_object_get_string(tables));
json_object_put(tables); json_object_put(tables);
return result; return result;

View File

@ -1,8 +1,12 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This code defines a simple HTTP client using libcurl in C. It provides functions for executing POST and GET HTTP requests with JSON data, including authorization via a bearer token. The functions `curl_post` and `curl_get` handle these operations and return the server's response as a string. // This code defines a simple HTTP client using libcurl in C. It provides
// functions for executing POST and GET HTTP requests with JSON data, including
// authorization via a bearer token. The functions `curl_post` and `curl_get`
// handle these operations and return the server's response as a string.
// Uses libcurl for HTTP requests and includes a custom "auth.h" for API key resolution. // Uses libcurl for HTTP requests and includes a custom "auth.h" for API key
// resolution.
// MIT License // MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -11,31 +15,31 @@
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is // copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: the above copyright // furnished to do so, subject to the following conditions: the above copyright
// notice and this permission notice shall be included in all copies or substantial // notice and this permission notice shall be included in all copies or
// portions of the Software. The Software is provided "as is", without warranty of // substantial portions of the Software. The Software is provided "as is",
// any kind, express or implied, including but not limited to the warranties of // without warranty of any kind, express or implied, including but not limited
// merchantability, fitness for a particular purpose and noninfringement. In no // to the warranties of merchantability, fitness for a particular purpose and
// event shall the authors or copyright holders be liable for any claim, damages // noninfringement. In no event shall the authors or copyright holders be liable
// or other liability, whether in an action of contract, tort or otherwise, arising // for any claim, damages or other liability, whether in an action of contract,
// from, out of or in connection with the software or the use or other dealings in // tort or otherwise, arising from, out of or in connection with the software or
// the Software. // the use or other dealings in the Software.
#ifndef HTTP_CURL #ifndef HTTP_CURL
#define HTTP_CURL #define HTTP_CURL
#include "auth.h"
#include <curl/curl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <curl/curl.h>
#include "auth.h"
struct ResponseBuffer { struct ResponseBuffer {
char *data; char *data;
size_t size; size_t size;
}; };
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { static size_t WriteCallback(void *contents, size_t size, size_t nmemb,
void *userp) {
size_t total_size = size * nmemb; size_t total_size = size * nmemb;
struct ResponseBuffer *response = (struct ResponseBuffer *)userp; struct ResponseBuffer *response = (struct ResponseBuffer *)userp;
char *ptr = realloc(response->data, response->size + total_size + 1); char *ptr = realloc(response->data, response->size + total_size + 1);
@ -55,7 +59,8 @@ char *curl_post(const char *url, const char *data) {
CURLcode res; CURLcode res;
struct ResponseBuffer response = {malloc(1), 0}; struct ResponseBuffer response = {malloc(1), 0};
if (!response.data) return NULL; if (!response.data)
return NULL;
curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if (curl) {
@ -85,7 +90,8 @@ char *curl_get(const char *url) {
CURLcode res; CURLcode res;
struct ResponseBuffer response = {malloc(1), 0}; struct ResponseBuffer response = {malloc(1), 0};
if (!response.data) return NULL; if (!response.data)
return NULL;
curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if (curl) {

View File

@ -1,19 +1,22 @@
#include <dirent.h>
#include <json-c/json.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <time.h> #include <time.h>
#include <json-c/json.h>
#include <limits.h>
#include <unistd.h> #include <unistd.h>
#define MAX_FILES 20000 #define MAX_FILES 20000
#define MAX_PATH 4096 #define MAX_PATH 4096
static const char *extensions[] = {".c", ".cpp", ".h", ".py", ".java", ".js", ".mk", ".html", "Makefile", ".css", ".json", ".cs", ".csproj", ".sln", ".toml",".rs"}; static const char *extensions[] = {
static size_t ext_count = sizeof(extensions) / sizeof(extensions[0]); // Updated count to reflect the new number of extensions ".c", ".cpp", ".h", ".py", ".java", ".js", ".mk", ".html",
"Makefile", ".css", ".json", ".cs", ".csproj", ".sln", ".toml", ".rs"};
static size_t ext_count =
sizeof(extensions) /
sizeof(
extensions[0]); // Updated count to reflect the new number of extensions
typedef struct { typedef struct {
char name[MAX_PATH]; char name[MAX_PATH];
@ -26,7 +29,8 @@ typedef struct {
FileInfo file_list[MAX_FILES]; FileInfo file_list[MAX_FILES];
size_t file_count = 0; size_t file_count = 0;
int is_valid_extension(const char *filename, const char *extensions[], size_t ext_count) { int is_valid_extension(const char *filename, const char *extensions[],
size_t ext_count) {
const char *dot = strrchr(filename, '.'); const char *dot = strrchr(filename, '.');
if (!dot) { if (!dot) {
dot = filename; dot = filename;
@ -40,7 +44,8 @@ int is_valid_extension(const char *filename, const char *extensions[], size_t ex
} }
int is_ignored_directory(const char *dir_name) { int is_ignored_directory(const char *dir_name) {
const char *ignored_dirs[] = {"env", ".venv", "node_modules", "venv", "virtualenv"}; const char *ignored_dirs[] = {"env", ".venv", "node_modules", "venv",
"virtualenv"};
for (size_t i = 0; i < sizeof(ignored_dirs) / sizeof(ignored_dirs[0]); i++) { for (size_t i = 0; i < sizeof(ignored_dirs) / sizeof(ignored_dirs[0]); i++) {
if (strcmp(dir_name, ignored_dirs[i]) == 0) { if (strcmp(dir_name, ignored_dirs[i]) == 0) {
return 1; return 1;
@ -53,10 +58,14 @@ void get_file_info(const char *path) {
struct stat file_stat; struct stat file_stat;
if (stat(path, &file_stat) == 0) { if (stat(path, &file_stat) == 0) {
FileInfo info; FileInfo info;
strncpy(info.name, path, MAX_PATH - 1); // Copy with one less to leave space for null terminator strncpy(info.name, path,
MAX_PATH -
1); // Copy with one less to leave space for null terminator
info.name[MAX_PATH - 1] = '\0'; // Ensure null termination info.name[MAX_PATH - 1] = '\0'; // Ensure null termination
strftime(info.modification_date, sizeof(info.modification_date), "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_mtime)); strftime(info.modification_date, sizeof(info.modification_date),
strftime(info.creation_date, sizeof(info.creation_date), "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_ctime)); "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_mtime));
strftime(info.creation_date, sizeof(info.creation_date),
"%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_ctime));
strncpy(info.type, S_ISDIR(file_stat.st_mode) ? "directory" : "file", 10); strncpy(info.type, S_ISDIR(file_stat.st_mode) ? "directory" : "file", 10);
info.type[9] = '\0'; // Ensure null termination info.type[9] = '\0'; // Ensure null termination
info.size_bytes = file_stat.st_size; info.size_bytes = file_stat.st_size;
@ -91,11 +100,22 @@ char* index_directory(const char *dir_path) {
} else if (is_valid_extension(entry->d_name, extensions, ext_count)) { } else if (is_valid_extension(entry->d_name, extensions, ext_count)) {
get_file_info(full_path); get_file_info(full_path);
json_object *jfile = json_object_new_object(); json_object *jfile = json_object_new_object();
json_object_object_add(jfile, "file_name", json_object_new_string(file_list[file_count - 1].name)); json_object_object_add(
json_object_object_add(jfile, "modification_date", json_object_new_string(file_list[file_count - 1].modification_date)); jfile, "file_name",
json_object_object_add(jfile, "creation_date", json_object_new_string(file_list[file_count - 1].creation_date)); json_object_new_string(file_list[file_count - 1].name));
json_object_object_add(jfile, "type", json_object_new_string(file_list[file_count - 1].type)); json_object_object_add(
json_object_object_add(jfile, "size_bytes", json_object_new_int64(file_list[file_count - 1].size_bytes)); jfile, "modification_date",
json_object_new_string(
file_list[file_count - 1].modification_date));
json_object_object_add(
jfile, "creation_date",
json_object_new_string(file_list[file_count - 1].creation_date));
json_object_object_add(
jfile, "type",
json_object_new_string(file_list[file_count - 1].type));
json_object_object_add(
jfile, "size_bytes",
json_object_new_int64(file_list[file_count - 1].size_bytes));
// Read the file contents // Read the file contents
FILE *fp = fopen(file_list[file_count - 1].name, "r"); FILE *fp = fopen(file_list[file_count - 1].name, "r");
@ -109,16 +129,20 @@ char* index_directory(const char *dir_path) {
if (bytesRead != length) { if (bytesRead != length) {
free(content); free(content);
content = NULL; content = NULL;
json_object_object_add(jfile, "file_current_content_data", json_object_new_string("Error reading file")); json_object_object_add(
jfile, "file_current_content_data",
json_object_new_string("Error reading file"));
} else { } else {
content[length] = '\0'; // Null-terminate the string content[length] = '\0'; // Null-terminate the string
//json_object_object_add(jfile, "file_current_content_data", json_object_new_string(content)); // json_object_object_add(jfile, "file_current_content_data",
// json_object_new_string(content));
} }
free(content); free(content);
} }
fclose(fp); fclose(fp);
} else { } else {
//json_object_object_add(jfile, "content", json_object_new_string("Unable to read file")); // json_object_object_add(jfile, "content",
// json_object_new_string("Unable to read file"));
} }
json_object_array_add(jarray, jfile); json_object_array_add(jarray, jfile);

View File

@ -1,15 +1,16 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This source code extracts URLs from an input string and replaces them inline with their respective content in Markdown style. // This source code extracts URLs from an input string and replaces them inline
// with their respective content in Markdown style.
// Imports used: regex.h for regular expression operations, http.h and url.h for HTTP and URL-related utility functions. // Imports used: regex.h for regular expression operations, http.h and url.h for
// HTTP and URL-related utility functions.
// MIT License // MIT License
#include <regex.h>
#include "http.h" #include "http.h"
#include "url.h" #include "url.h"
#include <regex.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -30,11 +31,13 @@ void extract_urls(const char *input, char **urls, int *url_count) {
regfree(&regex); regfree(&regex);
} }
void inplace_urls_markdown_style(char **input, char **urls, char **contents, int url_count) { void inplace_urls_markdown_style(char **input, char **urls, char **contents,
int url_count) {
for (int i = 0; i < url_count; i++) { for (int i = 0; i < url_count; i++) {
char *found = strstr(*input, urls[i]); char *found = strstr(*input, urls[i]);
if (found) { if (found) {
char *new_text = (char *)malloc(strlen(*input) + strlen(contents[i]) - strlen(urls[i]) + 1); char *new_text = (char *)malloc(strlen(*input) + strlen(contents[i]) -
strlen(urls[i]) + 1);
strncpy(new_text, *input, found - *input); strncpy(new_text, *input, found - *input);
new_text[found - *input] = '\0'; new_text[found - *input] = '\0';
strcat(new_text, contents[i]); strcat(new_text, contents[i]);

26
line.h
View File

@ -1,25 +1,28 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This source code provides command-line input functionalities with autocomplete and history features using the readline library. It allows users to complete commands and manage input history. // This source code provides command-line input functionalities with
// autocomplete and history features using the readline library. It allows users
// to complete commands and manage input history.
// External includes: // External includes:
// - <readline/readline.h> // - <readline/readline.h>
// - <readline/history.h> // - <readline/history.h>
// - <glob.h> // - <glob.h>
// MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction. // MIT License: Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction.
#include <readline/readline.h>
#include <readline/history.h>
#include <string.h>
#include <stdbool.h>
#include <glob.h>
#include "utils.h" #include "utils.h"
#include <glob.h>
#include <readline/history.h>
#include <readline/readline.h>
#include <stdbool.h>
#include <string.h>
#define HISTORY_FILE "~/.r_history" #define HISTORY_FILE "~/.r_history"
bool line_initialized = false; bool line_initialized = false;
char *get_history_file() { char *get_history_file() {
static char result[4096]; static char result[4096];
result[0] = 0; result[0] = 0;
@ -32,7 +35,9 @@ char * get_history_file(){
char *line_command_generator(const char *text, int state) { char *line_command_generator(const char *text, int state) {
static int list_index, len = 0; static int list_index, len = 0;
const char* commands[] = {"help", "exit", "list", "review", "refactor", "obfuscate", "!verbose","!dump", "!model","!debug", NULL}; const char *commands[] = {"help", "exit", "list", "review",
"refactor", "obfuscate", "!verbose", "!dump",
"!model", "!debug", NULL};
if (!state) { if (!state) {
list_index = 0; list_index = 0;
@ -56,7 +61,8 @@ char* line_file_generator(const char* text, int state) {
if (!state) { if (!state) {
list_index = 0; list_index = 0;
snprintf(pattern, sizeof(pattern), "%s*", text); // Create a pattern for glob snprintf(pattern, sizeof(pattern), "%s*",
text); // Create a pattern for glob
glob(pattern, GLOB_NOSORT, NULL, &glob_result); glob(pattern, GLOB_NOSORT, NULL, &glob_result);
} }

69
main.c
View File

@ -1,6 +1,9 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This source code initializes a command-line application that uses OpenAI for chat interactions, handles user inputs, and can start a simple HTTP server with CGI support. The code allows command execution, markdown parsing, and OpenAI chat integration. // This source code initializes a command-line application that uses OpenAI for
// chat interactions, handles user inputs, and can start a simple HTTP server
// with CGI support. The code allows command execution, markdown parsing, and
// OpenAI chat integration.
// External imports used in this code: // External imports used in this code:
// - openai.h // - openai.h
@ -28,24 +31,22 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "r.h" #include "r.h"
#include <signal.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include "openai.h"
#include "markdown.h"
#include "line.h" #include "line.h"
#include "markdown.h"
#include "openai.h"
#include "utils.h"
#include <locale.h> #include <locale.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "utils.h"
#include "db_utils.h" #include "db_utils.h"
@ -157,7 +158,8 @@ bool try_prompt(int argc, char *argv[]) {
} }
void serve() { void serve() {
render("Starting server. *Put executables in a dir named cgi-bin and they will behave as web pages.*"); render("Starting server. *Put executables in a dir named cgi-bin and they "
"will behave as web pages.*");
int res = system("python3 -m http.server --cgi"); int res = system("python3 -m http.server --cgi");
(void)res; (void)res;
} }
@ -180,17 +182,14 @@ char ** get_parameters(char * content, char * delimiter){
parameters = (char **)realloc(parameters, sizeof(char *) * (1 + count * 2)); parameters = (char **)realloc(parameters, sizeof(char *) * (1 + count * 2));
parameters[count - 1] = parameter; parameters[count - 1] = parameter;
parameters[count] = NULL; parameters[count] = NULL;
} }
return parameters; return parameters;
} }
void render(char *content) void render(char *content) {
{
if(SYNTAX_HIGHLIGHT_ENABLED) if (SYNTAX_HIGHLIGHT_ENABLED) {
{
parse_markdown_to_ansi(content); parse_markdown_to_ansi(content);
} else { } else {
printf("%s", content); printf("%s", content);
@ -216,7 +215,8 @@ void repl() {
} }
if (!strncmp(line, "!verbose", 7)) { if (!strncmp(line, "!verbose", 7)) {
is_verbose = !is_verbose; is_verbose = !is_verbose;
fprintf(stderr,"%s\n",is_verbose?"Verbose mode enabled":"Verbose mode disabled"); fprintf(stderr, "%s\n",
is_verbose ? "Verbose mode enabled" : "Verbose mode disabled");
continue; continue;
} }
if (!strncmp(line, "!model", 6)) { if (!strncmp(line, "!model", 6)) {
@ -253,7 +253,6 @@ void repl() {
} }
free(response); free(response);
} }
} }
} }
@ -261,7 +260,8 @@ void repl() {
void help() { void help() {
char help_text[1024 * 1024] = {0}; char help_text[1024 * 1024] = {0};
char *template = "# Help\n" char *template =
"# Help\n"
"Written by retoor@molodetz.nl.\n\n" "Written by retoor@molodetz.nl.\n\n"
"## Features\n" "## Features\n"
" - navigate through history using `arrows`.\n" " - navigate through history using `arrows`.\n"
@ -270,7 +270,8 @@ void help() {
" - markdown and **syntax highlighting**.\n" " - markdown and **syntax highlighting**.\n"
" - **execute python commands** with prefix `!`\n" " - **execute python commands** with prefix `!`\n"
" - list files of the current work directory using `ls`.\n" " - list files of the current work directory using `ls`.\n"
" - type `serve` to start a web server with directory listing. Easy for network transfers.\n\n" " - type `serve` to start a web server with directory listing. Easy for "
"network transfers.\n\n"
"## Configuration\n" "## Configuration\n"
" - model temperature is %f.\n" " - model temperature is %f.\n"
" - model name is %s.\n" " - model name is %s.\n"
@ -278,8 +279,10 @@ void help() {
"## In development\n" "## In development\n"
" - **google search** and actions with those results.\n" " - **google search** and actions with those results.\n"
" - **reminders**.\n" " - **reminders**.\n"
" - predefined **templates** for **reviewing** / **refactoring** so you can personalize.\n"; " - predefined **templates** for **reviewing** / **refactoring** so you "
sprintf(help_text, template, PROMPT_TEMPERATURE, get_prompt_model(), prompt_max_tokens); "can personalize.\n";
sprintf(help_text, template, PROMPT_TEMPERATURE, get_prompt_model(),
prompt_max_tokens);
render(help_text); render(help_text);
} }
@ -292,21 +295,22 @@ char * strreplace(char * content, char * what, char * with){
memset(result, 0, strlen(content) + strlen(with) + 3); memset(result, 0, strlen(content) + strlen(with) + 3);
memcpy(result, content, pos - content); memcpy(result, content, pos - content);
memcpy(result + (pos - content), with, strlen(with)); memcpy(result + (pos - content), with, strlen(with));
memcpy(result + (pos - content) + strlen(with), pos + strlen(what), strlen(content) - (pos - content) - strlen(what) + 1); memcpy(result + (pos - content) + strlen(with), pos + strlen(what),
strlen(content) - (pos - content) - strlen(what) + 1);
return result; return result;
} }
char *linux_instructions = char *linux_instructions =
"You are a linux master and are able to transform the prompt of " "You are a linux master and are able to transform the prompt of "
"user into shell commands that will be executed on a debian " "user into shell commands that will be executed on a debian "
"based system. You can execute shell commands by responding with python code: " "based system. You can execute shell commands by responding with python "
"literally `\"\"\"!system\"\"\",\"\"\"`your shell command`\"\"\". Execute immediately. Read bash history file if you have to work with history."; "code: "
char * retoor_instructions = "If the user prompts with social talk, " "literally `\"\"\"!system\"\"\",\"\"\"`your shell command`\"\"\". Execute "
"respond like replica and emoji. Your name is retoor and made by molodetz. Be interested. Be creative."; "immediately. Read bash history file if you have to work with history.";
char *retoor_instructions =
"If the user prompts with social talk, "
"respond like replica and emoji. Your name is retoor and made by molodetz. "
"Be interested. Be creative.";
bool openai_include(char *path) { bool openai_include(char *path) {
char *file_content = read_file(path); char *file_content = read_file(path);
@ -318,8 +322,6 @@ bool openai_include(char *path) {
return true; return true;
} }
void init() { void init() {
setbuf(stdout, NULL); setbuf(stdout, NULL);
line_init(); line_init();
@ -327,7 +329,11 @@ void init() {
db_initialize(); db_initialize();
char *schema = db_get_schema(); char *schema = db_get_schema();
char payload[1024 * 1024] = {0}; char payload[1024 * 1024] = {0};
sprintf(payload, "Your have a database that you can mutate using the query tool and the get and set tool. This is the schema in json format: %s. Dialect is sqlite.", schema); sprintf(payload,
"Your have a database that you can mutate using the query tool and "
"the get and set tool. This is the schema in json format: %s. "
"Dialect is sqlite.",
schema);
free(schema); free(schema);
fprintf(stderr, "%s", "Loading... ⏳"); fprintf(stderr, "%s", "Loading... ⏳");
openai_system(payload); openai_system(payload);
@ -353,7 +359,6 @@ void handle_sigint(int sig) {
} }
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
signal(SIGINT, handle_sigint); signal(SIGINT, handle_sigint);

View File

@ -1,8 +1,11 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This program provides functionality to highlight the keywords in source code using ANSI color formatting and convert Markdown syntax into ANSI-colored text output. // This program provides functionality to highlight the keywords in source code
// using ANSI color formatting and convert Markdown syntax into ANSI-colored
// text output.
// Uses standard C libraries: <stdio.h>, <string.h>. Also utilizes ANSI escape codes for text formatting. // Uses standard C libraries: <stdio.h>, <string.h>. Also utilizes ANSI escape
// codes for text formatting.
// MIT License: // MIT License:
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -12,8 +15,8 @@
// copies of the Software, and to permit persons to whom the Software is // copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: // furnished to do so, subject to the following conditions:
// //
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in
// copies or substantial portions of the Software. // all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@ -23,9 +26,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define RESET "\033[0m" #define RESET "\033[0m"
#define BOLD "\033[1m" #define BOLD "\033[1m"
@ -37,26 +40,32 @@
int is_keyword(const char *word) { int is_keyword(const char *word) {
const char *keywords[] = { const char *keywords[] = {
"int", "float", "double", "char", "void", "int", "float", "double", "char", "void", "if", "else", "while", "for",
"if", "else", "while", "for", "return", "return", "struct", "printf",
"struct", "printf",
// Rust keywords // Rust keywords
"let", "fn", "impl", "match", "enum", "trait", "use", "mod", "pub", "const", "static", "let", "fn", "impl", "match", "enum", "trait", "use", "mod", "pub",
"const", "static",
// Python keywords // Python keywords
"def", "class", "import", "from", "as", "with", "try", "except", "finally", "lambda", "async", "await", "def", "class", "import", "from", "as", "with", "try", "except",
"finally", "lambda", "async", "await",
// Java keywords // Java keywords
"public", "private", "protected", "class", "interface", "extends", "implements", "new", "static", "final", "synchronized", "public", "private", "protected", "class", "interface", "extends",
"implements", "new", "static", "final", "synchronized",
// JavaScript keywords // JavaScript keywords
"var", "let", "const", "function", "async", "await", "if", "else", "switch", "case", "break", "continue", "return", "var", "let", "const", "function", "async", "await", "if", "else",
"switch", "case", "break", "continue", "return",
// C++ keywords // C++ keywords
"namespace", "template", "typename", "class", "public", "private", "protected", "virtual", "override", "friend", "new", "namespace", "template", "typename", "class", "public", "private",
"protected", "virtual", "override", "friend", "new",
// Go keywords // Go keywords
"package", "import", "func", "var", "const", "type", "interface", "struct", "go", "defer", "select", "package", "import", "func", "var", "const", "type", "interface",
"struct", "go", "defer", "select",
// Bash keywords // Bash keywords
"if", "then", "else", "elif", "fi", "case", "esac", "for", "while", "until", "do", "done", "function", "if", "then", "else", "elif", "fi", "case", "esac", "for", "while",
"until", "do", "done", "function",
// C# keywords // C# keywords
"namespace", "using", "class", "interface", "public", "private", "protected", "static", "void", "new", "override" "namespace", "using", "class", "interface", "public", "private",
}; "protected", "static", "void", "new", "override"};
for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) { for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
if (strcmp(word, keywords[i]) == 0) { if (strcmp(word, keywords[i]) == 0) {
@ -72,8 +81,10 @@ void highlight_code(const char *code) {
size_t index = 0; size_t index = 0;
while (*ptr) { while (*ptr) {
if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr == '_')) { if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') ||
while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= '0' && *ptr <= '9') || (*ptr == '_')) { (*ptr == '_')) {
while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') ||
(*ptr >= '0' && *ptr <= '9') || (*ptr == '_')) {
buffer[index++] = *ptr++; buffer[index++] = *ptr++;
} }
buffer[index] = 0; buffer[index] = 0;
@ -125,7 +136,8 @@ void parse_markdown_to_ansi(const char *markdown) {
} }
if (inside_code) { if (inside_code) {
char code_buffer[1024*1024] = {0};; char code_buffer[1024 * 1024] = {0};
;
size_t index = 0; size_t index = 0;
while (*ptr && *ptr != '`') { while (*ptr && *ptr != '`') {
@ -147,7 +159,8 @@ void parse_markdown_to_ansi(const char *markdown) {
while (*ptr && strncmp(ptr, "**", 2) != 0) { while (*ptr && strncmp(ptr, "**", 2) != 0) {
putchar(*ptr++); putchar(*ptr++);
} }
if (*ptr == '*' && *(ptr + 1) == '*') ptr += 2; if (*ptr == '*' && *(ptr + 1) == '*')
ptr += 2;
printf(RESET); printf(RESET);
} else if (*ptr == '*' && (ptr == markdown || *(ptr - 1) != '*')) { } else if (*ptr == '*' && (ptr == markdown || *(ptr - 1) != '*')) {
printf(ITALIC); printf(ITALIC);
@ -155,7 +168,8 @@ void parse_markdown_to_ansi(const char *markdown) {
while (*ptr && *ptr != '*') { while (*ptr && *ptr != '*') {
putchar(*ptr++); putchar(*ptr++);
} }
if (*ptr == '*') ptr++; if (*ptr == '*')
ptr++;
printf(RESET); printf(RESET);
} else if (strncmp(ptr, "### ", 4) == 0) { } else if (strncmp(ptr, "### ", 4) == 0) {
printf(BOLD FG_YELLOW); printf(BOLD FG_YELLOW);

View File

@ -1,20 +1,33 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This code manages a collection of messages using JSON objects. It provides functions to retrieve all messages as a JSON array, add a new message with a specified role and content, and free the allocated resources. // This code manages a collection of messages using JSON objects. It provides
// functions to retrieve all messages as a JSON array, add a new message with a
// specified role and content, and free the allocated resources.
// Uses the external library <json-c/json.h> for JSON manipulation // Uses the external library <json-c/json.h> for JSON manipulation
// MIT License // MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: // Permission is hereby granted, free of charge, to any person obtaining a copy
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. // of this software and associated documentation files (the "Software"), to deal
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: The above copyright
// notice and this permission notice shall be included in all copies or
// substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
// THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef R_MESSAGES_H #ifndef R_MESSAGES_H
#define R_MESSAGES_H #define R_MESSAGES_H
#include <string.h>
#include "tools.h"
#include "json-c/json.h" #include "json-c/json.h"
#include "tools.h"
#include <string.h>
struct json_object *message_array = NULL; struct json_object *message_array = NULL;
@ -39,19 +52,21 @@ void messages_remove(){
continue; continue;
} }
struct json_object *message_add_tool_call(struct json_object *message) { struct json_object *message_add_tool_call(struct json_object *message) {
struct json_object *messages = message_list(); struct json_object *messages = message_list();
json_object_array_add(messages, message); json_object_array_add(messages, message);
return message; return message;
} }
struct json_object *message_add_tool_result(const char *tool_call_id, const char *tool_result) { struct json_object *message_add_tool_result(const char *tool_call_id,
const char *tool_result) {
struct json_object *messages = message_list(); struct json_object *messages = message_list();
struct json_object *message = json_object_new_object(); struct json_object *message = json_object_new_object();
json_object_object_add(message, "tool_call_id", json_object_new_string(tool_call_id)); json_object_object_add(message, "tool_call_id",
json_object_object_add(message, "tool_result", json_object_new_string(tool_result)); json_object_new_string(tool_call_id));
json_object_object_add(message, "tool_result",
json_object_new_string(tool_result));
json_object_array_add(messages, message); json_object_array_add(messages, message);
return message; return message;
@ -77,7 +92,8 @@ struct json_object *message_add(const char *role, const char *content) {
} }
char *message_json() { char *message_json() {
return (char *)json_object_to_json_string_ext(message_list(), JSON_C_TO_STRING_PRETTY); return (char *)json_object_to_json_string_ext(message_list(),
JSON_C_TO_STRING_PRETTY);
} }
void message_free() { void message_free() {

View File

@ -1,8 +1,11 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This code interacts with OpenAI's API to perform various tasks such as fetching models, sending chat messages, and processing responses. // This code interacts with OpenAI's API to perform various tasks such as
// fetching models, sending chat messages, and processing responses.
// Uncommon imports include "http.h", "chat.h", and "http_curl.h". These may be internal or external libraries providing HTTP and JSON communication capabilities required to interact with APIs. // Uncommon imports include "http.h", "chat.h", and "http_curl.h". These may be
// internal or external libraries providing HTTP and JSON communication
// capabilities required to interact with APIs.
// MIT License // MIT License
// //
@ -15,8 +18,8 @@
// copies of the Software, and to permit persons to whom the Software is // copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: // furnished to do so, subject to the following conditions:
// //
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in
// copies or substantial portions of the Software. // all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@ -26,14 +29,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
#ifndef R_OPENAI_H #ifndef R_OPENAI_H
#define R_OPENAI_H #define R_OPENAI_H
#include "chat.h" #include "chat.h"
#include "http_curl.h" #include "http_curl.h"
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
char *openai_fetch_models() { char *openai_fetch_models() {
const char *api_url = "https://api.openai.com/v1/models"; const char *api_url = "https://api.openai.com/v1/models";
@ -45,7 +47,8 @@ bool openai_system(char* message_content) {
return true; return true;
} }
struct json_object* openai_process_chat_message(const char* api_url, const char* json_data) { struct json_object *openai_process_chat_message(const char *api_url,
const char *json_data) {
char *response = curl_post(api_url, json_data); char *response = curl_post(api_url, json_data);
struct json_object *parsed_json = json_tokener_parse(response); struct json_object *parsed_json = json_tokener_parse(response);
if (!parsed_json) { if (!parsed_json) {
@ -57,8 +60,6 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
char *all_messages = (char *)json_object_to_json_string(message_array); char *all_messages = (char *)json_object_to_json_string(message_array);
fprintf(stderr, "Messages: "); fprintf(stderr, "Messages: ");
fwrite(all_messages, strlen(all_messages), 1, stderr); fwrite(all_messages, strlen(all_messages), 1, stderr);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -80,7 +81,8 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
json_object_put(parsed_json); json_object_put(parsed_json);
return NULL; return NULL;
} }
struct json_object* first_choice = json_object_array_get_idx(choices_array, 0); struct json_object *first_choice =
json_object_array_get_idx(choices_array, 0);
if (!first_choice) { if (!first_choice) {
fprintf(stderr, "Failed to get the first element of 'choices'.\n"); fprintf(stderr, "Failed to get the first element of 'choices'.\n");
json_object_put(parsed_json); json_object_put(parsed_json);
@ -96,14 +98,16 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
} }
char *openai_chat(const char *user_role, const char *message_content) { char *openai_chat(const char *user_role, const char *message_content) {
if(message_content == NULL || *message_content == '\0' || *message_content == '\n') { if (message_content == NULL || *message_content == '\0' ||
*message_content == '\n') {
return NULL; return NULL;
} }
const char *api_url = "https://api.openai.com/v1/chat/completions"; const char *api_url = "https://api.openai.com/v1/chat/completions";
char *json_data = chat_json(user_role, message_content); char *json_data = chat_json(user_role, message_content);
struct json_object* message_object = openai_process_chat_message(api_url, json_data); struct json_object *message_object =
openai_process_chat_message(api_url, json_data);
message_add_object(message_object); message_add_object(message_object);
if (message_object == NULL) { if (message_object == NULL) {
printf("ERROR + NULL IS SUCCESS\n"); printf("ERROR + NULL IS SUCCESS\n");
@ -116,18 +120,21 @@ char* openai_chat(const char* user_role, const char* message_content) {
struct json_object *tool_call_results = tools_execute(tool_calls); struct json_object *tool_call_results = tools_execute(tool_calls);
int results_count = json_object_array_length(tool_call_results); int results_count = json_object_array_length(tool_call_results);
for (int i = 0; i < results_count; i++) { for (int i = 0; i < results_count; i++) {
struct json_object* tool_call_result = json_object_array_get_idx(tool_call_results, i); struct json_object *tool_call_result =
json_object_array_get_idx(tool_call_results, i);
message_add_tool_call(tool_call_result); message_add_tool_call(tool_call_result);
} }
char *tool_calls_result_str = chat_json(NULL, NULL); char *tool_calls_result_str = chat_json(NULL, NULL);
message_object = openai_process_chat_message(api_url, tool_calls_result_str); message_object =
openai_process_chat_message(api_url, tool_calls_result_str);
if (message_object == NULL) { if (message_object == NULL) {
return NULL; return NULL;
} }
message_add_object(message_object); message_add_object(message_object);
// message_add_tool_call(message_object); // message_add_tool_call(message_object);
} }
const char* content_str = json_object_get_string(json_object_object_get(message_object, "content")); const char *content_str =
json_object_get_string(json_object_object_get(message_object, "content"));
return strdup(content_str); return strdup(content_str);
} }

View File

@ -1,23 +1,26 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This source code initializes a Python interpreter within a plugin, executes a provided Python script with some basic imports, and finalizes the Python environment when done. // This source code initializes a Python interpreter within a plugin, executes a
// provided Python script with some basic imports, and finalizes the Python
// environment when done.
// This code does not use any non-standard imports or includes aside from Python.h and structmember.h which are part of Python's C API. // This code does not use any non-standard imports or includes aside from
// Python.h and structmember.h which are part of Python's C API.
// MIT License // MIT License
#include <Python.h> #include <Python.h>
#include <structmember.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <structmember.h>
bool plugin_initialized = false; bool plugin_initialized = false;
bool plugin_construct() { bool plugin_construct() {
if (plugin_initialized) return true; if (plugin_initialized)
return true;
Py_Initialize(); Py_Initialize();
if (!Py_IsInitialized()) { if (!Py_IsInitialized()) {
@ -54,5 +57,6 @@ void plugin_run(char *src) {
} }
void plugin_destruct() { void plugin_destruct() {
if (plugin_initialized) Py_Finalize(); if (plugin_initialized)
Py_Finalize();
} }

8
r.h
View File

@ -1,10 +1,10 @@
#ifndef R_H #ifndef R_H
#define R_H #define R_H
#include "auth.h"
#include "malloc.h" #include "malloc.h"
#include "utils.h"
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "utils.h"
#include "auth.h"
bool is_verbose = false; bool is_verbose = false;
char *_model = NULL; char *_model = NULL;
@ -13,9 +13,6 @@ char * _model = NULL;
static int prompt_max_tokens = 10000; static int prompt_max_tokens = 10000;
#define PROMPT_TEMPERATURE 0.1 #define PROMPT_TEMPERATURE 0.1
void set_prompt_model(const char *model) { void set_prompt_model(const char *model) {
if (_model != NULL) { if (_model != NULL) {
free(_model); free(_model);
@ -34,5 +31,4 @@ const char * get_prompt_model() {
return _model; return _model;
} }
#endif #endif

View File

@ -1,8 +1,9 @@
/* Written by retoor@molodetz.nl */ /* Written by retoor@molodetz.nl */
/* /*
This C extension for Python provides a simple API for communication with an OpenAI service. This C extension for Python provides a simple API for communication with an
It includes functions to return a "Hello World" string, conduct a chat session through OpenAI, and reset the message history. OpenAI service. It includes functions to return a "Hello World" string, conduct
a chat session through OpenAI, and reset the message history.
*/ */
/* /*
@ -34,9 +35,9 @@ SOFTWARE.
*/ */
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "openai.h"
#include "auth.h" #include "auth.h"
#include "openai.h"
#include <Python.h>
static PyObject *rpylib_reset(PyObject *self, PyObject *args) { static PyObject *rpylib_reset(PyObject *self, PyObject *args) {
return PyUnicode_FromString("True"); return PyUnicode_FromString("True");
@ -45,7 +46,6 @@ static PyObject* rpylib_reset(PyObject *self, PyObject *args) {
static PyObject *rpylib_chat(PyObject *self, PyObject *args) { static PyObject *rpylib_chat(PyObject *self, PyObject *args) {
const char *role, *message; const char *role, *message;
printf("That goes alright! 1\n"); printf("That goes alright! 1\n");
if (!PyArg_ParseTuple(args, "ss", &role, &message)) { if (!PyArg_ParseTuple(args, "ss", &role, &message)) {
return NULL; return NULL;
@ -83,16 +83,11 @@ static PyMethodDef MyModuleMethods[] = {
//{"prompt", rpylib_prompt, METH_VARARGS, "Prompt to OpenAI."}, //{"prompt", rpylib_prompt, METH_VARARGS, "Prompt to OpenAI."},
//{"system", rpylib_system, METH_VARARGS, "Add system message."}, //{"system", rpylib_system, METH_VARARGS, "Add system message."},
{"reset", rpylib_reset, METH_NOARGS, "Reset message history."}, {"reset", rpylib_reset, METH_NOARGS, "Reset message history."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}};
};
static struct PyModuleDef rpylib = { static struct PyModuleDef rpylib = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT, "rpylib",
"rpylib", "R - the power of R in Python, made by retoor.", -1, MyModuleMethods};
"R - the power of R in Python, made by retoor.",
-1,
MyModuleMethods
};
PyMODINIT_FUNC PyInit_rpylib(void) { PyMODINIT_FUNC PyInit_rpylib(void) {

BIN
rpylib.so

Binary file not shown.

473
tools.h

File diff suppressed because it is too large Load Diff

29
url.h
View File

@ -1,6 +1,7 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This code defines a URL parser in C that extracts components such as the scheme, hostname, port, path, and query from a given URL. // This code defines a URL parser in C that extracts components such as the
// scheme, hostname, port, path, and query from a given URL.
// Includes: // Includes:
// - <stdio.h> for standard I/O operations // - <stdio.h> for standard I/O operations
@ -8,13 +9,26 @@
// - <stdlib.h> for memory allocation and management // - <stdlib.h> for memory allocation and management
// MIT License // MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: The above copyright
// notice and this permission notice shall be included in all copies or
// substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
// THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef R_URL_H #ifndef R_URL_H
#define R_URL_H #define R_URL_H
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
typedef struct { typedef struct {
char scheme[16]; char scheme[16];
@ -49,7 +63,8 @@ int parse_url(const char *url, url_t *parsed_url) {
strncpy(parsed_url->hostname, hostname_start, hostname_length); strncpy(parsed_url->hostname, hostname_start, hostname_length);
parsed_url->hostname[hostname_length] = '\0'; parsed_url->hostname[hostname_length] = '\0';
size_t port_length = query_start ? (size_t)(query_start - port_start - 1) : strlen(port_start + 1); size_t port_length = query_start ? (size_t)(query_start - port_start - 1)
: strlen(port_start + 1);
if (port_length >= sizeof(parsed_url->port)) { if (port_length >= sizeof(parsed_url->port)) {
fprintf(stderr, "Port value is too long\n"); fprintf(stderr, "Port value is too long\n");
return -1; return -1;
@ -57,8 +72,10 @@ int parse_url(const char *url, url_t *parsed_url) {
strncpy(parsed_url->port, port_start + 1, port_length); strncpy(parsed_url->port, port_start + 1, port_length);
parsed_url->port[port_length] = '\0'; parsed_url->port[port_length] = '\0';
} else { } else {
size_t hostname_length = path_start ? (size_t)(path_start - hostname_start) : size_t hostname_length =
(query_start ? (size_t)(query_start - hostname_start) : strlen(hostname_start)); path_start ? (size_t)(path_start - hostname_start)
: (query_start ? (size_t)(query_start - hostname_start)
: strlen(hostname_start));
if (hostname_length >= sizeof(parsed_url->hostname)) { if (hostname_length >= sizeof(parsed_url->hostname)) {
fprintf(stderr, "Hostname is too long\n"); fprintf(stderr, "Hostname is too long\n");
return -1; return -1;

24
utils.h
View File

@ -1,24 +1,30 @@
// Written by retoor@molodetz.nl // Written by retoor@molodetz.nl
// This header file contains utility functions for manipulating file system paths, focusing primarily on expanding paths starting with '~' to the home directory. // This header file contains utility functions for manipulating file system
// paths, focusing primarily on expanding paths starting with '~' to the home
// directory.
// This code uses standard libraries: stdio.h, stdlib.h, and string.h, and conditionally includes the posix libraries pwd.h and unistd.h when expanding the home directory manually. // This code uses standard libraries: stdio.h, stdlib.h, and string.h, and
// conditionally includes the posix libraries pwd.h and unistd.h when expanding
// the home directory manually.
// MIT License // MIT License
// //
// Permission is granted to use, copy, modify, merge, distribute, sublicense, and/or sell copies of the Software. // Permission is granted to use, copy, modify, merge, distribute, sublicense,
// The license includes conditions about providing a copy of the license and the limitation of liability and warranty. // and/or sell copies of the Software. The license includes conditions about
// providing a copy of the license and the limitation of liability and warranty.
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
char *expand_home_directory(const char *path) { char *expand_home_directory(const char *path) {
if (path == NULL) return NULL; if (path == NULL)
return NULL;
if (path[0] == '~' && path[1] == '/') { if (path[0] == '~' && path[1] == '/') {
const char *home_dir = getenv("HOME"); const char *home_dir = getenv("HOME");
@ -26,7 +32,8 @@ char* expand_home_directory(const char* path) {
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
if (pw == NULL) return NULL; if (pw == NULL)
return NULL;
home_dir = pw->pw_dir; home_dir = pw->pw_dir;
} }
@ -34,7 +41,8 @@ char* expand_home_directory(const char* path) {
size_t path_len = strlen(path) - 1; size_t path_len = strlen(path) - 1;
char *expanded_path = malloc(home_len + path_len + 1); char *expanded_path = malloc(home_len + path_len + 1);
if (expanded_path == NULL) return NULL; if (expanded_path == NULL)
return NULL;
strcpy(expanded_path, home_dir); strcpy(expanded_path, home_dir);
strcat(expanded_path, path + 1); strcat(expanded_path, path + 1);