#define _POSIX_C_SOURCE 200809L #include "tools_internal.h" #include #include #include #include "cjson/cJSON.h" #include "../main.h" #include "../nostr_handler.h" #include "../../nostr_core_lib/nostr_core/nostr_core.h" static char* json_error_local(const char* msg) { cJSON* root = cJSON_CreateObject(); if (!root) return NULL; cJSON_AddBoolToObject(root, "success", 0); cJSON_AddStringToObject(root, "error", msg ? msg : "unknown error"); char* out = cJSON_PrintUnformatted(root); cJSON_Delete(root); return out; } static cJSON* parse_args_local(const char* args_json) { const char* raw = args_json ? args_json : "{}"; cJSON* args = cJSON_Parse(raw); if (!args || !cJSON_IsObject(args)) { cJSON_Delete(args); return NULL; } return args; } char* execute_message_current(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); cJSON* out = cJSON_CreateObject(); if (!out) return NULL; cJSON_AddBoolToObject(out, "success", 1); cJSON_AddStringToObject(out, "content", ctx->template_current_user_message ? ctx->template_current_user_message : ""); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); return json; } char* execute_agent_identity(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); char npub[128] = {0}; if (nostr_key_to_bech32(ctx->cfg->keys.public_key, "npub", npub) != NOSTR_SUCCESS) { strcpy(npub, "unknown"); } cJSON* out = cJSON_CreateObject(); if (!out) return NULL; cJSON_AddBoolToObject(out, "success", 1); char content[384]; snprintf(content, sizeof(content), "## Agent Identity\n\nYour pubkey (hex): %s\nYour npub: %s", ctx->cfg->keys.public_key_hex[0] ? ctx->cfg->keys.public_key_hex : "unknown", npub); cJSON_AddStringToObject(out, "content", content); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); return json; } char* execute_nostr_agent_profile(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); char* kind0 = nostr_handler_get_agent_kind0_context(); const char* profile_json = (kind0 && kind0[0]) ? kind0 : "{}"; cJSON* out = cJSON_CreateObject(); if (!out) { free(kind0); return NULL; } cJSON_AddBoolToObject(out, "success", 1); size_t content_len = strlen("## Agent Kind 0 Profile (source: nostr kind 0)\n\nAgent kind 0 profile content (JSON): ") + strlen(profile_json) + 1U; char* content = (char*)malloc(content_len); if (!content) { cJSON_Delete(out); free(kind0); return NULL; } snprintf(content, content_len, "## Agent Kind 0 Profile (source: nostr kind 0)\n\nAgent kind 0 profile content (JSON): %s", profile_json); cJSON_AddStringToObject(out, "content", content); free(content); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); free(kind0); return json; } char* execute_nostr_agent_contacts(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); char* kind3 = nostr_handler_get_agent_kind3_context(); const char* contacts_json = (kind3 && kind3[0]) ? kind3 : "[]"; cJSON* out = cJSON_CreateObject(); if (!out) { free(kind3); return NULL; } cJSON_AddBoolToObject(out, "success", 1); size_t content_len = strlen("## Agent Kind 3 Contacts (source: nostr kind 3)\n\nAgent contacts (JSON): ") + strlen(contacts_json) + 1U; char* content = (char*)malloc(content_len); if (!content) { cJSON_Delete(out); free(kind3); return NULL; } snprintf(content, content_len, "## Agent Kind 3 Contacts (source: nostr kind 3)\n\nAgent contacts (JSON): %s", contacts_json); cJSON_AddStringToObject(out, "content", content); free(content); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); free(kind3); return json; } char* execute_nostr_agent_relays(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); char* kind10002 = nostr_handler_get_agent_kind10002_context(); const char* relays_json = (kind10002 && kind10002[0]) ? kind10002 : "[]"; cJSON* out = cJSON_CreateObject(); if (!out) { free(kind10002); return NULL; } cJSON_AddBoolToObject(out, "success", 1); size_t content_len = strlen("## Agent Kind 10002 Relays (source: nostr kind 10002)\n\nAgent relay list (JSON): ") + strlen(relays_json) + 1U; char* content = (char*)malloc(content_len); if (!content) { cJSON_Delete(out); free(kind10002); return NULL; } snprintf(content, content_len, "## Agent Kind 10002 Relays (source: nostr kind 10002)\n\nAgent relay list (JSON): %s", relays_json); cJSON_AddStringToObject(out, "content", content); free(content); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); free(kind10002); return json; } char* execute_nostr_agent_notes(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); char* notes = nostr_handler_get_agent_kind1_notes_context(); const char* notes_text = (notes && notes[0]) ? notes : ""; cJSON* out = cJSON_CreateObject(); if (!out) { free(notes); return NULL; } cJSON_AddBoolToObject(out, "success", 1); size_t content_len = strlen("## Agent Recent Kind 1 Notes\n\n") + strlen(notes_text) + 1U; char* content = (char*)malloc(content_len); if (!content) { cJSON_Delete(out); free(notes); return NULL; } snprintf(content, content_len, "## Agent Recent Kind 1 Notes\n\n%s", notes_text); cJSON_AddStringToObject(out, "content", content); free(content); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); free(notes); return json; } char* execute_adopted_skills(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); cJSON* filter = cJSON_CreateObject(); cJSON* kinds = cJSON_CreateArray(); cJSON* authors = cJSON_CreateArray(); if (!filter || !kinds || !authors) { cJSON_Delete(filter); cJSON_Delete(kinds); cJSON_Delete(authors); return NULL; } cJSON_AddItemToArray(kinds, cJSON_CreateNumber(10123)); cJSON_AddItemToObject(filter, "kinds", kinds); cJSON_AddItemToArray(authors, cJSON_CreateString(ctx->cfg->keys.public_key_hex)); cJSON_AddItemToObject(filter, "authors", authors); cJSON_AddNumberToObject(filter, "limit", 1); char* events_json = nostr_handler_query_json(filter, 3000); cJSON_Delete(filter); cJSON* out = cJSON_CreateObject(); if (!out) { free(events_json); return NULL; } cJSON_AddBoolToObject(out, "success", 1); cJSON_AddStringToObject(out, "content", (events_json && events_json[0]) ? events_json : "[]"); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); free(events_json); return json; } char* execute_trigger_event(tools_context_t* ctx, const char* args_json) { if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable"); cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); const char* trigger_json = (ctx->template_trigger_event_json && ctx->template_trigger_event_json[0] != '\0') ? ctx->template_trigger_event_json : NULL; if (!trigger_json) { cJSON* arg_json = cJSON_GetObjectItemCaseSensitive(args, "trigger_event_json"); if (arg_json && cJSON_IsString(arg_json) && arg_json->valuestring && arg_json->valuestring[0] != '\0') { trigger_json = arg_json->valuestring; } } cJSON_Delete(args); if (!trigger_json) { trigger_json = "{}"; } cJSON* out = cJSON_CreateObject(); if (!out) return NULL; cJSON_AddBoolToObject(out, "success", 1); cJSON_AddStringToObject(out, "content", trigger_json); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); return json; } char* execute_agent_version(const char* args_json) { cJSON* args = parse_args_local(args_json); if (!args) return json_error_local("invalid arguments JSON"); cJSON_Delete(args); cJSON* out = cJSON_CreateObject(); if (!out) return NULL; cJSON_AddBoolToObject(out, "success", 1); cJSON_AddStringToObject(out, "name", DIDACTYL_NAME); cJSON_AddStringToObject(out, "description", DIDACTYL_DESCRIPTION); cJSON_AddStringToObject(out, "software", DIDACTYL_SOFTWARE); cJSON_AddStringToObject(out, "version", DIDACTYL_VERSION); cJSON_AddNumberToObject(out, "version_major", DIDACTYL_VERSION_MAJOR); cJSON_AddNumberToObject(out, "version_minor", DIDACTYL_VERSION_MINOR); cJSON_AddNumberToObject(out, "version_patch", DIDACTYL_VERSION_PATCH); char* json = cJSON_PrintUnformatted(out); cJSON_Delete(out); return json; }