diff --git a/browse.h b/browse.h index 377fbd6..f4f67df 100644 --- a/browse.h +++ b/browse.h @@ -47,7 +47,7 @@ char * web_search(char * q){ if(!json_result){ json_object_put(json_ret); free(ret); - return web_search_news(q); + return web_search(q); } json_object_put(json_ret); return ret; diff --git a/db_utils.h b/db_utils.h index f5544cf..2851c67 100644 --- a/db_utils.h +++ b/db_utils.h @@ -7,6 +7,9 @@ const char * db_file = "~/.r.db"; + +json_object* db_execute(const char *query); + char * db_file_expanded(){ char * expanded = expand_home_directory(db_file); static char result[4096]; @@ -51,7 +54,7 @@ json_object * db_set(const char *key, const char *value) { return NULL; } - char *sql = sqlite3_mprintf("INSERT INTO kv_store (key, value) VALUES (%Q, %Q)", key, value); + char *sql = sqlite3_mprintf("INSERT INTO kv_store (key, value) VALUES (%Q, %Q) ON CONFLICT(key) DO UPDATE SET value = %Q WHERE key = %Q", key, value, value,key); rc = sqlite3_exec(db, sql, 0, 0, &err_msg); sqlite3_free(sql); @@ -97,6 +100,11 @@ json_object* db_get(const char *key) { json_object* db_query(const char *query) { sqlite3 *db; sqlite3_stmt *stmt; + + if(strncmp(query, "SELECT", 6)){ + return db_execute(query); + } + json_object *result = json_object_new_array(); int rc = sqlite3_open(db_file_expanded(), &db); @@ -138,4 +146,33 @@ json_object* db_query(const char *query) { } -#endif // DB_UTILS_H +json_object* db_execute(const char *query) { + sqlite3 *db; + char *err_msg = 0; + int rc = sqlite3_open(db_file_expanded(), &db); + json_object *result = json_object_new_object(); + + if (rc != SQLITE_OK) { + json_object_object_add(result, "error", json_object_new_string("Cannot open database")); + return result; + } + + rc = sqlite3_exec(db, query, 0, 0, &err_msg); + if (rc != SQLITE_OK) { + json_object_object_add(result, "error", json_object_new_string(err_msg)); + sqlite3_free(err_msg); + } else { + json_object_object_add(result, "success", json_object_new_string("Query executed successfully")); + } + + sqlite3_close(db); + return result; +} +char * db_get_schema(){ + json_object * tables =db_query("SELECT * FROM sqlite_master WHERE type='table'"); + char * result = strdup(json_object_get_string(tables)); + json_object_put(tables); + return result; +} + +#endif diff --git a/main.c b/main.c index 20d826e..3d031ef 100644 --- a/main.c +++ b/main.c @@ -192,7 +192,6 @@ void render(char *content) if(SYNTAX_HIGHLIGHT_ENABLED) { parse_markdown_to_ansi(content); - printf("\n\n"); }else{ printf("%s", content); } @@ -317,13 +316,17 @@ bool openai_include(char *path) { return true; } + + void init() { setbuf(stdout, NULL); line_init(); auth_init(); - const char *locale = setlocale(LC_ALL, NULL); - char payload[4096] = {0}; - sprintf(payload, "Your locale is %s. User lang is %s.", locale, locale); + db_initialize(); + char * schema = db_get_schema(); + char payload[1024*1024] = {0}; + sprintf(payload, "Your have a database that you can mutate using the query tool and the get and set tool. This is the schema in json format: %s. Dialect is sqlite.", schema); + free(schema); fprintf(stderr, "%s", "Loading... ⏳"); openai_system(payload); if(!openai_include(".rcontext.txt")){ @@ -353,7 +356,7 @@ void handle_sigint(int sig) { int main(int argc, char *argv[]) { signal(SIGINT, handle_sigint); - db_initialize(); + init(); if (try_prompt(argc, argv)) return 0; diff --git a/markdown.h b/markdown.h index 8a7c3d5..3ae7a39 100644 --- a/markdown.h +++ b/markdown.h @@ -114,7 +114,14 @@ void parse_markdown_to_ansi(const char *markdown) { continue; }else if(!strncmp(ptr, "```", 3)) { inside_code = !inside_code; + if(inside_code){ ptr = strstr(ptr, "\n") + 1; + }else{ + ptr+=3; + } + if(*ptr == '\0'){ + break; + } } if (inside_code) { diff --git a/rpylib.so b/rpylib.so index 74d1282..ca04a2d 100755 Binary files a/rpylib.so and b/rpylib.so differ diff --git a/tools.h b/tools.h index b55bdf2..b294b8d 100644 --- a/tools.h +++ b/tools.h @@ -44,6 +44,7 @@ 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* tools_descriptions() { struct json_object* root = json_object_new_array(); @@ -61,6 +62,7 @@ struct json_object* tools_descriptions() { 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()); return root; } @@ -111,6 +113,57 @@ struct json_object* tool_description_web_search_news() { 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); @@ -1070,6 +1123,18 @@ struct json_object* tools_execute(struct json_object* tools_array) { 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)) {