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
// 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;
}

14
chat.h
View File

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

View File

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

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.
// 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

8
line.h
View File

@ -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);
}
}

View File

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

View File

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

357
tools.h
View File

@ -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, &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++) {
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(&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);
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

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