Error handling.

This commit is contained in:
retoor 2025-03-05 23:53:35 +01:00
parent bce037286c
commit 09e43ed176
4 changed files with 120 additions and 28 deletions

23
main.c
View File

@ -36,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "utils.h"
bool SYNTAX_HIGHLIGHT_ENABLED = true;
bool API_MODE = false;
@ -178,10 +179,14 @@ void render(char *content){
prompt[0] = 0;
sprintf(prompt,"This are records seperated by newline: ```%s```. Respond to use with record that is about ```%s```. Rspond in plain text, do not execute command.",buffer, note_name);
char* result = openai_chat("user",prompt);
printf("%s\n",result);
free(prompt);
free(result);
free(buffer);
free(prompt);
if(result){
printf("%s\n",result);
free(result);
}
}
if(!strcmp(parameter, "!write_note")){
@ -303,9 +308,11 @@ void repl() {
if(*line){
line_add_history(line);
char *response = openai_chat("user", line);
render(response);
printf("\n");
free(response);
if(response){
render(response);
printf("\n");
free(response);
}
}
}
}
@ -377,7 +384,9 @@ bool openai_include(char *path) {
" 8. find ten largest folders on my pc using sudo.");
return true;
}
FILE *file = fopen(path, "r");
char * expanded_path = expand_home_directory(path);
FILE *file = fopen(expanded_path, "r");
free(expanded_path);
if (file == NULL) {
return false;
}

View File

@ -25,6 +25,15 @@ struct json_object *message_list() {
return message_array;
}
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);
}
}
struct json_object *message_add_tool_call(struct json_object *message) {
struct json_object *messages = message_list();
json_object_array_add(messages, message);
@ -67,4 +76,4 @@ void message_free() {
}
}
#endif
#endif

View File

@ -52,32 +52,39 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
struct json_object* parsed_json = json_tokener_parse(response);
if (!parsed_json) {
fprintf(stderr, "Failed to parse JSON.\n %s \n", response);
return json_object_new_null();
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);
json_object_put(parsed_json);
return json_object_new_null();
char * all_messages = (char *)json_object_to_json_string(message_array);
fprintf(stderr, "Messages: ");
fwrite(all_messages,strlen(all_messages),1, stderr);
fprintf(stderr, "\n");
free(all_messages);
messages_remove_last();
messages_remove_last();
return NULL;
}
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);
json_object_put(parsed_json);
return json_object_new_null();
return NULL;
}
struct json_object* first_choice = json_object_array_get_idx(choices_array, 0);
if (!first_choice) {
fprintf(stderr, "Failed to get the first element of 'choices'.\n");
json_object_put(parsed_json);
return json_object_new_null();
return NULL;
}
struct json_object* message_object;
if (!json_object_object_get_ex(first_choice, "message", &message_object)) {
fprintf(stderr, "Failed to get 'message' object.\n");
json_object_put(parsed_json);
return json_object_new_null();
return NULL;
}
return message_object;
}
@ -86,6 +93,10 @@ 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) {
printf("ERROR + NULL IS SUCCESS\n");
return NULL;
}
struct json_object* tool_calls;
json_object_object_get_ex(message_object, "tool_calls", &tool_calls);
if (tool_calls) {
@ -98,6 +109,9 @@ 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;
}
message_add_tool_call(message_object);
}
const char* content_str = json_object_get_string(json_object_object_get(message_object, "content"));

90
tools.h
View File

@ -24,6 +24,7 @@ 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();
@ -33,7 +34,7 @@ struct json_object *tools_descriptions() {
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());
return root;
}
@ -57,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 = realloc(output, total_size + chunk_size + 1);
char *new_output = (char *)realloc(output, total_size + chunk_size + 1);
if (new_output == NULL) {
perror("realloc failed");
free(output);
@ -73,6 +74,54 @@ char *tool_function_linux_terminal(char *command) {
return output ? output : strdup("");
}
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);
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();
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 interactive."));;
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"));
@ -537,12 +586,24 @@ struct json_object *tools_execute(struct json_object *tools_array) {
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 *http_result = tool_function_linux_terminal(command);
json_object_object_add(tool_result, "content", json_object_new_string(http_result));
char *terminal_result = tool_function_linux_terminal(command);
json_object_object_add(tool_result, "content", json_object_new_string(terminal_result));
free(terminal_result);
}
}
}
if (!strcmp(function_name, "directory_glob")) {
} 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, "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));
@ -554,8 +615,7 @@ struct json_object *tools_execute(struct json_object *tools_array) {
free(listing_result);
}
}
}
if (!strcmp(function_name, "http_fetch")) {
} 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));
@ -564,11 +624,10 @@ struct json_object *tools_execute(struct json_object *tools_array) {
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);
}
}
}
if (!strcmp(function_name, "read_file")) {
} 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;
@ -582,8 +641,7 @@ struct json_object *tools_execute(struct json_object *tools_array) {
free(file_content);
}
}
}
if (!strcmp(function_name, "write_file")) {
} 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;
@ -599,8 +657,7 @@ struct json_object *tools_execute(struct json_object *tools_array) {
free(write_result);
}
}
}
if (!strcmp(function_name, "directory_rglob")) {
} 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));
@ -612,6 +669,9 @@ struct json_object *tools_execute(struct json_object *tools_array) {
free(listing_result);
}
}
}else {
fprintf(stderr, "Unkown 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);