v0.0.56 - Load triggers deterministically from startup events before EOSE
This commit is contained in:
@@ -53,11 +53,11 @@ Skills support context modes (`inject`, `full`, `override`) and per-skill LLM fa
|
||||
|
||||
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.55
|
||||
## Current Status — v0.0.56
|
||||
|
||||
**Active build — this project is barely working. Experiment at your own risk.**
|
||||
|
||||
> Last release update: v0.0.55 — Defer trigger loading until self-skill EOSE and add trigger subscription debug instrumentation
|
||||
> Last release update: v0.0.56 — Load triggers deterministically from startup events before EOSE
|
||||
|
||||
- Connects to configured relays with auto-reconnect and relay state transition logging
|
||||
- Publishes configured startup events per relay as each relay becomes connected
|
||||
|
||||
@@ -271,6 +271,12 @@ int main(int argc, char** argv) {
|
||||
|
||||
DEBUG_INFO("[didactyl] startup phase: deferred trigger load will run after self-skill EOSE");
|
||||
|
||||
DEBUG_INFO("[didactyl] startup phase: startup-config trigger load begin");
|
||||
if (trigger_manager_load_from_startup_events(&trigger_manager) != 0) {
|
||||
DEBUG_WARN("[didactyl] startup phase: startup-config trigger load failed (continuing)");
|
||||
}
|
||||
DEBUG_INFO("[didactyl] startup phase: startup-config trigger load end");
|
||||
|
||||
DEBUG_INFO("[didactyl] startup phase: subscribe admin context begin");
|
||||
if (nostr_handler_subscribe_admin_context() != 0) {
|
||||
DEBUG_WARN("[didactyl] startup phase: subscribe admin context failed (continuing)");
|
||||
|
||||
+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 55
|
||||
#define DIDACTYL_VERSION "v0.0.55"
|
||||
#define DIDACTYL_VERSION_PATCH 56
|
||||
#define DIDACTYL_VERSION "v0.0.56"
|
||||
|
||||
// Agent metadata
|
||||
#define DIDACTYL_NAME "Didactyl"
|
||||
|
||||
@@ -495,6 +495,77 @@ int trigger_manager_load_from_skills(trigger_manager_t* mgr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trigger_manager_load_from_startup_events(trigger_manager_t* mgr) {
|
||||
if (!mgr || !mgr->cfg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int loaded = 0;
|
||||
int considered = 0;
|
||||
|
||||
for (int i = 0; i < mgr->cfg->startup_event_count; i++) {
|
||||
startup_event_t* ev = &mgr->cfg->startup_events[i];
|
||||
if (!ev) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ev->kind != 31123 && ev->kind != 31124) {
|
||||
continue;
|
||||
}
|
||||
|
||||
considered++;
|
||||
|
||||
if (!ev->content || ev->content[0] == '\0' || !ev->tags_json || ev->tags_json[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
cJSON* tags = cJSON_Parse(ev->tags_json);
|
||||
if (!tags || !cJSON_IsArray(tags)) {
|
||||
cJSON_Delete(tags);
|
||||
DEBUG_WARN("[didactyl] startup trigger skip: invalid tags_json for startup event index=%d", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
cJSON* d = find_tag_value_string(tags, "d");
|
||||
cJSON* trigger = find_tag_value_string(tags, "trigger");
|
||||
cJSON* filter = find_tag_value_string(tags, "filter");
|
||||
cJSON* action = find_tag_value_string(tags, "action");
|
||||
cJSON* enabled = find_tag_value_string(tags, "enabled");
|
||||
|
||||
const char* slug = (d && cJSON_IsString(d) && d->valuestring) ? d->valuestring : NULL;
|
||||
const char* trigger_s = (trigger && cJSON_IsString(trigger) && trigger->valuestring) ? trigger->valuestring : NULL;
|
||||
const char* filter_s = (filter && cJSON_IsString(filter) && filter->valuestring) ? filter->valuestring : NULL;
|
||||
const char* action_s = (action && cJSON_IsString(action) && action->valuestring) ? action->valuestring : "llm";
|
||||
const char* enabled_s = (enabled && cJSON_IsString(enabled) && enabled->valuestring) ? enabled->valuestring : "true";
|
||||
|
||||
if (!slug || slug[0] == '\0') {
|
||||
cJSON_Delete(tags);
|
||||
DEBUG_WARN("[didactyl] startup trigger skip: missing d tag for startup event index=%d", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!trigger_s || strcmp(trigger_s, "nostr-subscription") != 0 || !filter_s || filter_s[0] == '\0') {
|
||||
cJSON_Delete(tags);
|
||||
continue;
|
||||
}
|
||||
|
||||
trigger_action_type_t at = (strcmp(action_s, "template") == 0) ? TRIGGER_ACTION_TEMPLATE : TRIGGER_ACTION_LLM;
|
||||
int is_enabled = (strcmp(enabled_s, "false") == 0 || strcmp(enabled_s, "0") == 0) ? 0 : 1;
|
||||
|
||||
if (trigger_manager_add(mgr, slug, ev->content, filter_s, at, is_enabled) == 0) {
|
||||
loaded++;
|
||||
DEBUG_INFO("[didactyl] startup trigger registered slug=%s action=%s enabled=%d", slug, at == TRIGGER_ACTION_TEMPLATE ? "template" : "llm", is_enabled);
|
||||
} else {
|
||||
DEBUG_WARN("[didactyl] startup trigger failed slug=%s", slug);
|
||||
}
|
||||
|
||||
cJSON_Delete(tags);
|
||||
}
|
||||
|
||||
DEBUG_INFO("[didactyl] trigger manager loaded %d trigger(s) from startup config (considered=%d)", loaded, considered);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trigger_manager_add(trigger_manager_t* mgr,
|
||||
const char* skill_slug,
|
||||
const char* content,
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct trigger_manager {
|
||||
|
||||
int trigger_manager_init(trigger_manager_t* mgr, didactyl_config_t* cfg);
|
||||
int trigger_manager_load_from_skills(trigger_manager_t* mgr);
|
||||
int trigger_manager_load_from_startup_events(trigger_manager_t* mgr);
|
||||
int trigger_manager_add(trigger_manager_t* mgr,
|
||||
const char* skill_slug,
|
||||
const char* content,
|
||||
|
||||
Reference in New Issue
Block a user