Python execute.
This commit is contained in:
parent
cc00756479
commit
13d50fcd13
7
Makefile
7
Makefile
@ -66,3 +66,10 @@ docker_run:
|
||||
|
||||
build_deb:
|
||||
dpkg-deb --build r_package
|
||||
|
||||
# --- RAG Side Project ---
|
||||
rag_test: rag_test.c rag.c db_utils.c rag.h db_utils.h
|
||||
$(CC) -o rag_test rag_test.c rag.c db_utils.c -lsqlite3 -ljson-c
|
||||
|
||||
run_rag_test: rag_test
|
||||
./rag_test
|
||||
|
104
main.c
104
main.c
@ -1,12 +1,4 @@
|
||||
#include "r.h"
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "db_utils.h"
|
||||
#include "line.h"
|
||||
#include "markdown.h"
|
||||
@ -14,27 +6,40 @@
|
||||
#include "tools.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
volatile sig_atomic_t sigint_count = 0;
|
||||
time_t first_sigint_time = 0;
|
||||
bool SYNTAX_HIGHLIGHT_ENABLED = true;
|
||||
bool API_MODE = false;
|
||||
|
||||
void help();
|
||||
void render(const char *);
|
||||
bool openai_include(const char *);
|
||||
char *strreplace(const char *, const char *, const char *);
|
||||
static void render(const char *content);
|
||||
static bool openai_include(const char *path);
|
||||
static char *get_prompt_from_stdin(char *prompt);
|
||||
static char *get_prompt_from_args(int argc, char **argv);
|
||||
static bool try_prompt(int argc, char *argv[]);
|
||||
static void repl(void);
|
||||
static void init(void);
|
||||
static void handle_sigint(int sig);
|
||||
|
||||
char *get_prompt_from_stdin(char *prompt) {
|
||||
static char *get_prompt_from_stdin(char *prompt) {
|
||||
int index = 0;
|
||||
char c;
|
||||
int c;
|
||||
while ((c = getchar()) != EOF) {
|
||||
prompt[index++] = c;
|
||||
prompt[index++] = (char)c;
|
||||
}
|
||||
prompt[index] = '\0';
|
||||
return prompt;
|
||||
}
|
||||
|
||||
char *get_prompt_from_args(int argc, char **argv) {
|
||||
static char *get_prompt_from_args(int argc, char **argv) {
|
||||
char *prompt = malloc(10 * 1024 * 1024 + 1);
|
||||
char *system = malloc(1024 * 1024);
|
||||
if (!prompt || !system) {
|
||||
@ -90,7 +95,7 @@ char *get_prompt_from_args(int argc, char **argv) {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
bool try_prompt(int argc, char *argv[]) {
|
||||
static bool try_prompt(int argc, char *argv[]) {
|
||||
char *prompt = get_prompt_from_args(argc, argv);
|
||||
if (prompt) {
|
||||
char *response = openai_chat("user", prompt);
|
||||
@ -107,30 +112,17 @@ bool try_prompt(int argc, char *argv[]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char **get_parameters(const char *content, const char *delimiter) {
|
||||
char *start = NULL;
|
||||
char **parameters = NULL;
|
||||
int count = 0;
|
||||
static bool openai_include(const char *path) {
|
||||
char *file_content = read_file(path);
|
||||
if (!file_content)
|
||||
return false;
|
||||
|
||||
while ((start = strstr(content, delimiter)) != NULL) {
|
||||
start += 3;
|
||||
char *end = strstr(start, delimiter);
|
||||
char *parameter = malloc(end - start + 1);
|
||||
|
||||
memcpy(parameter, start, end - start);
|
||||
parameter[end - start] = '\0';
|
||||
|
||||
content = end + 3;
|
||||
count++;
|
||||
parameters = realloc(parameters, sizeof(char *) * (count + 1));
|
||||
parameters[count - 1] = parameter;
|
||||
parameters[count] = NULL;
|
||||
openai_system(file_content);
|
||||
free(file_content);
|
||||
return true;
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
void render(const char *content) {
|
||||
static void render(const char *content) {
|
||||
if (SYNTAX_HIGHLIGHT_ENABLED) {
|
||||
parse_markdown_to_ansi(content);
|
||||
} else {
|
||||
@ -138,7 +130,7 @@ void render(const char *content) {
|
||||
}
|
||||
}
|
||||
|
||||
void repl() {
|
||||
static void repl(void) {
|
||||
line_init();
|
||||
char *line = NULL;
|
||||
|
||||
@ -153,15 +145,13 @@ void repl() {
|
||||
}
|
||||
if (!strncmp(line, "!verbose", 8)) {
|
||||
is_verbose = !is_verbose;
|
||||
fprintf(stderr, "%s\n",
|
||||
is_verbose ? "Verbose mode enabled" : "Verbose mode disabled");
|
||||
fprintf(stderr, "%s\n", is_verbose ? "Verbose mode enabled" : "Verbose mode disabled");
|
||||
continue;
|
||||
}
|
||||
if (line && *line != '\n')
|
||||
line_add_history(line);
|
||||
if (!strncmp(line, "!tools", 6)) {
|
||||
printf("Available tools: %s\n",
|
||||
json_object_to_json_string(tools_descriptions()));
|
||||
printf("Available tools: %s\n", json_object_to_json_string(tools_descriptions()));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(line, "!models", 7)) {
|
||||
@ -196,29 +186,7 @@ void repl() {
|
||||
}
|
||||
}
|
||||
|
||||
char *strreplace(const char *content, const char *what, const char *with) {
|
||||
char *pos = strstr(content, what);
|
||||
if (!pos)
|
||||
return strdup(content);
|
||||
|
||||
size_t result_size = strlen(content) + strlen(with) - strlen(what) + 1;
|
||||
char *result = malloc(result_size);
|
||||
snprintf(result, result_size, "%.*s%s%s", (int)(pos - content), content, with,
|
||||
pos + strlen(what));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool openai_include(const char *path) {
|
||||
char *file_content = read_file(path);
|
||||
if (!file_content)
|
||||
return false;
|
||||
|
||||
openai_system(file_content);
|
||||
free(file_content);
|
||||
return true;
|
||||
}
|
||||
|
||||
void init() {
|
||||
static void init(void) {
|
||||
setbuf(stdout, NULL);
|
||||
line_init();
|
||||
auth_init();
|
||||
@ -232,7 +200,7 @@ void init() {
|
||||
schema);
|
||||
free(schema);
|
||||
|
||||
fprintf(stderr, "Loading... 4e6");
|
||||
fprintf(stderr, "Loading... 📨");
|
||||
openai_system(payload);
|
||||
if (!openai_include(".rcontext.txt")) {
|
||||
openai_include("~/.rcontext.txt");
|
||||
@ -240,7 +208,7 @@ void init() {
|
||||
fprintf(stderr, "\r \r");
|
||||
}
|
||||
|
||||
void handle_sigint(int sig) {
|
||||
static void handle_sigint(int sig) {
|
||||
time_t current_time = time(NULL);
|
||||
printf("\n");
|
||||
if (sigint_count == 0) {
|
||||
|
115
tools.h
115
tools.h
@ -49,6 +49,15 @@ 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 *tool_description_python_execute();
|
||||
|
||||
struct json_object *tool_description_rag_search();
|
||||
struct json_object *tool_description_rag_chunk();
|
||||
char *tool_function_rag_search(char *query, int top_k);
|
||||
char *tool_function_rag_chunk(char *file_path);
|
||||
|
||||
|
||||
char *tool_function_python_execute(char *source_code);
|
||||
|
||||
struct json_object *tools_descriptions() {
|
||||
struct json_object *root = json_object_new_array();
|
||||
@ -68,6 +77,8 @@ struct json_object *tools_descriptions() {
|
||||
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());
|
||||
json_object_array_add(root, tool_description_python_execute());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -411,6 +422,86 @@ char *tool_function_linux_terminal_interactive(char *command) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---- PYTHON EXECUTE TOOL ----
|
||||
char *tool_function_python_execute(char *source_code) {
|
||||
char tmp_file[] = "/tmp/r_python_tool_XXXXXX.py";
|
||||
int fd = mkstemps(tmp_file, 3); // 3 for ".py"
|
||||
if (fd == -1) {
|
||||
return strdup("Failed to create temporary file for Python code.");
|
||||
}
|
||||
FILE *fp = fdopen(fd, "w");
|
||||
if (!fp) {
|
||||
close(fd);
|
||||
return strdup("Failed to open temporary file for writing.");
|
||||
}
|
||||
fwrite(source_code, 1, strlen(source_code), fp);
|
||||
fclose(fp);
|
||||
|
||||
char command[4096];
|
||||
snprintf(command, sizeof(command), "python3 '%s' 2>&1", tmp_file);
|
||||
|
||||
FILE *proc = popen(command, "r");
|
||||
if (!proc) {
|
||||
unlink(tmp_file);
|
||||
return strdup("Failed to execute python3.");
|
||||
}
|
||||
char buffer[1024];
|
||||
size_t total = 0;
|
||||
char *output = NULL;
|
||||
while (fgets(buffer, sizeof(buffer), proc)) {
|
||||
size_t len = strlen(buffer);
|
||||
char *new_output = realloc(output, total + len + 1);
|
||||
if (!new_output) {
|
||||
free(output);
|
||||
pclose(proc);
|
||||
unlink(tmp_file);
|
||||
return strdup("Memory allocation failed.");
|
||||
}
|
||||
output = new_output;
|
||||
strcpy(output + total, buffer);
|
||||
total += len;
|
||||
}
|
||||
if (output)
|
||||
output[total] = 0;
|
||||
else
|
||||
output = strdup("");
|
||||
pclose(proc);
|
||||
unlink(tmp_file);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_python_execute() {
|
||||
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("python_execute"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Executes Python source code using the python3 interpreter and returns stdout/stderr."));
|
||||
|
||||
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 *source = json_object_new_object();
|
||||
json_object_object_add(source, "type", json_object_new_string("string"));
|
||||
json_object_object_add(source, "description", json_object_new_string("Python source code to execute."));
|
||||
json_object_object_add(properties, "source", source);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("source"));
|
||||
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(root, "function", function);
|
||||
|
||||
return root;
|
||||
}
|
||||
// ---- END PYTHON EXECUTE TOOL ----
|
||||
|
||||
char *tool_function_getpwd() {
|
||||
char *cwd = (char *)malloc(PATH_MAX);
|
||||
if (cwd == NULL) {
|
||||
@ -555,8 +646,7 @@ struct json_object *tool_description_linux_terminal_interactive() {
|
||||
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_object_add(path, "description",
|
||||
json_object_new_string(
|
||||
"Executable with parameters to execute interactively."));
|
||||
json_object_object_add(properties, "command", path);
|
||||
@ -725,7 +815,10 @@ struct json_object *tool_description_write_file() {
|
||||
}
|
||||
|
||||
char *tool_function_index_source_directory(char *path) {
|
||||
return index_directory(path);
|
||||
char * result = index_directory(path);
|
||||
if(!result)
|
||||
return strdup("Failed to index directory!");
|
||||
return result;
|
||||
}
|
||||
|
||||
char *tool_function_mkdir(char *path);
|
||||
@ -1133,9 +1226,13 @@ char *tool_function_mkdir(char *path) {
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
if (mkdir(temp, 0777) != 0 && errno != EEXIST) {
|
||||
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"));
|
||||
@ -1462,6 +1559,18 @@ struct json_object *tools_execute(struct json_object *tools_array) {
|
||||
free(mkdir_result);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "python_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 *source_obj;
|
||||
if (json_object_object_get_ex(arguments, "source", &source_obj)) {
|
||||
char *source = (char *)json_object_get_string(source_obj);
|
||||
char *result = tool_function_python_execute(source);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(result));
|
||||
free(result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unknown function: %s\n", function_name);
|
||||
json_object_object_add(
|
||||
|
Loading…
Reference in New Issue
Block a user