diff --git a/line.h b/line.h index fd6d412..9738cf9 100644 --- a/line.h +++ b/line.h @@ -13,7 +13,7 @@ #include <string.h> #include <stdbool.h> -#define HISTORY_FILE "~/.calpaca_history" +#define HISTORY_FILE ".r_history" bool line_initialized = false; @@ -61,7 +61,6 @@ char* line_read(char* prefix) { } void line_add_history(char* data) { - read_history(HISTORY_FILE); add_history(data); write_history(HISTORY_FILE); -} \ No newline at end of file +} diff --git a/tools.h b/tools.h index 80f859a..8c55849 100644 --- a/tools.h +++ b/tools.h @@ -15,17 +15,54 @@ #include "http_curl.h" struct json_object *tool_description_http_get(); +struct json_object *tool_description_bash(); 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_bash()); return root; } char *tool_function_http_get(char *url) { + fprintf(stderr, "Tool http_get: %s\n", url); return curl_get(url); } +char * tool_function_bash(char * command){ + + fprintf(stderr, "Tool bash: %s\n", command); + FILE *fp; + char buffer[1024]; + size_t total_size = 0; + char *output = NULL; + + // Open the command for reading + fp = popen(command, "r"); + if (fp == NULL) { + perror("popen failed"); + return NULL; + } + + // Read output in chunks + 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 NULL; + } + output = new_output; + strcpy(output + total_size, buffer); + total_size += chunk_size; + } + + pclose(fp); + return output; +} + 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")); @@ -59,9 +96,45 @@ struct json_object *tool_description_http_get() { return root; } + +struct json_object *tool_description_bash() { + 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("bash_execute")); + json_object_object_add(function, "description", json_object_new_string("Execute a bash 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; +} + + 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(); @@ -85,7 +158,19 @@ struct json_object *tools_execute(struct json_object *tools_array) { if (json_object_object_get_ex(function_obj, "name", &name_obj)) { function_name = (char *)json_object_get_string(name_obj); } - + + if (!strcmp(function_name, "bash_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 *url = (char *)json_object_get_string(url_obj); + char *http_result = tool_function_bash(url); + json_object_object_add(tool_result, "content", json_object_new_string(http_result)); + } + } + } if (!strcmp(function_name, "http_fetch")) { struct json_object *arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { @@ -93,7 +178,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { 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 = curl_get(url); + char *http_result = tool_function_http_get(url); json_object_object_add(tool_result, "content", json_object_new_string(http_result)); } } @@ -104,4 +189,4 @@ struct json_object *tools_execute(struct json_object *tools_array) { return tools_result_messages; } -#endif \ No newline at end of file +#endif