diff --git a/auth.h b/auth.h index b8b4cac..4050231 100644 --- a/auth.h +++ b/auth.h @@ -1,8 +1,8 @@ // Written by retoor@molodetz.nl -// This source code declares a constant character pointer variable that retrieves an API key from environment variables or falls back to a hardcoded key if not found. +// This source code retrieves an API key from environment variables or defaults to a hardcoded key if none are found. -// Uses standard library functions from stdlib.h and stdio.h to manage environment variables and output error messages. +// Uses the C standard library functions from stdlib.h for environment management and stdio.h for error handling. // MIT License @@ -26,7 +26,7 @@ const char *resolve_api_key() { } fprintf(stderr, "\nThere is no API key configured in the environment.\n"); exit(1); - #endif + #endif api_key = "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"; return api_key; } diff --git a/chat.h b/chat.h index f93c25c..c1df187 100644 --- a/chat.h +++ b/chat.h @@ -35,14 +35,14 @@ #include "messages.h" #ifdef FREE_VERSION -char *prompt_model = "gpt-3.5-turbo"; +static char *prompt_model = "gpt-3.5-turbo"; #else -char *prompt_model = "gpt-4o-mini"; +static char *prompt_model = "gpt-4o-mini"; #endif -int prompt_max_tokens = 2048; -double prompt_temperature = 0.1; +static int prompt_max_tokens = 2048; +static double prompt_temperature = 0.1; -json_object *_prompt = NULL; +static json_object *_prompt = NULL; void chat_free() { if (_prompt == NULL) return; @@ -52,7 +52,7 @@ void chat_free() { char *chat_json(const char *role, const char *message) { chat_free(); - struct 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(prompt_model)); if (role != NULL && message != NULL) { @@ -67,4 +67,4 @@ char *chat_json(const char *role, const char *message) { return (char *)json_object_to_json_string_ext(root_object, JSON_C_TO_STRING_PRETTY); } -#endif +#endif \ No newline at end of file diff --git a/http_curl.h b/http_curl.h index 41afd43..09dbfd8 100644 --- a/http_curl.h +++ b/http_curl.h @@ -1,6 +1,6 @@ // Written by retoor@molodetz.nl -// This code defines a simple HTTP client using libcurl in C, providing functions `curl_post` and `curl_get`. These functions enable POST and GET requests with JSON data and include authorization via a bearer token. +// 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. @@ -20,6 +20,7 @@ // from, out of or in connection with the software or the use or other dealings in // the Software. + #ifndef HTTP_CURL #define HTTP_CURL @@ -52,18 +53,18 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *use char *curl_post(const char *url, const char *data) { CURL *curl; CURLcode res; - struct ResponseBuffer response; - response.data = malloc(1); - response.size = 0; + struct ResponseBuffer response = {malloc(1), 0}; + + if (!response.data) return NULL; + curl = curl_easy_init(); if (curl) { struct curl_slist *headers = NULL; curl_easy_setopt(curl, CURLOPT_URL, url); headers = curl_slist_append(headers, "Content-Type: application/json"); - char *bearer_header = malloc(1337); + char bearer_header[1337]; sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key()); headers = curl_slist_append(headers, bearer_header); - free(bearer_header); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); @@ -91,25 +92,19 @@ char *curl_get(const char *url) { struct curl_slist *headers = NULL; curl_easy_setopt(curl, CURLOPT_URL, url); headers = curl_slist_append(headers, "Content-Type: application/json"); - - char *bearer_header = malloc(1337); + char bearer_header[1337]; sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key()); headers = curl_slist_append(headers, bearer_header); - free(bearer_header); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); - res = curl_easy_perform(curl); if (res != CURLE_OK) { fprintf(stderr, "An error occurred: %s\n", curl_easy_strerror(res)); } - curl_slist_free_all(headers); curl_easy_cleanup(curl); } - return response.data; } diff --git a/inplace_url.h b/inplace_url.h index f37dd0a..9e0f373 100644 --- a/inplace_url.h +++ b/inplace_url.h @@ -2,7 +2,7 @@ // 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 diff --git a/line.h b/line.h index 9738cf9..ba0443b 100644 --- a/line.h +++ b/line.h @@ -1,6 +1,6 @@ // Written by retoor@molodetz.nl -// This source code provides command-line input functionalities with autocomplete and history features using readline library functionalities. 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: // - <readline/readline.h> @@ -52,9 +52,7 @@ void line_init() { char* line_read(char* prefix) { char* data = readline(prefix); if (!(data && *data)) { - if (data) { - free(data); - } + free(data); return NULL; } return data; @@ -63,4 +61,4 @@ char* line_read(char* prefix) { void line_add_history(char* data) { add_history(data); write_history(HISTORY_FILE); -} +} \ No newline at end of file diff --git a/messages.h b/messages.h index cfe0808..d5dc07b 100644 --- a/messages.h +++ b/messages.h @@ -25,12 +25,11 @@ struct json_object *message_list() { return message_array; } - -void messages_remove_last(){ +void messages_remove_last() { struct json_object *messages = message_list(); int size = json_object_array_length(messages); - if(size){ - json_object_array_del_idx(messages, size - 1,1); + if (size) { + json_object_array_del_idx(messages, size - 1, 1); } } @@ -40,7 +39,7 @@ struct json_object *message_add_tool_call(struct json_object *message) { return message; } -struct json_object *message_add_tool_result(char *tool_call_id, 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 *message = json_object_new_object(); @@ -76,4 +75,4 @@ void message_free() { } } -#endif +#endif \ No newline at end of file diff --git a/openai.h b/openai.h index 5c30539..c693e11 100644 --- a/openai.h +++ b/openai.h @@ -1,10 +1,9 @@ // 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. - // MIT License // // Copyright (c) 2023 @@ -50,16 +49,16 @@ struct json_object* openai_process_chat_message(const char* api_url, const char* char* response = curl_post(api_url, json_data); struct json_object* parsed_json = json_tokener_parse(response); if (!parsed_json) { - fprintf(stderr, "Failed to parse JSON.\n %s \n", response); + fprintf(stderr, "Failed to parse JSON.\n%s\n", response); return NULL; } 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); + 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); + char *all_messages = (char *)json_object_to_json_string(message_array); fprintf(stderr, "Messages: "); - fwrite(all_messages,strlen(all_messages),1, stderr); + fwrite(all_messages, strlen(all_messages), 1, stderr); fprintf(stderr, "\n"); free(all_messages); messages_remove_last(); @@ -69,7 +68,7 @@ struct json_object* openai_process_chat_message(const char* api_url, const char* struct json_object* choices_array; if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) { - fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response); + fprintf(stderr, "Failed to get 'choices' array.\n%s\n", response); json_object_put(parsed_json); return NULL; } @@ -92,9 +91,9 @@ char* openai_chat(const char* user_role, const char* message_content) { 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); - if(message_object == NULL) { + if (message_object == NULL) { printf("ERROR + NULL IS SUCCESS\n"); - return NULL; + return NULL; } struct json_object* tool_calls; json_object_object_get_ex(message_object, "tool_calls", &tool_calls); @@ -108,8 +107,8 @@ char* openai_chat(const char* user_role, const char* message_content) { } char* tool_calls_result_str = chat_json(NULL, NULL); message_object = openai_process_chat_message(api_url, tool_calls_result_str); - if(message_object == NULL) { - return NULL; + if (message_object == NULL) { + return NULL; } message_add_tool_call(message_object); } @@ -117,4 +116,4 @@ char* openai_chat(const char* user_role, const char* message_content) { return strdup(content_str); } -#endif +#endif \ No newline at end of file diff --git a/tools.h b/tools.h index 0e41b8c..0ee669e 100644 --- a/tools.h +++ b/tools.h @@ -18,16 +18,16 @@ #include <time.h> #include <glob.h> -struct json_object *tool_description_http_get(); -struct json_object *tool_description_linux_terminal(); -struct json_object *tool_description_directory_glob(); -struct json_object *tool_description_read_file(); -struct json_object *tool_description_write_file(); -struct json_object *tool_description_directory_rglob(); -struct json_object *tool_description_linux_terminal_interactive(); +struct json_object* tool_description_http_get(); +struct json_object* tool_description_linux_terminal(); +struct json_object* tool_description_directory_glob(); +struct json_object* tool_description_read_file(); +struct json_object* tool_description_write_file(); +struct json_object* tool_description_directory_rglob(); +struct json_object* tool_description_linux_terminal_interactive(); -struct json_object *tools_descriptions() { - struct json_object *root = json_object_new_array(); +struct json_object* tools_descriptions() { + struct json_object* root = json_object_new_array(); json_object_array_add(root, tool_description_http_get()); json_object_array_add(root, tool_description_linux_terminal()); json_object_array_add(root, tool_description_directory_glob()); @@ -38,17 +38,17 @@ struct json_object *tools_descriptions() { return root; } -char *tool_function_http_get(char *url) { +char* tool_function_http_get(char* url) { fprintf(stderr, "Tool http_get: %s\n", url); return curl_get(url); } -char *tool_function_linux_terminal(char *command) { +char* tool_function_linux_terminal(char* command) { fprintf(stderr, "Tool linux_terminal: %s\n", command); - FILE *fp; + FILE* fp; char buffer[1024]; size_t total_size = 0; - char *output = NULL; + char* output = NULL; fp = popen(command, "r"); if (fp == NULL) { @@ -58,7 +58,7 @@ char *tool_function_linux_terminal(char *command) { while (fgets(buffer, sizeof(buffer), fp) != NULL) { size_t chunk_size = strlen(buffer); - char *new_output = (char *)realloc(output, total_size + chunk_size + 1); + char* new_output = realloc(output, total_size + chunk_size + 1); if (new_output == NULL) { perror("realloc failed"); free(output); @@ -74,41 +74,41 @@ char *tool_function_linux_terminal(char *command) { return output ? output : strdup(""); } -char *tool_function_linux_terminal_interactive(char *command) { +char* tool_function_linux_terminal_interactive(char* command) { fprintf(stderr, "Tool linux_terminal_interactive: %s\n", command); int result_code = system(command); - char * result = (char *)malloc(100); + char* result = malloc(100); result[0] = 0; sprintf(result, "Command exited with status code %d.", result_code); return result; } -struct json_object *tool_description_linux_terminal_interactive() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_linux_terminal_interactive() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - struct json_object *function = json_object_new_object(); + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("linux_terminal_execute_interactive")); json_object_object_add(function, "description", json_object_new_string("Executes interactive terminal for user. You will not be able to read the result. Do not use if you need to know output.")); - struct json_object *parameters = json_object_new_object(); + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - struct json_object *properties = json_object_new_object(); - struct json_object *path = json_object_new_object(); + struct json_object* properties = json_object_new_object(); + struct json_object* path = json_object_new_object(); json_object_object_add(path, "type", json_object_new_string("string")); - json_object_object_add(path, "description", json_object_new_string("Executable with parameters to execute interactive."));; + json_object_object_add(path, "description", json_object_new_string("Executable with parameters to execute interactively.")); json_object_object_add(properties, "command", path); json_object_object_add(parameters, "properties", properties); - struct json_object *required = json_object_new_array(); + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("command")); json_object_object_add(parameters, "required", required); - + json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(function, "parameters", parameters); @@ -119,30 +119,27 @@ struct json_object *tool_description_linux_terminal_interactive() { return root; } - - - -struct json_object *tool_description_directory_rglob() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_directory_rglob() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - struct json_object *function = json_object_new_object(); + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("directory_rglob")); json_object_object_add(function, "description", json_object_new_string("Recursively list the contents of a specified directory in glob format. " - "Result is a json array containing objects with keys: name, modification_date(iso), creation_date(iso), type and size_bytes.")); + "Result is a JSON array containing objects with keys: name, modification_date(iso), creation_date(iso), type, and size_bytes.")); - struct json_object *parameters = json_object_new_object(); + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - struct json_object *properties = json_object_new_object(); - struct json_object *directory = json_object_new_object(); + struct json_object* properties = json_object_new_object(); + struct json_object* directory = json_object_new_object(); json_object_object_add(directory, "type", json_object_new_string("string")); json_object_object_add(directory, "description", json_object_new_string("Path to the directory to list in glob format.")); json_object_object_add(properties, "path", directory); json_object_object_add(parameters, "properties", properties); - struct json_object *required = json_object_new_array(); + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("path")); json_object_object_add(parameters, "required", required); @@ -156,29 +153,29 @@ struct json_object *tool_description_directory_rglob() { return root; } -struct json_object *tool_description_read_file() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_read_file() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - struct json_object *function = json_object_new_object(); + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("read_file")); json_object_object_add(function, "description", json_object_new_string("Reads / opens / loads a file and returns its contents as a string.")); - struct json_object *parameters = json_object_new_object(); + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - struct json_object *properties = json_object_new_object(); - struct json_object *path = json_object_new_object(); + struct json_object* properties = json_object_new_object(); + struct json_object* path = json_object_new_object(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add(path, "description", json_object_new_string("Path to the file to read / open / load.")); json_object_object_add(properties, "path", path); json_object_object_add(parameters, "properties", properties); - struct json_object *required = json_object_new_array(); + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("path")); json_object_object_add(parameters, "required", required); - + json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(function, "parameters", parameters); @@ -189,36 +186,36 @@ struct json_object *tool_description_read_file() { return root; } -struct json_object *tool_description_write_file() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_write_file() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - struct json_object *function = json_object_new_object(); + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("write_file")); json_object_object_add(function, "description", json_object_new_string("Writes / saves / stores content to a file.")); - struct json_object *parameters = json_object_new_object(); + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - struct json_object *properties = json_object_new_object(); - - struct json_object *path = json_object_new_object(); + struct json_object* properties = json_object_new_object(); + + struct json_object* path = json_object_new_object(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add(path, "description", json_object_new_string("Path to the file to write / save / store.")); json_object_object_add(properties, "path", path); - struct json_object *content = json_object_new_object(); + struct json_object* content = json_object_new_object(); json_object_object_add(content, "type", json_object_new_string("string")); json_object_object_add(content, "description", json_object_new_string("Content to write / save / store into the file.")); json_object_object_add(properties, "content", content); json_object_object_add(parameters, "properties", properties); - struct json_object *required = json_object_new_array(); + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("path")); json_object_array_add(required, json_object_new_string("content")); json_object_object_add(parameters, "required", required); - + json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(function, "parameters", parameters); @@ -229,9 +226,9 @@ struct json_object *tool_description_write_file() { return root; } -char *tool_function_read_file(char *path) { +char* tool_function_read_file(char* path) { fprintf(stderr, "Tools read_file: %s\n", path); - FILE *fp = fopen(path, "r"); + FILE* fp = fopen(path, "r"); if (fp == NULL) { perror("fopen failed"); return strdup("Failed to open file for reading!"); @@ -241,23 +238,23 @@ char *tool_function_read_file(char *path) { long size = ftell(fp); rewind(fp); - char *content = (char *)malloc(size + 1); + char* content = malloc(size + 1); if (content == NULL) { fclose(fp); return strdup("Memory allocation failed!"); } ssize_t read_size = fread(content, 1, size, fp); - + content[read_size] = '\0'; fclose(fp); return content; } -char *tool_function_write_file(char *path, char *content) { +char* tool_function_write_file(char* path, char* content) { fprintf(stderr, "Tools write_file with %zu bytes: %s\n", strlen(content), path); - FILE *fp = fopen(path, "w"); + FILE* fp = fopen(path, "w"); if (fp == NULL) { perror("fopen failed"); return strdup("Failed to open file for writing!"); @@ -269,18 +266,18 @@ char *tool_function_write_file(char *path, char *content) { return strdup("File successfully written."); } -const char *get_file_type(struct stat *st) { +const char* get_file_type(struct stat* st) { if (S_ISREG(st->st_mode)) return "file"; if (S_ISDIR(st->st_mode)) return "directory"; return "other"; } -void format_time(time_t raw_time, char *buffer, size_t size) { - struct tm *time_info = localtime(&raw_time); +void format_time(time_t raw_time, char* buffer, size_t size) { + struct tm* time_info = localtime(&raw_time); strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info); } -void recursive_glob(const char *pattern, glob_t *results) { +void recursive_glob(const char* pattern, glob_t* results) { glob_t current_matches; int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, ¤t_matches); @@ -296,28 +293,28 @@ void recursive_glob(const char *pattern, glob_t *results) { } for (size_t i = 0; i < current_matches.gl_pathc; i++) { - char *path = current_matches.gl_pathv[i]; + char* path = current_matches.gl_pathv[i]; if (results->gl_pathc == 0) { results->gl_pathc = 1; - results->gl_pathv = malloc(sizeof(char *)); + results->gl_pathv = malloc(sizeof(char*)); results->gl_pathv[0] = strdup(path); } else { results->gl_pathc++; - results->gl_pathv = realloc(results->gl_pathv, - results->gl_pathc * sizeof(char *)); + results->gl_pathv = realloc(results->gl_pathv, + results->gl_pathc * sizeof(char*)); results->gl_pathv[results->gl_pathc - 1] = strdup(path); } } - DIR *dir; - struct dirent *entry; + DIR* dir; + struct dirent* entry; struct stat statbuf; - char *pattern_copy = strdup(pattern); - char *last_slash = strrchr(pattern_copy, '/'); - char *dir_path; - char *file_pattern; + char* pattern_copy = strdup(pattern); + char* last_slash = strrchr(pattern_copy, '/'); + char* dir_path; + char* file_pattern; if (last_slash) { *last_slash = '\0'; @@ -365,7 +362,7 @@ void recursive_glob(const char *pattern, glob_t *results) { globfree(¤t_matches); } -char *tool_function_directory_rglob(char *target_dir) { +char* tool_function_directory_rglob(char* target_dir) { fprintf(stderr, "Tools directory_rglob: %s\n", target_dir); glob_t results; results.gl_pathc = 0; @@ -374,10 +371,10 @@ char *tool_function_directory_rglob(char *target_dir) { recursive_glob(target_dir, &results); - json_object *json_array = json_object_new_array(); + json_object* json_array = json_object_new_array(); for (size_t i = 0; i < results.gl_pathc; i++) { - const char *file_path = results.gl_pathv[i]; + const char* file_path = results.gl_pathv[i]; if (stat(file_path, &file_stat) == -1) { perror("stat failed"); @@ -387,7 +384,7 @@ char *tool_function_directory_rglob(char *target_dir) { format_time(file_stat.st_mtime, mod_time, sizeof(mod_time)); format_time(file_stat.st_ctime, create_time, sizeof(create_time)); - json_object *json_entry = json_object_new_object(); + json_object* json_entry = json_object_new_object(); json_object_object_add(json_entry, "name", json_object_new_string(file_path)); json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time)); json_object_object_add(json_entry, "creation_date", json_object_new_string(create_time)); @@ -398,14 +395,14 @@ char *tool_function_directory_rglob(char *target_dir) { } globfree(&results); - char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); + char* result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); json_object_put(json_array); return result; } -char *tool_function_directory_glob(char *target_dir) { +char* tool_function_directory_glob(char* target_dir) { fprintf(stderr, "Tools directory_glob: %s\n", target_dir); glob_t results; struct stat file_stat; @@ -420,10 +417,10 @@ char *tool_function_directory_glob(char *target_dir) { return NULL; } - json_object *json_array = json_object_new_array(); + json_object* json_array = json_object_new_array(); for (size_t i = 0; i < results.gl_pathc; i++) { - const char *file_path = results.gl_pathv[i]; + const char* file_path = results.gl_pathv[i]; if (stat(file_path, &file_stat) == -1) { perror("stat failed"); @@ -433,7 +430,7 @@ char *tool_function_directory_glob(char *target_dir) { format_time(file_stat.st_mtime, mod_time, sizeof(mod_time)); format_time(file_stat.st_ctime, create_time, sizeof(create_time)); - json_object *json_entry = json_object_new_object(); + json_object* json_entry = json_object_new_object(); json_object_object_add(json_entry, "name", json_object_new_string(file_path)); json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time)); json_object_object_add(json_entry, "creation_date", json_object_new_string(create_time)); @@ -444,67 +441,67 @@ char *tool_function_directory_glob(char *target_dir) { } globfree(&results); - char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); + char* result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); json_object_put(json_array); return result; } -struct json_object *tool_description_http_get() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_http_get() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - - struct json_object *function = json_object_new_object(); + + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("http_fetch")); json_object_object_add(function, "description", json_object_new_string("Get the contents of a URL.")); - - struct json_object *parameters = json_object_new_object(); + + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - - struct json_object *properties = json_object_new_object(); - struct json_object *url = json_object_new_object(); + + struct json_object* properties = json_object_new_object(); + struct json_object* url = json_object_new_object(); json_object_object_add(url, "type", json_object_new_string("string")); json_object_object_add(url, "description", json_object_new_string("Fetch URL contents.")); json_object_object_add(properties, "url", url); - + json_object_object_add(parameters, "properties", properties); - - struct json_object *required = json_object_new_array(); + + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("url")); json_object_object_add(parameters, "required", required); - + json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); - + json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "strict", json_object_new_boolean(1)); - + json_object_object_add(root, "function", function); - + return root; } -struct json_object *tool_description_directory_glob() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_directory_glob() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - struct json_object *function = json_object_new_object(); + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("directory_glob")); - json_object_object_add(function, "description", json_object_new_string("List the contents of a specified directory in glob format. " - "Result is a json array containing objects with keys: name, modification_date(iso), creation_date(iso), type and size_bytes.")); + json_object_object_add(function, "description", json_object_new_string("List the contents of a specified directory in glob format. " + "Result is a JSON array containing objects with keys: name, modification_date(iso), creation_date(iso), type, and size_bytes.")); - struct json_object *parameters = json_object_new_object(); + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - struct json_object *properties = json_object_new_object(); - struct json_object *directory = json_object_new_object(); + struct json_object* properties = json_object_new_object(); + struct json_object* directory = json_object_new_object(); json_object_object_add(directory, "type", json_object_new_string("string")); json_object_object_add(directory, "description", json_object_new_string("Path to the directory to list in glob format.")); json_object_object_add(properties, "path", directory); json_object_object_add(parameters, "properties", properties); - struct json_object *required = json_object_new_array(); + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("path")); json_object_object_add(parameters, "required", required); @@ -518,159 +515,159 @@ struct json_object *tool_description_directory_glob() { return root; } -struct json_object *tool_description_linux_terminal() { - struct json_object *root = json_object_new_object(); +struct json_object* tool_description_linux_terminal() { + struct json_object* root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); - - struct json_object *function = json_object_new_object(); + + struct json_object* function = json_object_new_object(); json_object_object_add(function, "name", json_object_new_string("linux_terminal_execute")); json_object_object_add(function, "description", json_object_new_string("Execute a linux_terminal command on user terminal.")); - - struct json_object *parameters = json_object_new_object(); + + struct json_object* parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); - - struct json_object *properties = json_object_new_object(); - struct json_object *url = json_object_new_object(); + + struct json_object* properties = json_object_new_object(); + struct json_object* url = json_object_new_object(); json_object_object_add(url, "type", json_object_new_string("string")); json_object_object_add(url, "description", json_object_new_string("Bash command to execute.")); json_object_object_add(properties, "command", url); - + json_object_object_add(parameters, "properties", properties); - - struct json_object *required = json_object_new_array(); + + struct json_object* required = json_object_new_array(); json_object_array_add(required, json_object_new_string("command")); json_object_object_add(parameters, "required", required); - + json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); - + json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "strict", json_object_new_boolean(1)); - + json_object_object_add(root, "function", function); - + return root; } -struct json_object *tools_execute(struct json_object *tools_array) { - struct json_object *tools_result_messages = json_object_new_array(); +struct json_object* tools_execute(struct json_object* tools_array) { + struct json_object* tools_result_messages = json_object_new_array(); int array_len = json_object_array_length(tools_array); - + for (int i = 0; i < array_len; i++) { - struct json_object *obj = json_object_array_get_idx(tools_array, i); - struct json_object *tool_result = json_object_new_object(); - - json_object_object_add(tool_result, "tool_call_id", + struct json_object* obj = json_object_array_get_idx(tools_array, i); + struct json_object* tool_result = json_object_new_object(); + + json_object_object_add(tool_result, "tool_call_id", json_object_new_string(json_object_get_string( json_object_object_get(obj, "id")))); json_object_object_add(tool_result, "role", json_object_new_string("tool")); - - struct json_object *type_obj; + + struct json_object* type_obj; if (json_object_object_get_ex(obj, "type", &type_obj)) { if (strcmp(json_object_get_string(type_obj), "function")) { continue; } } - - struct json_object *function_obj; + + struct json_object* function_obj; if (json_object_object_get_ex(obj, "function", &function_obj)) { - struct json_object *name_obj; - char *function_name = NULL; + struct json_object* name_obj; + char* function_name = NULL; if (json_object_object_get_ex(function_obj, "name", &name_obj)) { - function_name = (char *)json_object_get_string(name_obj); + function_name = (char*)json_object_get_string(name_obj); } if (!strcmp(function_name, "linux_terminal_execute")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *url_obj; + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* url_obj; if (json_object_object_get_ex(arguments, "command", &url_obj)) { - char *command = (char *)json_object_get_string(url_obj); - char *terminal_result = tool_function_linux_terminal(command); + char* command = (char*)json_object_get_string(url_obj); + char* terminal_result = tool_function_linux_terminal(command); json_object_object_add(tool_result, "content", json_object_new_string(terminal_result)); free(terminal_result); } } } else if (!strcmp(function_name, "linux_terminal_execute_interactive")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *url_obj; + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* url_obj; if (json_object_object_get_ex(arguments, "command", &url_obj)) { - char *command = (char *)json_object_get_string(url_obj); - char *terminal_result = tool_function_linux_terminal_interactive(command); + char* command = (char*)json_object_get_string(url_obj); + char* terminal_result = tool_function_linux_terminal_interactive(command); json_object_object_add(tool_result, "content", json_object_new_string(terminal_result)); free(terminal_result); } } - }else if (!strcmp(function_name, "directory_glob")) { - struct json_object *arguments_obj; + } else if (!strcmp(function_name, "directory_glob")) { + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *path_obj; + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* path_obj; if (json_object_object_get_ex(arguments, "path", &path_obj)) { - char *path = (char *)json_object_get_string(path_obj); - char *listing_result = tool_function_directory_glob(path); + char* path = (char*)json_object_get_string(path_obj); + char* listing_result = tool_function_directory_glob(path); json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); free(listing_result); } } } else if (!strcmp(function_name, "http_fetch")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *url_obj; + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* url_obj; if (json_object_object_get_ex(arguments, "url", &url_obj)) { - char *url = (char *)json_object_get_string(url_obj); - char *http_result = tool_function_http_get(url); + char* url = (char*)json_object_get_string(url_obj); + char* http_result = tool_function_http_get(url); json_object_object_add(tool_result, "content", json_object_new_string(http_result)); free(http_result); } } } else if (!strcmp(function_name, "read_file")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *path_obj; - - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* path_obj; + + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); if (json_object_object_get_ex(arguments, "path", &path_obj)) { - char *path = (char *)json_object_get_string(path_obj); - char *file_content = tool_function_read_file(path); + char* path = (char*)json_object_get_string(path_obj); + char* file_content = tool_function_read_file(path); json_object_object_add(tool_result, "content", json_object_new_string(file_content)); free(file_content); } } } else if (!strcmp(function_name, "write_file")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *path_obj, *content_obj; + struct json_object* path_obj, * content_obj; - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); if (json_object_object_get_ex(arguments, "path", &path_obj) && json_object_object_get_ex(arguments, "content", &content_obj)) { - char *path = (char *)json_object_get_string(path_obj); - char *content = (char *)json_object_get_string(content_obj); - char *write_result = tool_function_write_file(path, content); + char* path = (char*)json_object_get_string(path_obj); + char* content = (char*)json_object_get_string(content_obj); + char* write_result = tool_function_write_file(path, content); json_object_object_add(tool_result, "content", json_object_new_string(write_result)); free(write_result); } } } else if (!strcmp(function_name, "directory_rglob")) { - struct json_object *arguments_obj; + struct json_object* arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *path_obj; + struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object* path_obj; if (json_object_object_get_ex(arguments, "path", &path_obj)) { - char *path = (char *)json_object_get_string(path_obj); - char *listing_result = tool_function_directory_rglob(path); + char* path = (char*)json_object_get_string(path_obj); + char* listing_result = tool_function_directory_rglob(path); json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); free(listing_result); } } - }else { - fprintf(stderr, "Unkown function: %s\n", function_name); + } else { + fprintf(stderr, "Unknown function: %s\n", function_name); json_object_object_add(tool_result, "content", json_object_new_string("Error: function not found.")); } @@ -680,4 +677,4 @@ struct json_object *tools_execute(struct json_object *tools_array) { return tools_result_messages; } -#endif +#endif \ No newline at end of file diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..a096ba8 --- /dev/null +++ b/utils.h @@ -0,0 +1,47 @@ +// 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 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 +// +// Permission is granted to use, copy, modify, merge, distribute, sublicense, 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 +#define UTILS_H + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char* expand_home_directory(const char* path) { + if (path == NULL) return NULL; + + if (path[0] == '~' && path[1] == '/') { + const char* home_dir = getenv("HOME"); + if (home_dir == NULL) { + #include <pwd.h> + #include <unistd.h> + struct passwd* pw = getpwuid(getuid()); + if (pw == NULL) return NULL; + home_dir = pw->pw_dir; + } + + size_t home_len = strlen(home_dir); + size_t path_len = strlen(path) - 1; + char* expanded_path = malloc(home_len + path_len + 1); + + if (expanded_path == NULL) return NULL; + + strcpy(expanded_path, home_dir); + strcat(expanded_path, path + 1); + + return expanded_path; + } else { + return strdup(path); + } +} + +#endif \ No newline at end of file