Branding.

This commit is contained in:
retoor 2025-03-03 17:06:05 +01:00
parent bee172c6eb
commit bce037286c
12 changed files with 167 additions and 202 deletions

25
auth.h
View File

@ -9,23 +9,24 @@
#ifndef R_AUTH_H
#define R_AUTH_H
#include <stdlib.h>
#include <stdio.h>
const char *resolve_api_key() {
static char *api_key = NULL;
#ifndef FREE_VERSION
api_key = getenv("R_KEY");
if (api_key) {
return api_key;
}
api_key = getenv("OPENAI_API_KEY");
if (api_key) {
return api_key;
}
fprintf(stderr, "\nThere is no API key configured in environment.\n");
exit(1);
#endif
#ifndef FREE_VERSION
api_key = getenv("R_KEY");
if (api_key) {
return api_key;
}
api_key = getenv("OPENAI_API_KEY");
if (api_key) {
return api_key;
}
fprintf(stderr, "\nThere is no API key configured in the environment.\n");
exit(1);
#endif
api_key = "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";
return api_key;
}

11
chat.h
View File

@ -6,7 +6,6 @@
// Non-standard imports: json-c library for handling JSON objects.
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@ -47,27 +46,21 @@ double prompt_temperature = 0.1;
json_object *_prompt = NULL;
void chat_free() {
if (_prompt == NULL) {
return;
}
if (_prompt == NULL) return;
json_object_put(_prompt);
_prompt = NULL;
}
char *chat_json(char *role, char *message) {
char *chat_json(const char *role, const char *message) {
chat_free();
struct json_object *root_object = json_object_new_object();
json_object_object_add(root_object, "model", json_object_new_string(prompt_model));
if (role != NULL && message != NULL) {
message_add(role, message);
json_object_object_add(root_object, "tools", tools_descriptions());
}
json_object_object_add(root_object, "messages", message_list());
json_object_object_add(root_object, "max_tokens", json_object_new_int(prompt_max_tokens));
json_object_object_add(root_object, "temperature", json_object_new_double(prompt_temperature));

72
http.h
View File

@ -6,6 +6,7 @@
// MIT License
#ifndef R_HTTP_H
#define R_HTTP_H
@ -81,13 +82,11 @@ int create_socket(const char *hostname, int port) {
typedef struct ssl_st ssl_stt;
char *read_until_ssl(ssl_stt *sock, char *until) {
static char data[1024 * 1024];
data[0] = 0;
static char data[1024 * 1024] = {0};
int index = 0;
char chunk[2];
while (SSL_read(sock, chunk, 1) == 1) {
data[index] = chunk[0];
index++;
data[index++] = chunk[0];
data[index] = 0;
if (strstr(data, until) != NULL) {
return data;
@ -97,13 +96,11 @@ char *read_until_ssl(ssl_stt *sock, char *until) {
}
char *read_until(int sock, char *until) {
static char data[1024 * 1024];
data[0] = 0;
static char data[1024 * 1024] = {0};
int index = 0;
char chunk[2];
while (recv(sock, chunk, 1, 0) == 1) {
data[index] = chunk[0];
index++;
data[index++] = chunk[0];
data[index] = 0;
if (strstr(data, until) != NULL) {
return data;
@ -127,40 +124,42 @@ size_t hex_to_int(const char *hex) {
return result;
}
bool http_has_header(char * http_headers, char * http_header_name){
char search_for[strlen(http_header_name)+10];
bool http_has_header(char *http_headers, char *http_header_name) {
char search_for[strlen(http_header_name) + 10];
search_for[0] = '\0';
strcpy(search_for,http_header_name);
strcat(search_for,": ");
strcpy(search_for, http_header_name);
strcat(search_for, ": ");
return strstr(http_headers, search_for) != NULL;
}
char * http_header_get_str(char * http_headers, char * http_header_name){
char search_for[strlen(http_header_name)+10];
char *http_header_get_str(char *http_headers, char *http_header_name) {
char search_for[strlen(http_header_name) + 10];
search_for[0] = '\0';
strcpy(search_for,http_header_name);
strcat(search_for,": ");
char * header = strstr(http_headers, search_for);
if(header == NULL){
strcpy(search_for, http_header_name);
strcat(search_for, ": ");
char *header = strstr(http_headers, search_for);
if (!header) {
return NULL;
}
header += strlen(search_for);
char * end = strstr(header, "\r\n");
char *end = strstr(header, "\r\n");
*end = '\0';
char * result = (char *)malloc(end - header + 1);
char *result = (char *)malloc(end - header + 1);
strcpy(result, header);
return result;
}
long http_header_get_long(char * http_headers, char * http_header_name){
char * str_value = http_header_get_str(http_headers, http_header_name);
if(str_value == NULL)
long http_header_get_long(char *http_headers, char *http_header_name) {
char *str_value = http_header_get_str(http_headers, http_header_name);
if (!str_value) {
return 0;
}
long long_value = atol(str_value);
free(str_value);
return long_value;
}
char *https_post(char *url, char *data) {
char *https_post(const char *url, char *data) {
url_t parsed_url;
parse_url(url, &parsed_url);
char *hostname = parsed_url.hostname;
@ -198,15 +197,15 @@ char *https_post(char *url, char *data) {
(void)headers;
long content_length = http_header_get_long(headers, "Content-Length");
if (content_length){
if( content_length > buffer_size) {
if (content_length) {
if (content_length > buffer_size) {
buffer_size = content_length;
buffer = (char *)realloc(buffer, buffer_size);
}
size_t bytes_read = 0;
while(bytes_read < content_length) {
while (bytes_read < content_length) {
int bytes_read_chunk = SSL_read(ssl, buffer + bytes_read, buffer_size - bytes_read);
if(bytes_read_chunk <= 0){
if (bytes_read_chunk <= 0) {
free(buffer);
return NULL;
}
@ -219,8 +218,9 @@ char *https_post(char *url, char *data) {
while (true) {
char *header = read_until_ssl(ssl, "\r\n");
size_t chunk_size = hex_to_int(header);
if (chunk_size == 0)
if (chunk_size == 0) {
break;
}
size_t remaining = chunk_size;
while (remaining > 0) {
size_t to_read = (remaining < buffer_size) ? remaining : buffer_size;
@ -246,7 +246,7 @@ char *https_post(char *url, char *data) {
return buffer;
}
char *https_get(char *url) {
char *https_get(const char *url) {
url_t parsed_url;
parse_url(url, &parsed_url);
char *hostname = parsed_url.hostname;
@ -284,8 +284,9 @@ char *https_get(char *url) {
while (true) {
char *header = read_until_ssl(ssl, "\r\n");
size_t chunk_size = hex_to_int(header);
if (chunk_size == 0)
if (chunk_size == 0) {
break;
}
size_t remaining = chunk_size;
while (remaining > 0) {
size_t to_read = (remaining < buffer_size) ? remaining : buffer_size;
@ -322,7 +323,7 @@ char *http_post(char *url, char *data) {
int buffer_size = 1024 * 1024;
char *buffer = malloc(buffer_size);
size_t chunk_size_total = 0;
size_t len = strlen(data) + strlen(path) + strlen(resolve_api_key()) + 10;
char *request = malloc(len + buffer_size);
sprintf(request,
@ -339,7 +340,7 @@ char *http_post(char *url, char *data) {
char *headers = read_until(sock, "\r\n\r\n");
(void)headers;
size_t actual_buffer_size = buffer_size;
while (true) {
char *header = read_until(sock, "\r\n");
@ -359,7 +360,7 @@ char *http_post(char *url, char *data) {
fprintf(stderr, "Error reading chunk data\n");
return NULL;
}
chunk_size_total += bytes_read;
remaining -= bytes_read;
}
@ -400,8 +401,9 @@ char *http_get(char *url) {
while (true) {
char *header = read_until(sock, "\r\n");
size_t chunk_size = hex_to_int(header);
if (chunk_size == 0)
if (chunk_size == 0) {
break;
}
size_t remaining = chunk_size;
while (remaining > 0) {
size_t to_read = (remaining < buffer_size) ? remaining : buffer_size;

View File

@ -1,6 +1,6 @@
// Written by retoor@molodetz.nl
// This code defines a simple HTTP client using libcurl in C, providing a function `curl_post` to make POST requests with JSON data, including authorization via a bearer token.
// This code defines a simple HTTP client using libcurl in C, providing functions `curl_post` and `curl_get`. These functions enable POST and GET requests with JSON data and include authorization via a bearer token.
// Uses libcurl for HTTP requests and includes a custom "auth.h" for API key resolution.
@ -20,9 +20,9 @@
// from, out of or in connection with the software or the use or other dealings in
// the Software.
#ifndef HTTP_CURL
#define HTTP_CURL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -79,7 +79,6 @@ char *curl_post(const char *url, const char *data) {
return NULL;
}
char *curl_get(const char *url) {
CURL *curl;
CURLcode res;
@ -114,4 +113,4 @@ char *curl_get(const char *url) {
return response.data;
}
#endif
#endif

View File

@ -27,7 +27,6 @@ void extract_urls(const char *input, char **urls, int *url_count) {
cursor += match.rm_eo;
(*url_count)++;
}
regfree(&regex);
}

2
line.h
View File

@ -63,4 +63,4 @@ char* line_read(char* prefix) {
void line_add_history(char* data) {
add_history(data);
write_history(HISTORY_FILE);
}
}

View File

@ -48,7 +48,7 @@ void highlight_code(const char *code) {
const char *ptr = code;
char buffer[4096];
size_t index = 0;
buffer[index] = 0;
while (*ptr) {
if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr == '_')) {
while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= '0' && *ptr <= '9') || (*ptr == '_')) {
@ -102,7 +102,6 @@ void parse_markdown_to_ansi(const char *markdown) {
code_buffer[index++] = 0;
highlight_code(code_buffer);
index = 0;
code_buffer[index] = 0;
}
}
code_buffer[index] = 0;
@ -113,29 +112,39 @@ void parse_markdown_to_ansi(const char *markdown) {
if (strncmp(ptr, "**", 2) == 0) {
printf(BOLD);
ptr += 2;
while (*ptr && strncmp(ptr, "**", 2) != 0) putchar(*ptr++);
while (*ptr && strncmp(ptr, "**", 2) != 0) {
putchar(*ptr++);
}
if (*ptr == '*' && *(ptr + 1) == '*') ptr += 2;
printf(RESET);
} else if (*ptr == '*' && (ptr == markdown || *(ptr - 1) != '*')) {
printf(ITALIC);
ptr++;
while (*ptr && *ptr != '*') putchar(*ptr++);
while (*ptr && *ptr != '*') {
putchar(*ptr++);
}
if (*ptr == '*') ptr++;
printf(RESET);
} else if (strncmp(ptr, "### ", 4) == 0) {
printf(BOLD FG_YELLOW);
ptr += 4;
while (*ptr && *ptr != '\n') putchar(*ptr++);
while (*ptr && *ptr != '\n') {
putchar(*ptr++);
}
printf(RESET "\n");
} else if (strncmp(ptr, "## ", 3) == 0) {
printf(BOLD FG_YELLOW);
ptr += 3;
while (*ptr && *ptr != '\n') putchar(*ptr++);
while (*ptr && *ptr != '\n') {
putchar(*ptr++);
}
printf(RESET "\n");
} else if (strncmp(ptr, "# ", 2) == 0) {
printf(BOLD FG_YELLOW);
ptr += 2;
while (*ptr && *ptr != '\n') putchar(*ptr++);
while (*ptr && *ptr != '\n') {
putchar(*ptr++);
}
printf(RESET "\n");
} else {
putchar(*ptr);

View File

@ -30,33 +30,28 @@ struct json_object *message_add_tool_call(struct json_object *message) {
json_object_array_add(messages, message);
return message;
}
struct json_object *message_add_tool_result(char * tool_call_id, char * tool_result) {
struct json_object *message_add_tool_result(char *tool_call_id, char *tool_result) {
struct json_object *messages = message_list();
struct json_object * message = json_object_new_object();
struct json_object *message = json_object_new_object();
json_object_object_add(message, "tool_call_id", json_object_new_string(tool_call_id));
json_object_object_add(message, "tool_result", json_object_new_string(tool_result));
json_object_array_add(messages, message);
return message;
return message;
}
struct json_object *message_add(const char *role, const char *content) {
struct json_object *messages = message_list();
struct json_object *message = json_object_new_object();
json_object_object_add(message, "role", json_object_new_string(role));
json_object_object_add(message, "content", json_object_new_string(content));
if(!strcmp(role, "user")) {
if (!strcmp(role, "user")) {
json_object_object_add(message, "tools", tools_descriptions());
}
json_object_array_add(messages, message);
return message;
}
@ -72,4 +67,4 @@ void message_free() {
}
}
#endif
#endif

View File

@ -1,5 +1,36 @@
// Written by retoor@molodetz.nl
// This code interacts with OpenAI's API to perform various tasks such as fetching models, sending chat messages, and processing responses.
// Uncommon imports include "http.h", "chat.h", and "http_curl.h". These may be internal or external libraries providing HTTP and JSON communication capabilities required to interact with APIs.
// MIT License
//
// Copyright (c) 2023
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef R_OPENAI_H
#define R_OPENAI_H
#include "http.h"
#include "chat.h"
#include "http_curl.h"
@ -7,35 +38,32 @@
#include <stdbool.h>
char* openai_fetch_models() {
char* api_url = "https://api.openai.com/v1/models";
const char* api_url = "https://api.openai.com/v1/models";
return https_get(api_url);
}
bool openai_system(char* message_content) {
(void)chat_json("system", message_content);
chat_json("system", message_content);
return true;
}
struct json_object* openai_process_chat_message(char* api_url, char* json_data) {
struct json_object* openai_process_chat_message(const char* api_url, const char* json_data) {
char* response = curl_post(api_url, json_data);
struct json_object* parsed_json = json_tokener_parse(response);
if (!parsed_json) {
fprintf(stderr, "Failed to parse JSON.\n");
fprintf(stderr, "%s\n", response);
fprintf(stderr, "Failed to parse JSON.\n %s \n", response);
return json_object_new_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");
fprintf(stderr, "%s\n", response);
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();
}
struct json_object* choices_array;
if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) {
fprintf(stderr, "Failed to get 'choices' array.\n");
fprintf(stderr, "%s\n", response);
fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response);
json_object_put(parsed_json);
return json_object_new_null();
}
@ -54,25 +82,25 @@ struct json_object* openai_process_chat_message(char* api_url, char* json_data)
return message_object;
}
char* openai_chat(char* user_role, char* message_content) {
char* api_url = "https://api.openai.com/v1/chat/completions";
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);
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);
struct json_object* tool_calls;
json_object_object_get_ex(message_object, "tool_calls", &tool_calls);
if (tool_calls) {
message_add_tool_call(message_object);
json_object* tool_call_results = tools_execute(tool_calls);
struct json_object* tool_call_results = tools_execute(tool_calls);
int results_count = json_object_array_length(tool_call_results);
for (int i = 0; i < results_count; i++) {
json_object* tool_call_result = json_object_array_get_idx(tool_call_results, i);
struct json_object* tool_call_result = json_object_array_get_idx(tool_call_results, i);
message_add_tool_call(tool_call_result);
}
char* tool_calls_result_str = chat_json(NULL, NULL);
message_object = openai_process_chat_message(api_url, tool_calls_result_str);
message_add_tool_call(message_object);
}
char* content_str = (char*)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"));
return strdup(content_str);
}

View File

@ -20,13 +20,12 @@ bool plugin_construct() {
if (plugin_initialized) return true;
Py_Initialize();
if (!Py_IsInitialized()) {
fprintf(stderr, "Failed to initialize the Python interpreter\n");
return plugin_initialized;
return false;
}
plugin_initialized = true;
return plugin_initialized;
return true;
}
void plugin_run(char *src) {
@ -45,7 +44,7 @@ void plugin_run(char *src) {
"from datetime import datetime\n"
"%s";
size_t length = strlen(basics) + strlen(src);
char *script = (char *)malloc(length + 1);
char *script = malloc(length + 1);
sprintf(script, basics, src);
script[length] = '\0';
PyRun_SimpleString(script);

142
tools.h
View File

@ -25,7 +25,6 @@ struct json_object *tool_description_read_file();
struct json_object *tool_description_write_file();
struct json_object *tool_description_directory_rglob();
struct json_object *tools_descriptions() {
struct json_object *root = json_object_new_array();
json_object_array_add(root, tool_description_http_get());
@ -43,22 +42,19 @@ char *tool_function_http_get(char *url) {
return curl_get(url);
}
char * tool_function_linux_terminal(char * command){
char *tool_function_linux_terminal(char *command) {
fprintf(stderr, "Tool linux_terminal: %s\n", command);
FILE *fp;
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 strdup("Popen failed!");
}
// 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);
@ -111,8 +107,6 @@ struct json_object *tool_description_directory_rglob() {
return root;
}
struct json_object *tool_description_read_file() {
struct json_object *root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function"));
@ -146,7 +140,6 @@ struct json_object *tool_description_read_file() {
return root;
}
// Write File Description
struct json_object *tool_description_write_file() {
struct json_object *root = json_object_new_object();
json_object_object_add(root, "type", json_object_new_string("function"));
@ -206,14 +199,13 @@ char *tool_function_read_file(char *path) {
}
ssize_t read_size = fread(content, 1, size, fp);
(void)read_size;
content[size] = '\0';
content[read_size] = '\0';
fclose(fp);
return content;
}
// Write content to a file
char *tool_function_write_file(char *path, char *content) {
fprintf(stderr, "Tools write_file with %zu bytes: %s\n", strlen(content), path);
FILE *fp = fopen(path, "w");
@ -225,137 +217,105 @@ char *tool_function_write_file(char *path, char *content) {
fwrite(content, 1, strlen(content), fp);
fclose(fp);
return strdup("File written successfully.");
return strdup("File successfully written.");
}
const char *get_file_type(struct stat *st) {
if (S_ISREG(st->st_mode)) return "file";
if (S_ISDIR(st->st_mode)) return "directory";
return "other";
}
// Function to convert timestamp to human-readable format
void format_time(time_t raw_time, char *buffer, size_t size) {
struct tm *time_info = localtime(&raw_time);
strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info);
}
void recursive_glob(const char *pattern, glob_t *results) {
// First, find all matching files in the current scope
glob_t current_matches;
int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, &current_matches);
// Handle errors
if (ret != 0 && ret != GLOB_NOMATCH) {
// Copy error state to results
results->gl_pathc = 0;
results->gl_pathv = NULL;
results->gl_offs = 0;
return;
}
// Initialize results if this is the first call
if (results->gl_pathv == NULL) {
memset(results, 0, sizeof(glob_t));
}
// Add found paths to results
for (size_t i = 0; i < current_matches.gl_pathc; i++) {
char *path = current_matches.gl_pathv[i];
// Add the path to results
if (results->gl_pathc == 0) {
// First result
results->gl_pathc = 1;
results->gl_pathv = malloc(sizeof(char *));
results->gl_pathv[0] = strdup(path);
} else {
// Additional result
results->gl_pathc++;
results->gl_pathv = realloc(results->gl_pathv,
results->gl_pathc * sizeof(char *));
results->gl_pathv[results->gl_pathc - 1] = strdup(path);
}
}
// Now look for directories to recurse into
DIR *dir;
struct dirent *entry;
struct stat statbuf;
// Extract directory part from pattern
char *pattern_copy = strdup(pattern);
char *last_slash = strrchr(pattern_copy, '/');
char *dir_path;
char *file_pattern;
if (last_slash) {
*last_slash = '\0';
dir_path = pattern_copy;
file_pattern = last_slash + 1;
} else {
// No directory part in the pattern
dir_path = ".";
file_pattern = pattern_copy;
}
if ((dir = opendir(dir_path)) != NULL) {
while ((entry = readdir(dir)) != NULL) {
// Skip . and ..
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// Construct full path - ensure sufficient buffer space
char full_path[PATH_MAX];
int path_len;
if (strcmp(dir_path, ".") == 0) {
path_len = snprintf(full_path, PATH_MAX, "%s", entry->d_name);
} else {
path_len = snprintf(full_path, PATH_MAX, "%s/%s", dir_path, entry->d_name);
}
// Check if snprintf truncated the output
if (path_len >= PATH_MAX) {
// Path too long, skip this entry
continue;
}
// Check if it's a directory
if (stat(full_path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
// Create new pattern for recursion - ensure sufficient buffer space
char new_pattern[PATH_MAX];
int new_pattern_len = snprintf(new_pattern, PATH_MAX, "%s/%s", full_path, file_pattern);
// Check if snprintf truncated the output
if (new_pattern_len >= PATH_MAX) {
// Pattern too long, skip this recursion
continue;
}
// Recurse
recursive_glob(new_pattern, results);
}
}
closedir(dir);
}
// Free temporary resources
free(pattern_copy);
globfree(&current_matches);
}
char *tool_function_directory_rglob(char *target_dir) {
fprintf(stderr, "Tools directory_rglob: %s\n", target_dir);
glob_t results;
@ -363,27 +323,21 @@ char *tool_function_directory_rglob(char *target_dir) {
struct stat file_stat;
char mod_time[20], create_time[20];
// Perform glob search recursively
recursive_glob(target_dir, &results);
// Create a JSON array to store results
json_object *json_array = json_object_new_array();
// Iterate through the matched files
for (size_t i = 0; i < results.gl_pathc; i++) {
const char *file_path = results.gl_pathv[i];
// Get file stats
if (stat(file_path, &file_stat) == -1) {
perror("stat failed");
continue;
}
// Format timestamps
format_time(file_stat.st_mtime, mod_time, sizeof(mod_time));
format_time(file_stat.st_ctime, create_time, sizeof(create_time)); // Creation time is unreliable on Linux
format_time(file_stat.st_ctime, create_time, sizeof(create_time));
// Create JSON object for each file
json_object *json_entry = json_object_new_object();
json_object_object_add(json_entry, "name", json_object_new_string(file_path));
json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time));
@ -391,55 +345,45 @@ char *tool_function_directory_rglob(char *target_dir) {
json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat)));
json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size));
// Add to JSON array
json_object_array_add(json_array, json_entry);
}
// Free glob results
globfree(&results);
char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY));
// Cleanup
json_object_put(json_array);
return result;
}
char * tool_function_directory_glob(char *target_dir) {
char *tool_function_directory_glob(char *target_dir) {
fprintf(stderr, "Tools directory_glob: %s\n", target_dir);
glob_t results;
glob_t results;
struct stat file_stat;
char mod_time[20], create_time[20];
if(!strcmp(target_dir, ".")) {
if (!strcmp(target_dir, ".")) {
target_dir[0] = '*';
}
// Perform glob search
if (glob(target_dir, GLOB_TILDE, NULL, &results) != 0) {
perror("glob failed");
return NULL;
}
// Create a JSON array to store results
json_object *json_array = json_object_new_array();
// Iterate through the matched files
for (size_t i = 0; i < results.gl_pathc; i++) {
const char *file_path = results.gl_pathv[i];
// Get file stats
if (stat(file_path, &file_stat) == -1) {
perror("stat failed");
continue;
}
// Format timestamps
format_time(file_stat.st_mtime, mod_time, sizeof(mod_time));
format_time(file_stat.st_ctime, create_time, sizeof(create_time)); // Creation time is unreliable on Linux
format_time(file_stat.st_ctime, create_time, sizeof(create_time));
// Create JSON object for each file
json_object *json_entry = json_object_new_object();
json_object_object_add(json_entry, "name", json_object_new_string(file_path));
json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time));
@ -447,15 +391,12 @@ glob_t results;
json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat)));
json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size));
// Add to JSON array
json_object_array_add(json_array, json_entry);
}
// Free glob results
globfree(&results);
char * result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY));
char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY));
// Cleanup
json_object_put(json_array);
return result;
@ -561,7 +502,6 @@ struct json_object *tool_description_linux_terminal() {
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);
@ -591,7 +531,7 @@ struct json_object *tools_execute(struct json_object *tools_array) {
}
if (!strcmp(function_name, "linux_terminal_execute")) {
struct json_object *arguments_obj;
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;
@ -603,7 +543,7 @@ struct json_object *tools_execute(struct json_object *tools_array) {
}
}
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)) {
struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj));
struct json_object *path_obj;
@ -661,18 +601,18 @@ struct json_object *tools_execute(struct json_object *tools_array) {
}
}
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));
struct json_object *path_obj;
if (json_object_object_get_ex(arguments, "path", &path_obj)) {
char *path = (char *)json_object_get_string(path_obj);
char *listing_result = tool_function_directory_rglob(path);
json_object_object_add(tool_result, "content", json_object_new_string(listing_result));
free(listing_result);
}
}
}
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 *path_obj;
if (json_object_object_get_ex(arguments, "path", &path_obj)) {
char *path = (char *)json_object_get_string(path_obj);
char *listing_result = tool_function_directory_rglob(path);
json_object_object_add(tool_result, "content", json_object_new_string(listing_result));
free(listing_result);
}
}
}
json_object_array_add(tools_result_messages, tool_result);
}

2
url.h
View File

@ -1,6 +1,6 @@
// Written by retoor@molodetz.nl
// This code defines a URL parser in C that extracts components such as scheme, hostname, port, path, and query from a given URL
// This code defines a URL parser in C that extracts components such as the scheme, hostname, port, path, and query from a given URL.
// Includes:
// - <stdio.h> for standard I/O operations