diff --git a/Makefile b/Makefile index 5a5ca2c..36c1f63 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,11 @@ all: build run build: # -lpython3.14 -I/usr/include/python3.14 - gcc main.c -lcurl -lssl -lcrypto -ljson-c -Ofast -o r -Werror -Wall -lreadline -lncurses + gcc main.c -Ofast -o r -Werror -Wall -lreadline -lncurses -lcurl -lssl -lcrypto -ljson-c -lm publish r build_free: - gcc main.c -lcurl -DFREE_VERSION -lssl -lcrypto -ljson-c -Ofast -o rf -Werror -Wall -lreadline -lncurses + gcc main.c -lcurl -DFREE_VERSION -lssl -lcrypto -ljson-c -Ofast -o rf -Werror -Wall -lreadline -lncurses -lm publish rf run: diff --git a/auth.h b/auth.h index 4050231..a4385f8 100644 --- a/auth.h +++ b/auth.h @@ -6,7 +6,6 @@ // MIT License - #ifndef R_AUTH_H #define R_AUTH_H @@ -15,20 +14,18 @@ const char *resolve_api_key() { static char *api_key = NULL; - #ifndef FREE_VERSION - api_key = getenv("R_KEY"); - if (api_key) { - return api_key; - } - api_key = getenv("OPENAI_API_KEY"); - if (api_key) { - return api_key; - } - fprintf(stderr, "\nThere is no API key configured in the environment.\n"); - exit(1); - #endif + api_key = getenv("R_KEY"); + if (api_key) { + return api_key; + } + api_key = getenv("OPENAI_API_KEY"); + if (api_key) { + return api_key; + } + fprintf(stderr, "\nThere is no API key configured in the environment.\n"); api_key = "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"; return api_key; } -#endif \ No newline at end of file +#endif + diff --git a/main.c b/main.c index e2f7496..6984990 100644 --- a/main.c +++ b/main.c @@ -28,6 +28,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + #include "openai.h" #include "markdown.h" #include "line.h" @@ -38,6 +44,7 @@ #include <unistd.h> #include "utils.h" + bool SYNTAX_HIGHLIGHT_ENABLED = true; bool API_MODE = false; void help(); @@ -67,7 +74,19 @@ char *get_prompt_from_args(int c, char **argv) { if (!strcmp(argv[i],"--stdin")){ fprintf(stderr, "%s\n", "Reading from stdin."); get_from_std_in = true; - }else if(!strcmp(argv[i],"--context")){ + }else if(!strcmp(argv[i],"--py")){ + if(i+1 <= c){ + char * py_file_path = expand_home_directory(argv[i+1]); + fprintf(stderr, "Including \"%s\".\n", py_file_path); + openai_include(py_file_path); + free(py_file_path); + //char * file_content = read_file(py_file_path); + //plugin_run(file_content); + i++; + } + } + + else if(!strcmp(argv[i],"--context")){ if(i+1 <= c){ char * context_file_path = argv[i+1]; fprintf(stderr, "Including \"%s\".\n", context_file_path); @@ -154,98 +173,8 @@ char ** get_parameters(char * content, char * delimiter){ return parameters; } -void render(char *content){ - - char ** parameters = get_parameters(content,"\"\"\""); - int parameter_index = 0; - bool print_result = true; - while(parameters){ - char * parameter = parameters[parameter_index]; - if(!parameter) - break; - print_result = false; - if(!strcmp(parameter, "!find_note")){ - char * note_name = parameters[parameter_index + 1]; - FILE * file = fopen("notes.txt", "r"); - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - - char *buffer = (char *)malloc(size + 1); - size = fread(buffer, 1, size, file); - buffer[size] = '\0'; - fclose(file); - char * prompt = (char *)malloc(size + 1000); - prompt[0] = 0; - sprintf(prompt,"This are records seperated by newline: ```%s```. Respond to use with record that is about ```%s```. Rspond in plain text, do not execute command.",buffer, note_name); - char* result = openai_chat("user",prompt); - - - free(buffer); - free(prompt); - if(result){ - printf("%s\n",result); - free(result); - } - } - - if(!strcmp(parameter, "!write_note")){ - char * file_name = "notes.txt"; - char * file_content = parameters[parameter_index + 1]; - FILE * file = fopen(file_name, "a+"); - fprintf(file, "%s\n\n", file_content); - fclose(file); - } - if(!strcmp(parameter, "!write_file")){ - - char * file_name = parameters[parameter_index + 1]; - - printf("Writing to file: %s\n",file_name); - char * file_content = parameters[parameter_index + 2]; - FILE * file = fopen(file_name, "w"); - fprintf(file, "%s", file_content); - fclose(file); - - } - if(!strcmp(parameter, "!system")){ - // printf("%s\n",parameters[parameter_index+1]); - char * command = parameters[parameter_index + 1]; - FILE * f = popen(command,"r");; - if(!f){ - printf("Execution failed: %s\n",command); - } - char buffer[4096]; - char * full_buffer = (char *)malloc(1); - int bytes_read = 0; - while (fgets(buffer, sizeof(buffer), f) != NULL) { - full_buffer = realloc(full_buffer, bytes_read + strlen(buffer) + 1); - memcpy(full_buffer + bytes_read, buffer, strlen(buffer)); - bytes_read += strlen(buffer); - printf("%s",buffer); - fflush(stdout); - } - pclose(f); - full_buffer[bytes_read] = '\0'; - //printf("%s",full_buffer); - char * prompt = (char *)malloc(strlen(full_buffer) + 1000); - prompt[0] = 0; - printf(prompt,"Last execution result and thus current context is: ```%s```\n",full_buffer); - char * rmsg = openai_chat("system",full_buffer); - - //printf("%s\n",rmsg); - free(prompt); - free(rmsg); - free(full_buffer); - - }else if(parameter[0] == '!'){ - printf("%s\n",parameter); - } - parameter_index+= 1; - - } - if(!print_result){ - return; - } +void render(char *content) +{ if(SYNTAX_HIGHLIGHT_ENABLED) { @@ -259,15 +188,16 @@ void render(char *content){ void repl() { line_init(); char *line = NULL; - char *previous_line = NULL; + //char *previous_line = NULL; while (true) { line = line_read("> "); if (!line || !*line) { - line = previous_line; + continue; + //line = previous_line; } if (!line || !*line) continue; - previous_line = line; + // previous_line = line; if (!strncmp(line, "exit", 4)) { exit(0); @@ -276,43 +206,22 @@ void repl() { help(); continue; } - if (!strncmp(line, "serve", 5)) { - continue ; - serve(); - } - if(!strncmp(line,"retoor",6)){ - openai_include("retoor"); - } - if (!strncmp(line, "spar ", 5)) { - char *response = line + 5; - while (true) { - render(response); - sleep(2); - response = openai_chat("user", response); - } - } - if (!strncmp(line, "/_", 2) || !strncmp(line, "____", 4)) { - continue; - int offset = 2; - if (!strncmp(line, "list", 4)) { - offset = 4; - } - char *command = (char *)malloc(strlen(line) + 42); - command[0] = '\0'; - strcpy(command, "ls "); - strcat(command, line + offset); - int res = system(command); - (void)res; - free(command); - continue; - } - if(*line){ + while(line && *line != '\n'){ line_add_history(line); char *response = openai_chat("user", line); if(response){ render(response); printf("\n"); + if(strstr(response,"_STEP_")){ + line = "continue"; + + }else{ + + line = NULL; + } + free(response); + } } } @@ -363,52 +272,17 @@ char * linux_instructions = 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) { - if(!strcmp(path,"retoor")){ - render("**Loading retoor.**"); - size_t new_size = strlen(linux_instructions) + strlen(retoor_instructions)+10; - char * all = (char *)malloc(new_size); - memset(all,0,new_size); - strcpy(all,linux_instructions); - strcat(all,retoor_instructions); - openai_chat("system",all); - free(all); - render("**Retoor is loaded. Retoor can do bash. Retoor can do all the bash.**"); - render("Let's diagnose your computer and network together by asking things like: \n" - " 1. how many devices are there on my network? Check also MDNS devices. \n" - " 2 does my network does something suspicious? \n" - " 3. can you benchmark https://molodetz.nl?\n" - " 4. do i run strange processes?\n" - " 5. what is the performance of my pc?\n" - " 6. describe my hardware.\n" - " 7. please make a backup from my current directory.\n" - " 8. find ten largest folders on my pc using sudo."); - return true; - } - char * expanded_path = expand_home_directory(path); - FILE *file = fopen(expanded_path, "r"); - free(expanded_path); - if (file == NULL) { + char * file_content = read_file(path); + if(!file_content){ return false; } - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - - char *buffer = (char *)malloc(size + 1); - size_t read = fread(buffer, 1, size, file); - if (read == 0) { - return false; - } - - fclose(file); - buffer[read] = '\0'; - char * replaced_linux = strreplace(buffer,"[linux]", linux_instructions); - char * replaced_retoor = strreplace(replaced_linux,"[retoor]", retoor_instructions); - openai_system(replaced_retoor); - free(replaced_retoor); - free(replaced_linux); - free(buffer); + openai_system(file_content); + free(file_content); return true; } diff --git a/openai.h b/openai.h index c693e11..e9469d3 100644 --- a/openai.h +++ b/openai.h @@ -54,7 +54,6 @@ struct json_object* openai_process_chat_message(const char* api_url, const char* } struct json_object *error_object; if (json_object_object_get_ex(parsed_json, "error", &error_object)) { - fprintf(stderr, "Failed to get 'error' object.\n%s\n", response); json_object_put(parsed_json); char *all_messages = (char *)json_object_to_json_string(message_array); fprintf(stderr, "Messages: "); @@ -88,6 +87,11 @@ struct json_object* openai_process_chat_message(const char* api_url, const char* } char* openai_chat(const char* user_role, const char* message_content) { + if(message_content == NULL || *message_content == '\0' || *message_content == '\n') { + return NULL; + } + + const char* api_url = "https://api.openai.com/v1/chat/completions"; char* json_data = chat_json(user_role, message_content); struct json_object* message_object = openai_process_chat_message(api_url, json_data); @@ -116,4 +120,4 @@ char* openai_chat(const char* user_role, const char* message_content) { return strdup(content_str); } -#endif \ No newline at end of file +#endif diff --git a/plugin.h b/plugin.h index 5bd1095..0461d56 100644 --- a/plugin.h +++ b/plugin.h @@ -7,8 +7,8 @@ // MIT License -#include <python3.14/Python.h> -#include <python3.14/structmember.h> +#include <Python.h> +#include <structmember.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -30,7 +30,7 @@ bool plugin_construct() { void plugin_run(char *src) { plugin_construct(); - const char *basics = + /*const char *basics = "import sys\n" "import os\n" "from os import *\n" @@ -43,7 +43,9 @@ void plugin_run(char *src) { "import time\n" "from datetime import datetime\n" "%s"; - size_t length = strlen(basics) + strlen(src); + */ + const char *basics = "\n\n"; + size_t length = strlen(basics) + strlen(src); char *script = malloc(length + 1); sprintf(script, basics, src); script[length] = '\0'; @@ -53,4 +55,4 @@ void plugin_run(char *src) { void plugin_destruct() { if (plugin_initialized) Py_Finalize(); -} \ No newline at end of file +} diff --git a/tools.h b/tools.h index 0ee669e..d644e46 100644 --- a/tools.h +++ b/tools.h @@ -9,6 +9,7 @@ #ifndef R_TOOLS_H #define R_TOOLS_H +#include <stdio.h> #include <json-c/json.h> #include <json-c/json_object.h> #include <string.h> @@ -17,6 +18,12 @@ #include <sys/stat.h> #include <time.h> #include <glob.h> +#include <unistd.h> +#include "utils.h" +#include <stdbool.h> + +#include <stdlib.h> +#include <string.h> struct json_object* tool_description_http_get(); struct json_object* tool_description_linux_terminal(); @@ -227,8 +234,12 @@ struct json_object* tool_description_write_file() { } char* tool_function_read_file(char* path) { - fprintf(stderr, "Tools read_file: %s\n", path); - FILE* fp = fopen(path, "r"); + + char * expanded_path = expand_home_directory(path); + fprintf(stderr, "Tools read_file: %s\n", expanded_path); + + FILE* fp = fopen(expanded_path, "r"); + free(expanded_path); if (fp == NULL) { perror("fopen failed"); return strdup("Failed to open file for reading!"); @@ -238,7 +249,7 @@ char* tool_function_read_file(char* path) { long size = ftell(fp); rewind(fp); - char* content = malloc(size + 1); + char* content = (char *)malloc(size + 1); if (content == NULL) { fclose(fp); return strdup("Memory allocation failed!"); @@ -677,4 +688,4 @@ struct json_object* tools_execute(struct json_object* tools_array) { return tools_result_messages; } -#endif \ No newline at end of file +#endif diff --git a/utils.h b/utils.h index a096ba8..3ec3570 100644 --- a/utils.h +++ b/utils.h @@ -43,5 +43,26 @@ char* expand_home_directory(const char* path) { return strdup(path); } } +char * read_file(const char * path) { + char * expanded_path = expand_home_directory(path); + FILE *file = fopen(expanded_path, "r"); + free(expanded_path); + if (file == NULL) { + return NULL; + } + fseek(file, 0, SEEK_END); + long size = ftell(file); + fseek(file, 0, SEEK_SET); -#endif \ No newline at end of file + char *buffer = (char *)malloc(size + 1); + size_t read = fread(buffer, 1, size, file); + if (read == 0) { + free(buffer); + return NULL; + } + + fclose(file); + buffer[read] = '\0'; + return buffer; +} +#endif