Error handling.
This commit is contained in:
		
							parent
							
								
									bce037286c
								
							
						
					
					
						commit
						09e43ed176
					
				
							
								
								
									
										23
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								main.c
									
									
									
									
									
								
							| @ -36,6 +36,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | #include "utils.h" | ||||||
| 
 | 
 | ||||||
| bool SYNTAX_HIGHLIGHT_ENABLED = true; | bool SYNTAX_HIGHLIGHT_ENABLED = true; | ||||||
| bool API_MODE = false; | bool API_MODE = false; | ||||||
| @ -178,10 +179,14 @@ void render(char *content){ | |||||||
|             prompt[0] = 0; |             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); |             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); |             char* result = openai_chat("user",prompt); | ||||||
|             printf("%s\n",result); | 
 | ||||||
|             free(prompt); | 
 | ||||||
|             free(result); |  | ||||||
|             free(buffer); |             free(buffer); | ||||||
|  |             free(prompt); | ||||||
|  |             if(result){ | ||||||
|  |                 printf("%s\n",result); | ||||||
|  |                 free(result); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if(!strcmp(parameter, "!write_note")){ |         if(!strcmp(parameter, "!write_note")){ | ||||||
| @ -303,9 +308,11 @@ void repl() { | |||||||
|         if(*line){ |         if(*line){ | ||||||
|             line_add_history(line); |             line_add_history(line); | ||||||
|             char *response = openai_chat("user", line); |             char *response = openai_chat("user", line); | ||||||
|             render(response); |             if(response){ | ||||||
|             printf("\n"); |                 render(response); | ||||||
|             free(response); |                 printf("\n"); | ||||||
|  |                 free(response); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -377,7 +384,9 @@ bool openai_include(char *path) { | |||||||
|         " 8. find ten largest folders on my pc using sudo."); |         " 8. find ten largest folders on my pc using sudo."); | ||||||
|         return true; |         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) { |     if (file == NULL) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								messages.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								messages.h
									
									
									
									
									
								
							| @ -25,6 +25,15 @@ struct json_object *message_list() { | |||||||
|     return message_array; |     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 *message_add_tool_call(struct json_object *message) { | ||||||
|     struct json_object *messages = message_list(); |     struct json_object *messages = message_list(); | ||||||
|     json_object_array_add(messages, message); |     json_object_array_add(messages, message); | ||||||
| @ -67,4 +76,4 @@ void message_free() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								openai.h
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								openai.h
									
									
									
									
									
								
							| @ -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); |     struct json_object* parsed_json = json_tokener_parse(response); | ||||||
|     if (!parsed_json) { |     if (!parsed_json) { | ||||||
|         fprintf(stderr, "Failed to parse JSON.\n %s \n", response); |         fprintf(stderr, "Failed to parse JSON.\n %s \n", response); | ||||||
|         return json_object_new_null(); |         return NULL; | ||||||
|     } |     } | ||||||
|     struct json_object *error_object; |     struct json_object *error_object; | ||||||
|     if (json_object_object_get_ex(parsed_json, "error", &error_object)) { |     if (json_object_object_get_ex(parsed_json, "error", &error_object)) { | ||||||
|         fprintf(stderr, "Failed to get 'error' object.\n %s \n", response); |         fprintf(stderr, "Failed to get 'error' object.\n %s \n", response); | ||||||
|         json_object_put(parsed_json); |         json_object_put(parsed_json); | ||||||
|         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; |     struct json_object* choices_array; | ||||||
|     if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) { |     if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) { | ||||||
|         fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response); |         fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response); | ||||||
|         json_object_put(parsed_json); |         json_object_put(parsed_json); | ||||||
|         return json_object_new_null(); |         return NULL; | ||||||
|     } |     } | ||||||
|     struct json_object* first_choice = json_object_array_get_idx(choices_array, 0); |     struct json_object* first_choice = json_object_array_get_idx(choices_array, 0); | ||||||
|     if (!first_choice) { |     if (!first_choice) { | ||||||
|         fprintf(stderr, "Failed to get the first element of 'choices'.\n"); |         fprintf(stderr, "Failed to get the first element of 'choices'.\n"); | ||||||
|         json_object_put(parsed_json); |         json_object_put(parsed_json); | ||||||
|         return json_object_new_null(); |         return NULL; | ||||||
|     } |     } | ||||||
|     struct json_object* message_object; |     struct json_object* message_object; | ||||||
|     if (!json_object_object_get_ex(first_choice, "message", &message_object)) { |     if (!json_object_object_get_ex(first_choice, "message", &message_object)) { | ||||||
|         fprintf(stderr, "Failed to get 'message' object.\n"); |         fprintf(stderr, "Failed to get 'message' object.\n"); | ||||||
|         json_object_put(parsed_json); |         json_object_put(parsed_json); | ||||||
|         return json_object_new_null(); |         return NULL; | ||||||
|     } |     } | ||||||
|     return message_object; |     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"; |     const char* api_url = "https://api.openai.com/v1/chat/completions"; | ||||||
|     char* json_data = chat_json(user_role, message_content); |     char* json_data = chat_json(user_role, message_content); | ||||||
|     struct json_object* message_object = openai_process_chat_message(api_url, json_data); |     struct json_object* message_object = openai_process_chat_message(api_url, json_data); | ||||||
|  |     if(message_object == NULL) { | ||||||
|  |         printf("ERROR + NULL IS SUCCESS\n"); | ||||||
|  |         return NULL;  | ||||||
|  |     } | ||||||
|     struct json_object* tool_calls; |     struct json_object* tool_calls; | ||||||
|     json_object_object_get_ex(message_object, "tool_calls", &tool_calls); |     json_object_object_get_ex(message_object, "tool_calls", &tool_calls); | ||||||
|     if (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); |         char* tool_calls_result_str = chat_json(NULL, NULL); | ||||||
|         message_object = openai_process_chat_message(api_url, tool_calls_result_str); |         message_object = openai_process_chat_message(api_url, tool_calls_result_str); | ||||||
|  |         if(message_object == NULL) { | ||||||
|  |             return NULL;  | ||||||
|  |         } | ||||||
|         message_add_tool_call(message_object); |         message_add_tool_call(message_object); | ||||||
|     } |     } | ||||||
|     const char* content_str = json_object_get_string(json_object_object_get(message_object, "content")); |     const char* content_str = json_object_get_string(json_object_object_get(message_object, "content")); | ||||||
|  | |||||||
							
								
								
									
										90
									
								
								tools.h
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								tools.h
									
									
									
									
									
								
							| @ -24,6 +24,7 @@ struct json_object *tool_description_directory_glob(); | |||||||
| struct json_object *tool_description_read_file(); | struct json_object *tool_description_read_file(); | ||||||
| struct json_object *tool_description_write_file(); | struct json_object *tool_description_write_file(); | ||||||
| struct json_object *tool_description_directory_rglob(); | struct json_object *tool_description_directory_rglob(); | ||||||
|  | struct json_object *tool_description_linux_terminal_interactive(); | ||||||
| 
 | 
 | ||||||
| struct json_object *tools_descriptions() { | struct json_object *tools_descriptions() { | ||||||
|     struct json_object *root = json_object_new_array(); |     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_read_file()); | ||||||
|     json_object_array_add(root, tool_description_write_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_directory_rglob()); | ||||||
| 
 |     json_object_array_add(root, tool_description_linux_terminal_interactive()); | ||||||
|     return root; |     return root; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -57,7 +58,7 @@ char *tool_function_linux_terminal(char *command) { | |||||||
| 
 | 
 | ||||||
|     while (fgets(buffer, sizeof(buffer), fp) != NULL) { |     while (fgets(buffer, sizeof(buffer), fp) != NULL) { | ||||||
|         size_t chunk_size = strlen(buffer); |         size_t chunk_size = strlen(buffer); | ||||||
|         char *new_output = realloc(output, total_size + chunk_size + 1); |         char *new_output = (char *)realloc(output, total_size + chunk_size + 1); | ||||||
|         if (new_output == NULL) { |         if (new_output == NULL) { | ||||||
|             perror("realloc failed"); |             perror("realloc failed"); | ||||||
|             free(output); |             free(output); | ||||||
| @ -73,6 +74,54 @@ char *tool_function_linux_terminal(char *command) { | |||||||
|     return output ? output : strdup(""); |     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 *tool_description_directory_rglob() { | ||||||
|     struct json_object *root = json_object_new_object(); |     struct json_object *root = json_object_new_object(); | ||||||
|     json_object_object_add(root, "type", json_object_new_string("function")); |     json_object_object_add(root, "type", json_object_new_string("function")); | ||||||
| @ -537,12 +586,24 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                     struct json_object *url_obj; |                     struct json_object *url_obj; | ||||||
|                     if (json_object_object_get_ex(arguments, "command", &url_obj)) { |                     if (json_object_object_get_ex(arguments, "command", &url_obj)) { | ||||||
|                         char *command = (char *)json_object_get_string(url_obj); |                         char *command = (char *)json_object_get_string(url_obj); | ||||||
|                         char *http_result = tool_function_linux_terminal(command); |                         char *terminal_result = tool_function_linux_terminal(command); | ||||||
|                         json_object_object_add(tool_result, "content", json_object_new_string(http_result)); |                         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")) { | ||||||
|             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 *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; |                 struct json_object *arguments_obj; | ||||||
|                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { |                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { | ||||||
|                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); |                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); | ||||||
| @ -554,8 +615,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                         free(listing_result); |                         free(listing_result); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } else if (!strcmp(function_name, "http_fetch")) { | ||||||
|             if (!strcmp(function_name, "http_fetch")) { |  | ||||||
|                 struct json_object *arguments_obj; |                 struct json_object *arguments_obj; | ||||||
|                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { |                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { | ||||||
|                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); |                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); | ||||||
| @ -564,11 +624,10 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                         char *url = (char *)json_object_get_string(url_obj); |                         char *url = (char *)json_object_get_string(url_obj); | ||||||
|                         char *http_result = tool_function_http_get(url); |                         char *http_result = tool_function_http_get(url); | ||||||
|                         json_object_object_add(tool_result, "content", json_object_new_string(http_result)); |                         json_object_object_add(tool_result, "content", json_object_new_string(http_result)); | ||||||
|  |                         free(http_result); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } else if (!strcmp(function_name, "read_file")) { | ||||||
| 
 |  | ||||||
|             if (!strcmp(function_name, "read_file")) { |  | ||||||
|                 struct json_object *arguments_obj; |                 struct json_object *arguments_obj; | ||||||
|                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { |                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { | ||||||
|                     struct json_object *path_obj; |                     struct json_object *path_obj; | ||||||
| @ -582,8 +641,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                         free(file_content); |                         free(file_content); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } else if (!strcmp(function_name, "write_file")) { | ||||||
|             if (!strcmp(function_name, "write_file")) { |  | ||||||
|                 struct json_object *arguments_obj; |                 struct json_object *arguments_obj; | ||||||
|                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { |                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { | ||||||
|                     struct json_object *path_obj, *content_obj; |                     struct json_object *path_obj, *content_obj; | ||||||
| @ -599,8 +657,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                         free(write_result); |                         free(write_result); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } else if (!strcmp(function_name, "directory_rglob")) { | ||||||
|             if (!strcmp(function_name, "directory_rglob")) { |  | ||||||
|                 struct json_object *arguments_obj; |                 struct json_object *arguments_obj; | ||||||
|                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { |                 if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { | ||||||
|                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); |                     struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); | ||||||
| @ -612,6 +669,9 @@ struct json_object *tools_execute(struct json_object *tools_array) { | |||||||
|                         free(listing_result); |                         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); |             json_object_array_add(tools_result_messages, tool_result); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user