// Written by retoor@molodetz.nl // This code defines functions for HTTP requests and structuring tool // descriptions and executions in JSON format using the JSON-C library. It uses // cURL for HTTP requests. // Imports not part of the language itself: JSON-C (json-c/json.h, // json-c/json_object.h) and a custom header "http_curl.h" // MIT License #ifndef R_TOOLS_H #define R_TOOLS_H #include "http_curl.h" #include "r.h" #include "utils.h" #include <dirent.h> #include <glob.h> #include <json-c/json.h> #include <json-c/json_object.h> #include <stdbool.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include "browse.h" #include "db_utils.h" #include "indexer.h" #include "r.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_index_source_directory(); struct json_object *tool_description_chdir(); struct json_object *tool_description_getpwd(); struct json_object *tool_description_db_set(); struct json_object *tool_description_db_query(); struct json_object *tool_description_db_get(); struct json_object *tool_description_web_search_news(); struct json_object *tool_description_web_search(); struct json_object *tool_description_mkdir(); 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()); json_object_array_add(root, tool_description_read_file()); json_object_array_add(root, tool_description_write_file()); json_object_array_add(root, tool_description_directory_rglob()); json_object_array_add(root, tool_description_linux_terminal_interactive()); json_object_array_add(root, tool_description_index_source_directory()); json_object_array_add(root, tool_description_chdir()); json_object_array_add(root, tool_description_getpwd()); json_object_array_add(root, tool_description_db_set()); json_object_array_add(root, tool_description_db_query()); json_object_array_add(root, tool_description_db_get()); json_object_array_add(root, tool_description_web_search_news()); json_object_array_add(root, tool_description_web_search()); json_object_array_add(root, tool_description_mkdir()); return root; } char *tool_function_web_search_news(char *query) { if (query == NULL) { return strdup("Query cannot be NULL."); } char *result = web_search_news(query); if (result == NULL) { return strdup("Failed to fetch news."); } return result; } struct json_object *tool_description_web_search_news() { 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(); json_object_object_add(function, "name", json_object_new_string("web_search_news")); json_object_object_add( function, "description", json_object_new_string("Searches for news articles based on a query.")); 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 *query = json_object_new_object(); json_object_object_add(query, "type", json_object_new_string("string")); json_object_object_add( query, "description", json_object_new_string( "The url encoded query string to search for news articles.")); json_object_object_add(properties, "query", query); json_object_object_add(parameters, "properties", properties); struct json_object *required = json_object_new_array(); json_object_array_add(required, json_object_new_string("query")); 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; } char *tool_function_web_search(char *query) { if (query == NULL) { return strdup("Query cannot be NULL."); } char *result = web_search_news(query); if (result == NULL) { return strdup("Failed to fetch news."); } return result; } struct json_object *tool_description_web_search() { 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(); json_object_object_add(function, "name", json_object_new_string("web_search")); json_object_object_add( function, "description", json_object_new_string("Searches for information based on a query using " "search engines like google.")); 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 *query = json_object_new_object(); json_object_object_add(query, "type", json_object_new_string("string")); json_object_object_add( query, "description", json_object_new_string( "The url encoded query string to search for information.")); json_object_object_add(properties, "query", query); json_object_object_add(parameters, "properties", properties); struct json_object *required = json_object_new_array(); json_object_array_add(required, json_object_new_string("query")); 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; } char *tool_function_db_get(char *key) { json_object *result = db_get(key); if (result == NULL) { return strdup("Failed to retrieve value from the database."); } char *response = strdup(json_object_to_json_string(result)); json_object_put(result); // Free the json_object return response; } struct json_object *tool_description_db_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(); json_object_object_add(function, "name", json_object_new_string("db_get")); json_object_object_add( function, "description", json_object_new_string( "Retrieves a value from the database for a given key.")); 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 *key = json_object_new_object(); json_object_object_add(key, "type", json_object_new_string("string")); json_object_object_add( key, "description", json_object_new_string("The key to retrieve from the database.")); json_object_object_add(properties, "key", key); json_object_object_add(parameters, "properties", properties); struct json_object *required = json_object_new_array(); json_object_array_add(required, json_object_new_string("key")); 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; } char *tool_function_db_query(char *query) { json_object *result = db_query(query); if (result == NULL) { return strdup("Failed to execute query on the database."); } char *response = strdup(json_object_to_json_string(result)); json_object_put(result); // Free the json_object return response; } struct json_object *tool_description_db_query() { 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(); json_object_object_add(function, "name", json_object_new_string("db_query")); json_object_object_add( function, "description", json_object_new_string( "Executes a query on the database and returns the results.")); 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 *query = json_object_new_object(); json_object_object_add(query, "type", json_object_new_string("string")); json_object_object_add(query, "description", json_object_new_string("The SQL query to execute.")); json_object_object_add(properties, "query", query); json_object_object_add(parameters, "properties", properties); struct json_object *required = json_object_new_array(); json_object_array_add(required, json_object_new_string("query")); 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; } char *tool_function_db_set(char *key, char *value) { json_object *result = db_set(key, value); if (result == NULL) { return strdup("Failed to set value in the database."); } const char *response = json_object_get_string(result); json_object_put(result); // Free the json_object return strdup(response); } struct json_object *tool_description_db_set() { 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(); json_object_object_add(function, "name", json_object_new_string("db_set")); json_object_object_add( function, "description", json_object_new_string("Sets a value in the database for a given key.")); 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 *key = json_object_new_object(); json_object_object_add(key, "type", json_object_new_string("string")); json_object_object_add( key, "description", json_object_new_string("The key to set in the database.")); json_object_object_add(properties, "key", key); struct json_object *value = json_object_new_object(); json_object_object_add(value, "type", json_object_new_string("string")); json_object_object_add( value, "description", json_object_new_string("The value to set for the given key.")); json_object_object_add(properties, "value", value); json_object_object_add(parameters, "properties", properties); struct json_object *required = json_object_new_array(); json_object_array_add(required, json_object_new_string("key")); json_object_array_add(required, json_object_new_string("value")); 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; } char *tool_function_http_get(char *url) { return curl_get(url); } char *tool_function_chdir(char *path) { if (chdir(path) != 0) { perror("chdir failed"); return strdup("Failed to change directory!"); } return strdup("Directory successfully changed."); } char *tool_function_linux_terminal(char *command) { FILE *fp; char buffer[1024]; size_t total_size = 0; char *output = NULL; char stderr_command[1024] = {0}; if(!strstr(command, "2>")) { snprintf(stderr_command, sizeof(stderr_command), "%s 2>&1", command); command = stderr_command; } fp = popen(command, "r"); if (fp == NULL) { perror("popen failed"); return strdup("Popen failed!"); } while (fgets(buffer, sizeof(buffer), fp) != NULL) { size_t chunk_size = strlen(buffer); char *new_output = realloc(output, total_size + chunk_size + 1); if (new_output == NULL) { perror("realloc failed"); free(output); pclose(fp); return strdup("Failed to allocate memory!"); } output = new_output; if (is_verbose) fprintf(stderr, "%s", buffer); strcpy(output + total_size, buffer); total_size += chunk_size; } pclose(fp); return output ? output : strdup(""); } char *tool_function_linux_terminal_interactive(char *command) { int result_code = system(command); char *result = malloc(100); result[0] = 0; sprintf(result, "Command exited with status code %d.", result_code); return result; } char *tool_function_getpwd() { char *cwd = (char *)malloc(PATH_MAX); if (cwd == NULL) { perror("Memory allocation failed"); return strdup("Failed to allocate memory for current working directory!"); } if (getcwd(cwd, PATH_MAX) == NULL) { free(cwd); perror("getcwd failed"); return strdup("Failed to get current working directory!"); } return cwd; } struct json_object *tool_description_getpwd() { 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(); json_object_object_add(function, "name", json_object_new_string("getpwd")); json_object_object_add( function, "description", json_object_new_string( "Returns the current working directory as a string.")); struct json_object *parameters = json_object_new_object(); json_object_object_add(parameters, "type", json_object_new_string("object")); json_object_object_add(function, "parameters", json_object_new_null()); json_object_object_add(root, "function", function); return root; } struct json_object *tool_description_chdir() { 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(); json_object_object_add(function, "name", json_object_new_string("chdir")); json_object_object_add( function, "description", json_object_new_string( "Changes the current working directory to the specified path. Call " "this function when `cd` is prompted.")); 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(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add( path, "description", json_object_new_string( "Path to change the current working directory to.")); json_object_object_add(properties, "path", path); json_object_object_add(parameters, "properties", properties); 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); 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_index_source_directory() { 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(); json_object_object_add(function, "name", json_object_new_string("index_source_directory")); json_object_object_add( function, "description", json_object_new_string("Returns a JSON array containing every source " "file with it's contents from given directory. " "Execute with '.' for current directory.")); 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(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add( path, "description", json_object_new_string("Path to index and retreive files from.")); json_object_object_add(properties, "path", path); json_object_object_add(parameters, "properties", properties); 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); 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_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(); 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(); 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(); 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 interactively.")); json_object_object_add(properties, "command", path); json_object_object_add(parameters, "properties", properties); 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 *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(); 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.")); 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(); 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(); 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); 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_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(); 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(); 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(); 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(); 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); 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_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(); 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. Content should be in " "plain format, not json encoded.")); 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(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add( path, "description", json_object_new_string( "Path to the plain file to write / save / store.")); json_object_object_add(properties, "path", path); 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( "Plain 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(); 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); json_object_object_add(function, "strict", json_object_new_boolean(1)); json_object_object_add(root, "function", function); return root; } char *tool_function_index_source_directory(char *path) { return index_directory(path); } char *tool_function_read_file(char *path) { char *expanded_path = expand_home_directory(path); FILE *fp = fopen(expanded_path, "r"); free(expanded_path); if (fp == NULL) { perror("fopen failed"); return strdup("Failed to open file for reading!"); } fseek(fp, 0, SEEK_END); long size = ftell(fp); rewind(fp); char *content = (char *)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) { db_store_file_version(path); FILE *fp = fopen(path, "w"); if (fp == NULL) { perror("fopen failed"); return strdup("Failed to open file for writing!"); } fwrite(content, 1, strlen(content), fp); fclose(fp); return strdup("File successfully written."); } 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); strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info); } void recursive_glob(const char *pattern, glob_t *results) { glob_t current_matches; int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, ¤t_matches); if (ret != 0 && ret != GLOB_NOMATCH) { results->gl_pathc = 0; results->gl_pathv = NULL; results->gl_offs = 0; return; } if (results->gl_pathv == NULL) { memset(results, 0, sizeof(glob_t)); } for (size_t i = 0; i < current_matches.gl_pathc; 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[0] = strdup(path); } else { results->gl_pathc++; 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; struct stat statbuf; char *pattern_copy = strdup(pattern); char *last_slash = strrchr(pattern_copy, '/'); char *dir_path; char *file_pattern; if (last_slash) { *last_slash = '\0'; dir_path = pattern_copy; file_pattern = last_slash + 1; } else { dir_path = "."; file_pattern = pattern_copy; } if ((dir = opendir(dir_path)) != NULL) { while ((entry = readdir(dir)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } char full_path[PATH_MAX]; int path_len; if (strcmp(dir_path, ".") == 0) { path_len = snprintf(full_path, PATH_MAX, "%s", entry->d_name); } else { path_len = snprintf(full_path, PATH_MAX, "%s/%s", dir_path, entry->d_name); } if (path_len >= PATH_MAX) { continue; } if (stat(full_path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { char new_pattern[PATH_MAX]; int new_pattern_len = snprintf(new_pattern, PATH_MAX, "%s/%s", full_path, file_pattern); if (new_pattern_len >= PATH_MAX) { continue; } recursive_glob(new_pattern, results); } } closedir(dir); } free(pattern_copy); globfree(¤t_matches); } char *tool_function_directory_rglob(char *target_dir) { glob_t results; results.gl_pathc = 0; struct stat file_stat; char mod_time[20], create_time[20]; recursive_glob(target_dir, &results); 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]; if (stat(file_path, &file_stat) == -1) { perror("stat failed"); continue; } 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_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)); json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat))); json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size)); json_object_array_add(json_array, json_entry); } globfree(&results); 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) { glob_t results; struct stat file_stat; char mod_time[20], create_time[20]; if (!strcmp(target_dir, ".")) { target_dir[0] = '*'; } if (glob(target_dir, GLOB_TILDE, NULL, &results) != 0) { perror("glob failed"); return strdup(""); } 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]; if (stat(file_path, &file_stat) == -1) { perror("stat failed"); continue; } 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_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)); json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat))); json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size)); json_object_array_add(json_array, json_entry); } globfree(&results); 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(); json_object_object_add(root, "type", json_object_new_string("function")); 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(); 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(); 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(); 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(); json_object_object_add(root, "type", json_object_new_string("function")); 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.")); 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(); 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(); 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); 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_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(); 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(); 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(); 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(); 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; } char *tool_function_mkdir(char *path) { if (mkdir(path, 0777) != 0) { perror("mkdir failed"); return strdup("Failed to create directory!"); } return strdup("Directory successfully created."); } struct json_object *tool_description_mkdir() { 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(); json_object_object_add(function, "name", json_object_new_string("mkdir")); json_object_object_add( function, "description", json_object_new_string("Creates a new directory with the specified path.")); 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(); json_object_object_add(path, "type", json_object_new_string("string")); json_object_object_add( path, "description", json_object_new_string("Path of the directory to create.")); json_object_object_add(properties, "path", path); json_object_object_add(parameters, "properties", properties); 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); 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(); 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", 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; 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; if (json_object_object_get_ex(obj, "function", &function_obj)) { 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); 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)); if (is_verbose) fprintf(stderr, "Executing function %s with arguments %s\n", function_name, json_object_to_json_string(arguments)); } } if (!strcmp(function_name, "linux_terminal_execute")) { 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; 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); 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; 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; 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); json_object_object_add(tool_result, "content", json_object_new_string(terminal_result)); free(terminal_result); } } } else if (!strcmp(function_name, "chdir")) { 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; if (json_object_object_get_ex(arguments, "path", &path_obj)) { char *path = (char *)json_object_get_string(path_obj); char *chdir_result = tool_function_chdir(path); json_object_object_add(tool_result, "content", json_object_new_string(chdir_result)); free(chdir_result); } } } 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; 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); 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; 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; 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); 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; 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)); 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); 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; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { struct json_object *path_obj, *content_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); json_object_object_add(tool_result, "content", json_object_new_string(write_result)); free(write_result); } } } else if (!strcmp(function_name, "db_query")) { 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 *query_obj; if (json_object_object_get_ex(arguments, "query", &query_obj)) { char *query = (char *)json_object_get_string(query_obj); char *db_query_result = tool_function_db_query(query); json_object_object_add(tool_result, "content", json_object_new_string(db_query_result)); ; if (db_query_result != NULL) free(db_query_result); } } } else if (!strcmp(function_name, "db_set")) { 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 *key_obj; struct json_object *value_obj; if (json_object_object_get_ex(arguments, "key", &key_obj) && json_object_object_get_ex(arguments, "value", &value_obj)) { char *key = (char *)json_object_get_string(key_obj); char *value = (char *)json_object_get_string(value_obj); char *db_set_result = tool_function_db_set(key, value); json_object_object_add(tool_result, "content", json_object_new_string(db_set_result)); free(db_set_result); } } } else if (!strcmp(function_name, "index_source_directory")) { 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; if (json_object_object_get_ex(arguments, "path", &path_obj)) { char *path = (char *)json_object_get_string(path_obj); char *listing_result = tool_function_index_source_directory(path); json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); free(listing_result); } } } else if (!strcmp(function_name, "web_search_news")) { 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 *query_obj; if (json_object_object_get_ex(arguments, "query", &query_obj)) { char *query = (char *)json_object_get_string(query_obj); char *news_result = tool_function_web_search_news(query); json_object_object_add(tool_result, "content", json_object_new_string(news_result)); free(news_result); } } } else if (!strcmp(function_name, "web_search")) { 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 *query_obj; if (json_object_object_get_ex(arguments, "query", &query_obj)) { char *query = (char *)json_object_get_string(query_obj); char *news_result = tool_function_web_search(query); json_object_object_add(tool_result, "content", json_object_new_string(news_result)); free(news_result); } } } else if (!strcmp(function_name, "db_get")) { 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 *key_obj; if (json_object_object_get_ex(arguments, "key", &key_obj)) { char *key = (char *)json_object_get_string(key_obj); char *db_get_result = tool_function_db_get(key); json_object_object_add(tool_result, "content", json_object_new_string(db_get_result)); free(db_get_result); } } } else if (!strcmp(function_name, "getpwd")) { char *pwd_result = tool_function_getpwd(); json_object_object_add(tool_result, "content", json_object_new_string(pwd_result)); free(pwd_result); } else if (!strcmp(function_name, "directory_rglob")) { 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; 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); json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); free(listing_result); } } } else if (!strcmp(function_name, "mkdir")) { 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; if (json_object_object_get_ex(arguments, "path", &path_obj)) { char *path = (char *)json_object_get_string(path_obj); char *mkdir_result = tool_function_mkdir(path); json_object_object_add(tool_result, "content", json_object_new_string(mkdir_result)); free(mkdir_result); } } } else { 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_array_add(tools_result_messages, tool_result); } } return tools_result_messages; } #endif