v0.0.85 - Skip llm_config republish on startup when config was recalled from Nostr
This commit is contained in:
@@ -55,11 +55,11 @@ Skills compose by adoption-list order (`10123`) and trigger tags carry runtime e
|
||||
|
||||
Didactyl will support local inference, which is very privacy preserving. Remote inference does however have it's advantages, and in those cases Didactyl supports using Bitcoin Lightning and eCash inference providers.
|
||||
|
||||
## Current Status — v0.0.84
|
||||
## Current Status — v0.0.85
|
||||
|
||||
**Active build — this project is barely working. Experiment at your own risk.**
|
||||
|
||||
> Last release update: v0.0.84 — Remove duplicated read-only tool payload fields and make slash output prefer content
|
||||
> Last release update: v0.0.85 — Skip llm_config republish on startup when config was recalled from Nostr
|
||||
|
||||
- Connects to configured relays with auto-reconnect and relay state transition logging
|
||||
- Publishes configured startup events per relay as each relay becomes connected
|
||||
|
||||
+29
-19
@@ -813,24 +813,29 @@ static int publish_encrypted_self_config(const didactyl_config_t* cfg, const cha
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int persist_runtime_config_to_nostr(const didactyl_config_t* cfg) {
|
||||
static int persist_runtime_config_to_nostr(const didactyl_config_t* cfg, int persist_llm_config) {
|
||||
if (!cfg) return -1;
|
||||
|
||||
cJSON* llm = cJSON_CreateObject();
|
||||
if (!llm) return -1;
|
||||
cJSON_AddStringToObject(llm, "provider", cfg->llm.provider);
|
||||
cJSON_AddStringToObject(llm, "api_key", cfg->llm.api_key);
|
||||
cJSON_AddStringToObject(llm, "model", cfg->llm.model);
|
||||
cJSON_AddStringToObject(llm, "base_url", cfg->llm.base_url);
|
||||
cJSON_AddNumberToObject(llm, "max_tokens", cfg->llm.max_tokens);
|
||||
cJSON_AddNumberToObject(llm, "temperature", cfg->llm.temperature);
|
||||
int llm_rc = 0;
|
||||
if (persist_llm_config) {
|
||||
cJSON* llm = cJSON_CreateObject();
|
||||
if (!llm) return -1;
|
||||
cJSON_AddStringToObject(llm, "provider", cfg->llm.provider);
|
||||
cJSON_AddStringToObject(llm, "api_key", cfg->llm.api_key);
|
||||
cJSON_AddStringToObject(llm, "model", cfg->llm.model);
|
||||
cJSON_AddStringToObject(llm, "base_url", cfg->llm.base_url);
|
||||
cJSON_AddNumberToObject(llm, "max_tokens", cfg->llm.max_tokens);
|
||||
cJSON_AddNumberToObject(llm, "temperature", cfg->llm.temperature);
|
||||
|
||||
char* llm_json = cJSON_PrintUnformatted(llm);
|
||||
cJSON_Delete(llm);
|
||||
if (!llm_json) return -1;
|
||||
char* llm_json = cJSON_PrintUnformatted(llm);
|
||||
cJSON_Delete(llm);
|
||||
if (!llm_json) return -1;
|
||||
|
||||
int llm_rc = publish_encrypted_self_config(cfg, "llm_config", llm_json);
|
||||
free(llm_json);
|
||||
llm_rc = publish_encrypted_self_config(cfg, "llm_config", llm_json);
|
||||
free(llm_json);
|
||||
} else {
|
||||
DEBUG_INFO("[didactyl] startup phase: skipping llm_config publish because it was recalled from Nostr");
|
||||
}
|
||||
|
||||
cJSON* agent = cJSON_CreateObject();
|
||||
if (!agent) return llm_rc;
|
||||
@@ -846,15 +851,18 @@ static int persist_runtime_config_to_nostr(const didactyl_config_t* cfg) {
|
||||
return (llm_rc == 0 && agent_rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void recover_missing_runtime_config_from_nostr(didactyl_config_t* cfg) {
|
||||
static int recover_missing_runtime_config_from_nostr(didactyl_config_t* cfg) {
|
||||
if (!cfg) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llm_recalled_from_nostr = 0;
|
||||
|
||||
if (!llm_config_is_complete(&cfg->llm)) {
|
||||
char* llm_plaintext = NULL;
|
||||
if (fetch_self_config_plaintext(cfg, "llm_config", &llm_plaintext) == 0 && llm_plaintext) {
|
||||
if (apply_recalled_llm_config(cfg, llm_plaintext) == 0) {
|
||||
llm_recalled_from_nostr = 1;
|
||||
DEBUG_INFO("[didactyl] startup phase: recovered llm_config from Nostr");
|
||||
} else {
|
||||
DEBUG_WARN("[didactyl] startup phase: failed to apply recalled llm_config");
|
||||
@@ -885,6 +893,8 @@ static void recover_missing_runtime_config_from_nostr(didactyl_config_t* cfg) {
|
||||
DEBUG_WARN("[didactyl] startup phase: agent_config recall unavailable");
|
||||
}
|
||||
free(agent_plaintext);
|
||||
|
||||
return llm_recalled_from_nostr;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
@@ -1129,8 +1139,8 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
startup_step_begin(2, "Recover runtime config from Nostr");
|
||||
recover_missing_runtime_config_from_nostr(&cfg);
|
||||
startup_step_ok(2, "Recover runtime config from Nostr", NULL);
|
||||
int llm_recalled_from_nostr = recover_missing_runtime_config_from_nostr(&cfg);
|
||||
startup_step_ok(2, "Recover runtime config from Nostr", llm_recalled_from_nostr ? "llm_config recalled" : NULL);
|
||||
|
||||
startup_step_begin(3, "Validate LLM config");
|
||||
if (!llm_config_is_complete(&cfg.llm)) {
|
||||
@@ -1184,7 +1194,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (persist_runtime_config_to_nostr(&cfg) != 0) {
|
||||
if (persist_runtime_config_to_nostr(&cfg, llm_recalled_from_nostr ? 0 : 1) != 0) {
|
||||
DEBUG_WARN("[didactyl] startup phase: failed to persist encrypted runtime config to Nostr");
|
||||
} else {
|
||||
DEBUG_INFO("[didactyl] startup phase: persisted encrypted runtime config to Nostr");
|
||||
|
||||
+2
-2
@@ -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 84
|
||||
#define DIDACTYL_VERSION "v0.0.84"
|
||||
#define DIDACTYL_VERSION_PATCH 85
|
||||
#define DIDACTYL_VERSION "v0.0.85"
|
||||
|
||||
// Agent metadata
|
||||
#define DIDACTYL_NAME "Didactyl"
|
||||
|
||||
@@ -108,6 +108,25 @@ static int assign_string_field(cJSON* item, char* dst, size_t dst_size, int* cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mask_api_key_local(const char* api_key, char* out, size_t out_size) {
|
||||
if (!out || out_size == 0) return;
|
||||
out[0] = '\0';
|
||||
if (!api_key || api_key[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t api_len = strlen(api_key);
|
||||
if (api_len >= 8U) {
|
||||
snprintf(out,
|
||||
out_size,
|
||||
"%.4s...%s",
|
||||
api_key,
|
||||
api_key + api_len - 4U);
|
||||
} else {
|
||||
snprintf(out, out_size, "%s", "(set)");
|
||||
}
|
||||
}
|
||||
|
||||
char* execute_model_get(const char* args_json) {
|
||||
cJSON* args = parse_args_local(args_json);
|
||||
if (!args) return json_error_local("invalid arguments JSON");
|
||||
@@ -120,10 +139,15 @@ char* execute_model_get(const char* args_json) {
|
||||
|
||||
cJSON* out = cJSON_CreateObject();
|
||||
if (!out) return NULL;
|
||||
|
||||
char api_key_masked[64] = {0};
|
||||
mask_api_key_local(cfg.api_key, api_key_masked, sizeof(api_key_masked));
|
||||
|
||||
cJSON_AddBoolToObject(out, "success", 1);
|
||||
cJSON_AddStringToObject(out, "provider", cfg.provider);
|
||||
cJSON_AddStringToObject(out, "model", cfg.model);
|
||||
cJSON_AddStringToObject(out, "base_url", cfg.base_url);
|
||||
cJSON_AddStringToObject(out, "api_key_masked", api_key_masked);
|
||||
cJSON_AddNumberToObject(out, "max_tokens", cfg.max_tokens);
|
||||
cJSON_AddNumberToObject(out, "temperature", cfg.temperature);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user