From 1c69a581d9d2f0b05b58dba51d64ed09263fd5ae Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Feb 2026 08:27:29 -0400 Subject: [PATCH] v0.0.6 - Remove top-level agent config, move SYSTEM prompt into Soul startup event, and update Quick Start binary flow --- README.md | 30 +++++++++++--------- SYSTEM.md | 24 ---------------- src/config.c | 20 +------------ src/config.h | 9 ------ src/main.h | 4 +-- src/nostr_handler.c | 68 --------------------------------------------- src/nostr_handler.h | 1 - 7 files changed, 20 insertions(+), 136 deletions(-) delete mode 100644 SYSTEM.md diff --git a/README.md b/README.md index 63ea646..0d5e827 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,25 @@ Because all identity, communication, and memory live on Nostr, the agent is **po ## Quick Start -### Prerequisites +### Download binary (recommended) + +1. Download the latest release binary from GitLab: +2. Make it executable and run it: + +```bash +chmod +x ./didactyl_static_x86_64 +./didactyl_static_x86_64 --config ./config.json +``` + +### Build from source (optional) + +#### Prerequisites - Docker (for static binary build) - An OpenAI-compatible LLM API key (OpenAI, PPQ, Ollama, etc.) - A Nostr keypair (nsec) -### Build +#### Build ```bash ./build_static.sh # builds a fully static MUSL binary via Docker @@ -44,14 +56,6 @@ Edit [`config.json`](config.json): ```json { - "agent": { - "name": "Didactyl Agent", - "display_name": "Didactyl", - "about": "A sovereign AI agent on Nostr", - "picture": "https://...", - "banner": "https://...", - "nip05": "" - }, "keys": { "nsec": "nsec1...", "npub": "npub1...", @@ -108,13 +112,13 @@ Edit [`config.json`](config.json): ### Run ```bash -./didactyl +./didactyl_static_x86_64 --config ./config.json ``` Options: ``` -./didactyl --config # custom config file (default: ./config.json) -./didactyl --debug <0-5> # log verbosity (0 none, 3 info, 5 trace) +./didactyl_static_x86_64 --config # custom config file (default: ./config.json) +./didactyl_static_x86_64 --debug <0-5> # log verbosity (0 none, 3 info, 5 trace) ``` ### Talk to it diff --git a/SYSTEM.md b/SYSTEM.md deleted file mode 100644 index e9d887d..0000000 --- a/SYSTEM.md +++ /dev/null @@ -1,24 +0,0 @@ -# Didactyl Agent - -You are Didactyl, a sovereign AI agent living on Nostr. - -## Communication Rules -- You communicate through encrypted Nostr direct messages. -- Keep responses concise and clear. - -## Behavior -- Be helpful and technically accurate. -- If unsure, state uncertainty directly. -- Prefer actionable, practical advice. - -## Tool Use Policy -- You have tools available and should use them when a request requires taking action. -- For requests involving local inspection or command execution, call `shell_exec` instead of refusing. -- For posting to Nostr, call `nostr_post` with explicit `kind` and `content`. -- For relay/event lookup tasks, call `nostr_query` with an appropriate filter. -- After a tool call, base your answer on the actual tool result. -- Never claim a tool was run if no tool was executed. - -## Safety -- Do not claim to have executed actions you did not execute. -- Do not reveal secrets from configuration or keys. diff --git a/src/config.c b/src/config.c index 169f4af..cf98520 100644 --- a/src/config.c +++ b/src/config.c @@ -417,34 +417,16 @@ int config_load(const char* path, didactyl_config_t* config) { int rc = -1; - cJSON* agent = cJSON_GetObjectItemCaseSensitive(root, "agent"); cJSON* keys = cJSON_GetObjectItemCaseSensitive(root, "keys"); cJSON* admin = cJSON_GetObjectItemCaseSensitive(root, "admin"); cJSON* llm = cJSON_GetObjectItemCaseSensitive(root, "llm"); - if (!agent || !cJSON_IsObject(agent) || - !keys || !cJSON_IsObject(keys) || + if (!keys || !cJSON_IsObject(keys) || !admin || !cJSON_IsObject(admin) || !llm || !cJSON_IsObject(llm)) { goto cleanup; } - if (copy_json_string(agent, "name", config->profile.name, sizeof(config->profile.name), 1) != 0) { - goto cleanup; - } - if (copy_json_string(agent, "display_name", config->profile.display_name, sizeof(config->profile.display_name), 1) != 0) { - goto cleanup; - } - if (copy_json_string(agent, "about", config->profile.about, sizeof(config->profile.about), 1) != 0) { - goto cleanup; - } - if (copy_json_string(agent, "picture", config->profile.picture, sizeof(config->profile.picture), 0) != 0) { - goto cleanup; - } - if (copy_json_string(agent, "nip05", config->profile.nip05, sizeof(config->profile.nip05), 0) != 0) { - goto cleanup; - } - if (copy_json_string(keys, "nsec", config->keys.nsec, sizeof(config->keys.nsec), 1) != 0) { goto cleanup; } diff --git a/src/config.h b/src/config.h index f0a5449..1466db7 100644 --- a/src/config.h +++ b/src/config.h @@ -9,14 +9,6 @@ #define OW_MAX_KEY_LEN 256 #define OW_MAX_MODEL_LEN 128 -typedef struct { - char name[OW_MAX_NAME_LEN]; - char display_name[OW_MAX_NAME_LEN]; - char about[OW_MAX_ABOUT_LEN]; - char picture[OW_MAX_URL_LEN]; - char nip05[OW_MAX_URL_LEN]; -} agent_profile_t; - typedef struct { char nsec[OW_MAX_KEY_LEN]; unsigned char private_key[32]; @@ -57,7 +49,6 @@ typedef struct { } startup_event_t; typedef struct { - agent_profile_t profile; agent_keys_t keys; admin_config_t admin; char** relays; diff --git a/src/main.h b/src/main.h index 235f8c5..d57ade4 100644 --- a/src/main.h +++ b/src/main.h @@ -12,8 +12,8 @@ // Using DIDACTYL_ prefix to avoid conflicts with nostr_core_lib VERSION macros #define DIDACTYL_VERSION_MAJOR 0 #define DIDACTYL_VERSION_MINOR 0 -#define DIDACTYL_VERSION_PATCH 5 -#define DIDACTYL_VERSION "v0.0.5" +#define DIDACTYL_VERSION_PATCH 6 +#define DIDACTYL_VERSION "v0.0.6" // Agent metadata #define DIDACTYL_NAME "Didactyl" diff --git a/src/nostr_handler.c b/src/nostr_handler.c index 1535348..9e5e948 100644 --- a/src/nostr_handler.c +++ b/src/nostr_handler.c @@ -390,74 +390,6 @@ int nostr_handler_init(didactyl_config_t* config) { return 0; } -int nostr_handler_publish_profile(void) { - if (!g_cfg || !g_pool) { - return -1; - } - - DEBUG_INFO("[didactyl] publish_profile: build metadata payload"); - cJSON* profile = cJSON_CreateObject(); - if (!profile) { - return -1; - } - - cJSON_AddStringToObject(profile, "name", g_cfg->profile.name); - cJSON_AddStringToObject(profile, "display_name", g_cfg->profile.display_name); - cJSON_AddStringToObject(profile, "about", g_cfg->profile.about); - cJSON_AddStringToObject(profile, "picture", g_cfg->profile.picture); - if (g_cfg->profile.nip05[0] != '\0') { - cJSON_AddStringToObject(profile, "nip05", g_cfg->profile.nip05); - } - - char* content = cJSON_PrintUnformatted(profile); - cJSON_Delete(profile); - if (!content) { - return -1; - } - - DEBUG_INFO("[didactyl] publish_profile: sign kind-0 event"); - cJSON* event = nostr_create_and_sign_event(0, content, NULL, g_cfg->keys.private_key, time(NULL)); - free(content); - - if (!event) { - return -1; - } - - const char** connected_relays = (const char**)calloc((size_t)g_cfg->relay_count, sizeof(char*)); - if (!connected_relays) { - cJSON_Delete(event); - return -1; - } - - int connected_count = 0; - for (int i = 0; i < g_cfg->relay_count; i++) { - if (nostr_relay_pool_get_relay_status(g_pool, g_cfg->relays[i]) == NOSTR_POOL_RELAY_CONNECTED) { - connected_relays[connected_count++] = g_cfg->relays[i]; - } - } - - if (connected_count == 0) { - DEBUG_WARN("[didactyl] publish_profile: no connected relays yet, deferring publish"); - free(connected_relays); - cJSON_Delete(event); - return 0; - } - - DEBUG_INFO("[didactyl] publish_profile: publishing to %d connected relay(s)", connected_count); - int sent = nostr_relay_pool_publish_async( - g_pool, - connected_relays, - connected_count, - event, - NULL, - NULL); - - free(connected_relays); - cJSON_Delete(event); - DEBUG_INFO("[didactyl] publish profile result: sent_to=%d connected relay(s)", sent); - return sent > 0 ? 0 : -1; -} - int nostr_handler_subscribe_dms(dm_callback_t callback, void* user_data) { if (!g_cfg || !g_pool || !callback) { return -1; diff --git a/src/nostr_handler.h b/src/nostr_handler.h index e6db733..3e8f908 100644 --- a/src/nostr_handler.h +++ b/src/nostr_handler.h @@ -7,7 +7,6 @@ typedef void (*dm_callback_t)(const char* sender_pubkey_hex, const char* message, void* user_data); int nostr_handler_init(didactyl_config_t* config); -int nostr_handler_publish_profile(void); int nostr_handler_subscribe_dms(dm_callback_t callback, void* user_data); int nostr_handler_send_dm(const char* recipient_pubkey_hex, const char* message); int nostr_handler_publish_kind_event(int kind, const char* content, cJSON* tags);