Project update.

This commit is contained in:
retoor 2025-03-16 07:36:13 +01:00
parent ab254abb4b
commit 48a543b56e
9 changed files with 262 additions and 227 deletions

6
auth.h
View File

@ -1,8 +1,8 @@
// Written by retoor@molodetz.nl // 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 // MIT License
@ -26,7 +26,7 @@ const char *resolve_api_key() {
} }
fprintf(stderr, "\nThere is no API key configured in the environment.\n"); fprintf(stderr, "\nThere is no API key configured in the environment.\n");
exit(1); exit(1);
#endif #endif
api_key = "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"; api_key = "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";
return api_key; return api_key;
} }

14
chat.h
View File

@ -35,14 +35,14 @@
#include "messages.h" #include "messages.h"
#ifdef FREE_VERSION #ifdef FREE_VERSION
char *prompt_model = "gpt-3.5-turbo"; static char *prompt_model = "gpt-3.5-turbo";
#else #else
char *prompt_model = "gpt-4o-mini"; static char *prompt_model = "gpt-4o-mini";
#endif #endif
int prompt_max_tokens = 2048; static int prompt_max_tokens = 2048;
double prompt_temperature = 0.1; static double prompt_temperature = 0.1;
json_object *_prompt = NULL; static json_object *_prompt = NULL;
void chat_free() { void chat_free() {
if (_prompt == NULL) return; if (_prompt == NULL) return;
@ -52,7 +52,7 @@ 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();
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)); json_object_object_add(root_object, "model", json_object_new_string(prompt_model));
if (role != NULL && message != NULL) { 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); return (char *)json_object_to_json_string_ext(root_object, JSON_C_TO_STRING_PRETTY);
} }
#endif #endif

View File

@ -1,6 +1,6 @@
// Written by retoor@molodetz.nl // 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. // 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 // from, out of or in connection with the software or the use or other dealings in
// the Software. // the Software.
#ifndef HTTP_CURL #ifndef HTTP_CURL
#define 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) { char *curl_post(const char *url, const char *data) {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct ResponseBuffer response; struct ResponseBuffer response = {malloc(1), 0};
response.data = malloc(1);
response.size = 0; if (!response.data) return NULL;
curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if (curl) {
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
headers = curl_slist_append(headers, "Content-Type: application/json"); 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()); sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key());
headers = curl_slist_append(headers, bearer_header); headers = curl_slist_append(headers, bearer_header);
free(bearer_header);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
@ -91,25 +92,19 @@ char *curl_get(const char *url) {
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json");
char bearer_header[1337];
char *bearer_header = malloc(1337);
sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key()); sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key());
headers = curl_slist_append(headers, bearer_header); headers = curl_slist_append(headers, bearer_header);
free(bearer_header);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if (res != CURLE_OK) { if (res != CURLE_OK) {
fprintf(stderr, "An error occurred: %s\n", curl_easy_strerror(res)); fprintf(stderr, "An error occurred: %s\n", curl_easy_strerror(res));
} }
curl_slist_free_all(headers); curl_slist_free_all(headers);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }
return response.data; return response.data;
} }

View File

@ -2,7 +2,7 @@
// 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

8
line.h
View File

@ -1,6 +1,6 @@
// Written by retoor@molodetz.nl // 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: // External includes:
// - <readline/readline.h> // - <readline/readline.h>
@ -52,9 +52,7 @@ void line_init() {
char* line_read(char* prefix) { char* line_read(char* prefix) {
char* data = readline(prefix); char* data = readline(prefix);
if (!(data && *data)) { if (!(data && *data)) {
if (data) { free(data);
free(data);
}
return NULL; return NULL;
} }
return data; return data;
@ -63,4 +61,4 @@ char* line_read(char* prefix) {
void line_add_history(char* data) { void line_add_history(char* data) {
add_history(data); add_history(data);
write_history(HISTORY_FILE); write_history(HISTORY_FILE);
} }

View File

@ -25,12 +25,11 @@ struct json_object *message_list() {
return message_array; return message_array;
} }
void messages_remove_last() {
void messages_remove_last(){
struct json_object *messages = message_list(); struct json_object *messages = message_list();
int size = json_object_array_length(messages); int size = json_object_array_length(messages);
if(size){ if (size) {
json_object_array_del_idx(messages, size - 1,1); 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; 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 *messages = message_list();
struct json_object *message = json_object_new_object(); struct json_object *message = json_object_new_object();
@ -76,4 +75,4 @@ void message_free() {
} }
} }
#endif #endif

View File

@ -1,10 +1,9 @@
// 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
// //
// Copyright (c) 2023 // 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); 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) {
fprintf(stderr, "Failed to parse JSON.\n %s \n", response); fprintf(stderr, "Failed to parse JSON.\n%s\n", response);
return NULL; return NULL;
} }
struct json_object *error_object; struct json_object *error_object;
if (json_object_object_get_ex(parsed_json, "error", &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); 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: "); 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");
free(all_messages); free(all_messages);
messages_remove_last(); 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; struct json_object* choices_array;
if (!json_object_object_get_ex(parsed_json, "choices", &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); json_object_put(parsed_json);
return NULL; 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"; 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);
if(message_object == NULL) { if (message_object == NULL) {
printf("ERROR + NULL IS SUCCESS\n"); printf("ERROR + NULL IS SUCCESS\n");
return NULL; return NULL;
} }
struct json_object* tool_calls; struct json_object* tool_calls;
json_object_object_get_ex(message_object, "tool_calls", &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); 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_tool_call(message_object); 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); return strdup(content_str);
} }
#endif #endif

357
tools.h
View File

@ -18,16 +18,16 @@
#include <time.h> #include <time.h>
#include <glob.h> #include <glob.h>
struct json_object *tool_description_http_get(); struct json_object* tool_description_http_get();
struct json_object *tool_description_linux_terminal(); struct json_object* tool_description_linux_terminal();
struct json_object *tool_description_directory_glob(); struct json_object* tool_description_directory_glob();
struct json_object *tool_description_read_file(); struct json_object* tool_description_read_file();
struct json_object *tool_description_write_file(); struct json_object* tool_description_write_file();
struct json_object *tool_description_directory_rglob(); struct json_object* tool_description_directory_rglob();
struct json_object *tool_description_linux_terminal_interactive(); struct json_object* tool_description_linux_terminal_interactive();
struct json_object *tools_descriptions() { struct json_object* tools_descriptions() {
struct json_object *root = json_object_new_array(); struct json_object* root = json_object_new_array();
json_object_array_add(root, tool_description_http_get()); 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_linux_terminal());
json_object_array_add(root, tool_description_directory_glob()); json_object_array_add(root, tool_description_directory_glob());
@ -38,17 +38,17 @@ struct json_object *tools_descriptions() {
return root; return root;
} }
char *tool_function_http_get(char *url) { char* tool_function_http_get(char* url) {
fprintf(stderr, "Tool http_get: %s\n", url); fprintf(stderr, "Tool http_get: %s\n", url);
return curl_get(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); fprintf(stderr, "Tool linux_terminal: %s\n", command);
FILE *fp; FILE* fp;
char buffer[1024]; char buffer[1024];
size_t total_size = 0; size_t total_size = 0;
char *output = NULL; char* output = NULL;
fp = popen(command, "r"); fp = popen(command, "r");
if (fp == NULL) { if (fp == NULL) {
@ -58,7 +58,7 @@ char *tool_function_linux_terminal(char *command) {
while (fgets(buffer, sizeof(buffer), fp) != NULL) { while (fgets(buffer, sizeof(buffer), fp) != NULL) {
size_t chunk_size = strlen(buffer); 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) { if (new_output == NULL) {
perror("realloc failed"); perror("realloc failed");
free(output); free(output);
@ -74,41 +74,41 @@ char *tool_function_linux_terminal(char *command) {
return output ? output : strdup(""); 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); fprintf(stderr, "Tool linux_terminal_interactive: %s\n", command);
int result_code = system(command); int result_code = system(command);
char * result = (char *)malloc(100); char* result = malloc(100);
result[0] = 0; result[0] = 0;
sprintf(result, "Command exited with status code %d.", result_code); sprintf(result, "Command exited with status code %d.", result_code);
return result; return result;
} }
struct json_object *tool_description_linux_terminal_interactive() { struct json_object* tool_description_linux_terminal_interactive() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "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.")); 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *path = 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, "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(properties, "command", path);
json_object_object_add(parameters, "properties", properties); 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_array_add(required, json_object_new_string("command"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "parameters", parameters);
@ -119,30 +119,27 @@ struct json_object *tool_description_linux_terminal_interactive() {
return root; 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")); 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, "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. " 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *directory = 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, "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(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(properties, "path", directory);
json_object_object_add(parameters, "properties", properties); 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("path"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
@ -156,29 +153,29 @@ struct json_object *tool_description_directory_rglob() {
return root; return root;
} }
struct json_object *tool_description_read_file() { struct json_object* tool_description_read_file() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "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.")); 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *path = 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, "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(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(properties, "path", path);
json_object_object_add(parameters, "properties", properties); 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("path"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "parameters", parameters);
@ -189,36 +186,36 @@ struct json_object *tool_description_read_file() {
return root; return root;
} }
struct json_object *tool_description_write_file() { struct json_object* tool_description_write_file() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "name", json_object_new_string("write_file"));
json_object_object_add(function, "description", json_object_new_string("Writes / saves / stores content to a 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *path = 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, "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(path, "description", json_object_new_string("Path to the file to write / save / store."));
json_object_object_add(properties, "path", path); 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, "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(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(properties, "content", content);
json_object_object_add(parameters, "properties", properties); 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("path"));
json_object_array_add(required, json_object_new_string("content")); json_object_array_add(required, json_object_new_string("content"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "parameters", parameters);
@ -229,9 +226,9 @@ struct json_object *tool_description_write_file() {
return root; return root;
} }
char *tool_function_read_file(char *path) { char* tool_function_read_file(char* path) {
fprintf(stderr, "Tools read_file: %s\n", path); fprintf(stderr, "Tools read_file: %s\n", path);
FILE *fp = fopen(path, "r"); FILE* fp = fopen(path, "r");
if (fp == NULL) { if (fp == NULL) {
perror("fopen failed"); perror("fopen failed");
return strdup("Failed to open file for reading!"); return strdup("Failed to open file for reading!");
@ -241,23 +238,23 @@ char *tool_function_read_file(char *path) {
long size = ftell(fp); long size = ftell(fp);
rewind(fp); rewind(fp);
char *content = (char *)malloc(size + 1); char* content = malloc(size + 1);
if (content == NULL) { if (content == NULL) {
fclose(fp); fclose(fp);
return strdup("Memory allocation failed!"); return strdup("Memory allocation failed!");
} }
ssize_t read_size = fread(content, 1, size, fp); ssize_t read_size = fread(content, 1, size, fp);
content[read_size] = '\0'; content[read_size] = '\0';
fclose(fp); fclose(fp);
return content; 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); 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) { if (fp == NULL) {
perror("fopen failed"); perror("fopen failed");
return strdup("Failed to open file for writing!"); 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."); 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_ISREG(st->st_mode)) return "file";
if (S_ISDIR(st->st_mode)) return "directory"; if (S_ISDIR(st->st_mode)) return "directory";
return "other"; return "other";
} }
void format_time(time_t raw_time, char *buffer, size_t size) { void format_time(time_t raw_time, char* buffer, size_t size) {
struct tm *time_info = localtime(&raw_time); struct tm* time_info = localtime(&raw_time);
strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info); 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; glob_t current_matches;
int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, &current_matches); int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, &current_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++) { 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) { if (results->gl_pathc == 0) {
results->gl_pathc = 1; results->gl_pathc = 1;
results->gl_pathv = malloc(sizeof(char *)); results->gl_pathv = malloc(sizeof(char*));
results->gl_pathv[0] = strdup(path); results->gl_pathv[0] = strdup(path);
} else { } else {
results->gl_pathc++; results->gl_pathc++;
results->gl_pathv = realloc(results->gl_pathv, results->gl_pathv = realloc(results->gl_pathv,
results->gl_pathc * sizeof(char *)); results->gl_pathc * sizeof(char*));
results->gl_pathv[results->gl_pathc - 1] = strdup(path); results->gl_pathv[results->gl_pathc - 1] = strdup(path);
} }
} }
DIR *dir; DIR* dir;
struct dirent *entry; struct dirent* entry;
struct stat statbuf; struct stat statbuf;
char *pattern_copy = strdup(pattern); char* pattern_copy = strdup(pattern);
char *last_slash = strrchr(pattern_copy, '/'); char* last_slash = strrchr(pattern_copy, '/');
char *dir_path; char* dir_path;
char *file_pattern; char* file_pattern;
if (last_slash) { if (last_slash) {
*last_slash = '\0'; *last_slash = '\0';
@ -365,7 +362,7 @@ void recursive_glob(const char *pattern, glob_t *results) {
globfree(&current_matches); globfree(&current_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); fprintf(stderr, "Tools directory_rglob: %s\n", target_dir);
glob_t results; glob_t results;
results.gl_pathc = 0; results.gl_pathc = 0;
@ -374,10 +371,10 @@ char *tool_function_directory_rglob(char *target_dir) {
recursive_glob(target_dir, &results); 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++) { 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) { if (stat(file_path, &file_stat) == -1) {
perror("stat failed"); 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_mtime, mod_time, sizeof(mod_time));
format_time(file_stat.st_ctime, create_time, sizeof(create_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, "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, "modification_date", json_object_new_string(mod_time));
json_object_object_add(json_entry, "creation_date", json_object_new_string(create_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); 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); json_object_put(json_array);
return result; 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); fprintf(stderr, "Tools directory_glob: %s\n", target_dir);
glob_t results; glob_t results;
struct stat file_stat; struct stat file_stat;
@ -420,10 +417,10 @@ char *tool_function_directory_glob(char *target_dir) {
return NULL; 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++) { 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) { if (stat(file_path, &file_stat) == -1) {
perror("stat failed"); 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_mtime, mod_time, sizeof(mod_time));
format_time(file_stat.st_ctime, create_time, sizeof(create_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, "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, "modification_date", json_object_new_string(mod_time));
json_object_object_add(json_entry, "creation_date", json_object_new_string(create_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); 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); json_object_put(json_array);
return result; return result;
} }
struct json_object *tool_description_http_get() { struct json_object* tool_description_http_get() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "name", json_object_new_string("http_fetch"));
json_object_object_add(function, "description", json_object_new_string("Get the contents of a URL.")); 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *url = 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, "type", json_object_new_string("string"));
json_object_object_add(url, "description", json_object_new_string("Fetch URL contents.")); json_object_object_add(url, "description", json_object_new_string("Fetch URL contents."));
json_object_object_add(properties, "url", url); json_object_object_add(properties, "url", url);
json_object_object_add(parameters, "properties", properties); 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_array_add(required, json_object_new_string("url"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "parameters", parameters);
json_object_object_add(function, "strict", json_object_new_boolean(1)); json_object_object_add(function, "strict", json_object_new_boolean(1));
json_object_object_add(root, "function", function); json_object_object_add(root, "function", function);
return root; return root;
} }
struct json_object *tool_description_directory_glob() { struct json_object* tool_description_directory_glob() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "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. " 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.")); "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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *directory = 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, "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(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(properties, "path", directory);
json_object_object_add(parameters, "properties", properties); 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("path"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
@ -518,159 +515,159 @@ struct json_object *tool_description_directory_glob() {
return root; return root;
} }
struct json_object *tool_description_linux_terminal() { struct json_object* tool_description_linux_terminal() {
struct json_object *root = json_object_new_object(); struct json_object* root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function")); 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, "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.")); 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")); json_object_object_add(parameters, "type", json_object_new_string("object"));
struct json_object *properties = json_object_new_object(); struct json_object* properties = json_object_new_object();
struct json_object *url = 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, "type", json_object_new_string("string"));
json_object_object_add(url, "description", json_object_new_string("Bash command to execute.")); 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(properties, "command", url);
json_object_object_add(parameters, "properties", properties); 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_array_add(required, json_object_new_string("command"));
json_object_object_add(parameters, "required", required); json_object_object_add(parameters, "required", required);
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0)); json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
json_object_object_add(function, "parameters", parameters); json_object_object_add(function, "parameters", parameters);
json_object_object_add(function, "strict", json_object_new_boolean(1)); json_object_object_add(function, "strict", json_object_new_boolean(1));
json_object_object_add(root, "function", function); json_object_object_add(root, "function", function);
return root; return root;
} }
struct json_object *tools_execute(struct json_object *tools_array) { struct json_object* tools_execute(struct json_object* tools_array) {
struct json_object *tools_result_messages = json_object_new_array(); struct json_object* tools_result_messages = json_object_new_array();
int array_len = json_object_array_length(tools_array); int array_len = json_object_array_length(tools_array);
for (int i = 0; i < array_len; i++) { for (int i = 0; i < array_len; i++) {
struct json_object *obj = json_object_array_get_idx(tools_array, i); struct json_object* obj = json_object_array_get_idx(tools_array, i);
struct json_object *tool_result = json_object_new_object(); struct json_object* tool_result = json_object_new_object();
json_object_object_add(tool_result, "tool_call_id", json_object_object_add(tool_result, "tool_call_id",
json_object_new_string(json_object_get_string( json_object_new_string(json_object_get_string(
json_object_object_get(obj, "id")))); json_object_object_get(obj, "id"))));
json_object_object_add(tool_result, "role", json_object_new_string("tool")); 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 (json_object_object_get_ex(obj, "type", &type_obj)) {
if (strcmp(json_object_get_string(type_obj), "function")) { if (strcmp(json_object_get_string(type_obj), "function")) {
continue; continue;
} }
} }
struct json_object *function_obj; struct json_object* function_obj;
if (json_object_object_get_ex(obj, "function", &function_obj)) { if (json_object_object_get_ex(obj, "function", &function_obj)) {
struct json_object *name_obj; struct json_object* name_obj;
char *function_name = NULL; char* function_name = NULL;
if (json_object_object_get_ex(function_obj, "name", &name_obj)) { 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")) { 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)) { 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* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *url_obj; struct json_object* url_obj;
if (json_object_object_get_ex(arguments, "command", &url_obj)) { if (json_object_object_get_ex(arguments, "command", &url_obj)) {
char *command = (char *)json_object_get_string(url_obj); char* command = (char*)json_object_get_string(url_obj);
char *terminal_result = tool_function_linux_terminal(command); char* terminal_result = tool_function_linux_terminal(command);
json_object_object_add(tool_result, "content", json_object_new_string(terminal_result)); json_object_object_add(tool_result, "content", json_object_new_string(terminal_result));
free(terminal_result); free(terminal_result);
} }
} }
} else if (!strcmp(function_name, "linux_terminal_execute_interactive")) { } 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)) { 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* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *url_obj; struct json_object* url_obj;
if (json_object_object_get_ex(arguments, "command", &url_obj)) { if (json_object_object_get_ex(arguments, "command", &url_obj)) {
char *command = (char *)json_object_get_string(url_obj); char* command = (char*)json_object_get_string(url_obj);
char *terminal_result = tool_function_linux_terminal_interactive(command); char* terminal_result = tool_function_linux_terminal_interactive(command);
json_object_object_add(tool_result, "content", json_object_new_string(terminal_result)); json_object_object_add(tool_result, "content", json_object_new_string(terminal_result));
free(terminal_result); free(terminal_result);
} }
} }
}else if (!strcmp(function_name, "directory_glob")) { } else if (!strcmp(function_name, "directory_glob")) {
struct json_object *arguments_obj; struct json_object* arguments_obj;
if (json_object_object_get_ex(function_obj, "arguments", &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* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *path_obj; struct json_object* path_obj;
if (json_object_object_get_ex(arguments, "path", &path_obj)) { if (json_object_object_get_ex(arguments, "path", &path_obj)) {
char *path = (char *)json_object_get_string(path_obj); char* path = (char*)json_object_get_string(path_obj);
char *listing_result = tool_function_directory_glob(path); char* listing_result = tool_function_directory_glob(path);
json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); json_object_object_add(tool_result, "content", json_object_new_string(listing_result));
free(listing_result); free(listing_result);
} }
} }
} else if (!strcmp(function_name, "http_fetch")) { } 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)) { 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* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *url_obj; struct json_object* url_obj;
if (json_object_object_get_ex(arguments, "url", &url_obj)) { if (json_object_object_get_ex(arguments, "url", &url_obj)) {
char *url = (char *)json_object_get_string(url_obj); char* url = (char*)json_object_get_string(url_obj);
char *http_result = tool_function_http_get(url); char* http_result = tool_function_http_get(url);
json_object_object_add(tool_result, "content", json_object_new_string(http_result)); json_object_object_add(tool_result, "content", json_object_new_string(http_result));
free(http_result); free(http_result);
} }
} }
} else if (!strcmp(function_name, "read_file")) { } 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)) { if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) {
struct json_object *path_obj; struct json_object* path_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)) { if (json_object_object_get_ex(arguments, "path", &path_obj)) {
char *path = (char *)json_object_get_string(path_obj); char* path = (char*)json_object_get_string(path_obj);
char *file_content = tool_function_read_file(path); char* file_content = tool_function_read_file(path);
json_object_object_add(tool_result, "content", json_object_new_string(file_content)); json_object_object_add(tool_result, "content", json_object_new_string(file_content));
free(file_content); free(file_content);
} }
} }
} else if (!strcmp(function_name, "write_file")) { } 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)) { 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) && if (json_object_object_get_ex(arguments, "path", &path_obj) &&
json_object_object_get_ex(arguments, "content", &content_obj)) { json_object_object_get_ex(arguments, "content", &content_obj)) {
char *path = (char *)json_object_get_string(path_obj); char* path = (char*)json_object_get_string(path_obj);
char *content = (char *)json_object_get_string(content_obj); char* content = (char*)json_object_get_string(content_obj);
char *write_result = tool_function_write_file(path, content); char* write_result = tool_function_write_file(path, content);
json_object_object_add(tool_result, "content", json_object_new_string(write_result)); json_object_object_add(tool_result, "content", json_object_new_string(write_result));
free(write_result); free(write_result);
} }
} }
} else if (!strcmp(function_name, "directory_rglob")) { } 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)) { 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* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *path_obj; struct json_object* path_obj;
if (json_object_object_get_ex(arguments, "path", &path_obj)) { if (json_object_object_get_ex(arguments, "path", &path_obj)) {
char *path = (char *)json_object_get_string(path_obj); char* path = (char*)json_object_get_string(path_obj);
char *listing_result = tool_function_directory_rglob(path); char* listing_result = tool_function_directory_rglob(path);
json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); json_object_object_add(tool_result, "content", json_object_new_string(listing_result));
free(listing_result); free(listing_result);
} }
} }
}else { } else {
fprintf(stderr, "Unkown function: %s\n", function_name); fprintf(stderr, "Unknown function: %s\n", function_name);
json_object_object_add(tool_result, "content", json_object_new_string("Error: function not found.")); 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; return tools_result_messages;
} }
#endif #endif

47
utils.h Normal file
View File

@ -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