// retoor <retoor@molodetz.nl>
#include "tool.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
tool_registry_t *tool_registry_create(void) {
tool_registry_t *registry = calloc(1, sizeof(tool_registry_t));
if (!registry) return NULL;
registry->capacity = 32;
registry->tools = calloc(registry->capacity, sizeof(tool_t *));
if (!registry->tools) {
free(registry);
return NULL;
}
return registry;
}
void tool_registry_destroy(tool_registry_t *registry) {
if (!registry) return;
free(registry->tools);
free(registry);
}
r_status_t tool_registry_register(tool_registry_t *registry, tool_t *tool) {
if (!registry || !tool) return R_ERROR_INVALID_ARG;
if (registry->count >= registry->capacity) {
size_t new_capacity = registry->capacity * 2;
tool_t **new_tools = realloc(registry->tools, new_capacity * sizeof(tool_t *));
if (!new_tools) return R_ERROR_OUT_OF_MEMORY;
registry->tools = new_tools;
registry->capacity = new_capacity;
}
registry->tools[registry->count++] = tool;
return R_SUCCESS;
}
tool_t *tool_registry_find(tool_registry_t *registry, const char *name) {
if (!registry || !name) return NULL;
for (size_t i = 0; i < registry->count; i++) {
if (strcmp(registry->tools[i]->name, name) == 0) {
return registry->tools[i];
}
}
return NULL;
}
struct json_object *tool_registry_get_descriptions(tool_registry_t *registry) {
if (!registry) return NULL;
struct json_object *array = json_object_new_array();
if (!array) return NULL;
for (size_t i = 0; i < registry->count; i++) {
tool_t *tool = registry->tools[i];
if (tool->vtable->get_description) {
struct json_object *desc = tool->vtable->get_description();
if (desc) {
json_object_array_add(array, desc);
}
}
}
return array;
}
struct json_object *tool_registry_execute(tool_registry_t *registry,
struct json_object *tool_calls,
bool verbose) {
if (!registry || !tool_calls) return NULL;
struct json_object *results = json_object_new_array();
if (!results) return NULL;
int len = json_object_array_length(tool_calls);
for (int i = 0; i < len; i++) {
struct json_object *call = json_object_array_get_idx(tool_calls, i);
struct json_object *result = json_object_new_object();
struct json_object *id_obj = json_object_object_get(call, "id");
if (id_obj) {
json_object_object_add(result, "tool_call_id",
json_object_new_string(json_object_get_string(id_obj)));
}
json_object_object_add(result, "role", json_object_new_string("tool"));
struct json_object *type_obj;
if (json_object_object_get_ex(call, "type", &type_obj)) {
if (strcmp(json_object_get_string(type_obj), "function") != 0) {
json_object_put(result);
continue;
}
}
struct json_object *function_obj;
if (!json_object_object_get_ex(call, "function", &function_obj)) {
json_object_object_add(result, "content",
json_object_new_string("Error: missing function object"));
json_object_array_add(results, result);
continue;
}
struct json_object *name_obj;
if (!json_object_object_get_ex(function_obj, "name", &name_obj)) {
json_object_object_add(result, "content",
json_object_new_string("Error: missing function name"));
json_object_array_add(results, result);
continue;
}
const char *name = json_object_get_string(name_obj);
tool_t *tool = tool_registry_find(registry, name);
if (!tool) {
fprintf(stderr, "Unknown function: %s\n", name);
json_object_object_add(result, "content",
json_object_new_string("Error: function not found."));
json_object_array_add(results, result);
continue;
}
struct json_object *args = NULL;
struct json_object *args_obj;
if (json_object_object_get_ex(function_obj, "arguments", &args_obj)) {
args = json_tokener_parse(json_object_get_string(args_obj));
}
if (tool->vtable->print_action) {
tool->vtable->print_action(tool->name, args);
}
if (verbose && args) {
fprintf(stderr, " [verbose] %s args: %s\n",
tool->name, json_object_to_json_string(args));
}
char *output = NULL;
if (tool->vtable->execute) {
output = tool->vtable->execute(tool, args);
}
json_object_object_add(result, "content",
json_object_new_string(output ? output : ""));
free(output);
if (args) json_object_put(args);
json_object_array_add(results, result);
}
return results;
}