v0.0.59 - Use tool-capable multi-turn execution for triggered skills

This commit is contained in:
Your Name
2026-03-09 18:31:15 -04:00
parent 53a181cec0
commit 3eddc032c1
3 changed files with 92 additions and 15 deletions
+2 -2
View File
@@ -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.58
## Current Status — v0.0.59
**Active build — this project is barely working. Experiment at your own risk.**
> Last release update: v0.0.58Disable pool dedup on trigger subscriptions to restore kind-1 firing
> Last release update: v0.0.59Use tool-capable multi-turn execution for triggered skills
- Connects to configured relays with auto-reconnect and relay state transition logging
- Publishes configured startup events per relay as each relay becomes connected
+88 -11
View File
@@ -1962,20 +1962,97 @@ void agent_on_trigger(const char* skill_slug,
snprintf(user_prompt, user_len, "Triggering event JSON:\n%s", event_json);
free(event_json);
append_context_log(g_cfg->admin.pubkey, "llm_trigger", user_prompt);
char* response = llm_chat(system_prompt, user_prompt);
free(system_prompt);
free(user_prompt);
if (!response) {
const char* fallback = "Triggered skill execution failed: LLM unavailable.";
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, fallback);
char* tools_json = tools_build_openai_schema_json(&g_tools_ctx);
if (!tools_json) {
free(system_prompt);
free(user_prompt);
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: tools unavailable.");
return;
}
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, response);
free(response);
cJSON* messages = cJSON_CreateArray();
if (!messages || !cJSON_IsArray(messages) ||
append_simple_message(messages, "system", system_prompt) != 0 ||
append_simple_message(messages, "user", user_prompt) != 0) {
cJSON_Delete(messages);
free(tools_json);
free(system_prompt);
free(user_prompt);
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: prompt initialization failed.");
return;
}
append_context_log(g_cfg->admin.pubkey, "llm_trigger", user_prompt);
free(system_prompt);
free(user_prompt);
int max_turns = g_cfg->tools.max_turns > 0 ? g_cfg->tools.max_turns : 6;
char* final_answer_owned = NULL;
for (int turn = 0; turn < max_turns; turn++) {
char* messages_json = cJSON_PrintUnformatted(messages);
if (!messages_json) {
break;
}
append_context_log(g_cfg->admin.pubkey, "llm_trigger_with_tools_messages", messages_json);
llm_response_t resp;
int rc = llm_chat_with_tools_messages(messages_json, tools_json, "auto", &resp);
free(messages_json);
if (rc != 0) {
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: LLM request failed.");
cJSON_Delete(messages);
free(tools_json);
return;
}
if (resp.tool_call_count <= 0) {
const char* answer = resp.content ? resp.content : "No response content.";
final_answer_owned = strdup(answer);
llm_response_free(&resp);
break;
}
if (append_assistant_tool_calls_message(messages, &resp) != 0) {
llm_response_free(&resp);
break;
}
for (int i = 0; i < resp.tool_call_count; i++) {
llm_tool_call_t* tc = &resp.tool_calls[i];
char* tool_result = tools_execute(&g_tools_ctx, tc->name, tc->arguments_json);
if (!tool_result) {
tool_result = strdup("{\"success\":false,\"error\":\"tool execution failed\"}");
}
if (append_tool_result_message(messages,
tc->id ? tc->id : "",
tool_result ? tool_result : "{\"success\":false,\"error\":\"tool execution failed\"}") != 0) {
free(tool_result);
llm_response_free(&resp);
cJSON_Delete(messages);
free(tools_json);
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: tool result append failed.");
return;
}
free(tool_result);
}
llm_response_free(&resp);
}
if (!final_answer_owned) {
final_answer_owned = strdup("I hit my tool-use limit for this trigger.");
}
const char* final_answer = final_answer_owned ? final_answer_owned : "I hit my tool-use limit for this trigger.";
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, final_answer);
free(final_answer_owned);
cJSON_Delete(messages);
free(tools_json);
}
int agent_build_admin_messages_json(const char* current_user_message,
+2 -2
View File
@@ -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 58
#define DIDACTYL_VERSION "v0.0.58"
#define DIDACTYL_VERSION_PATCH 59
#define DIDACTYL_VERSION "v0.0.59"
// Agent metadata
#define DIDACTYL_NAME "Didactyl"