v0.2.49 - Add startup-failure DM de-dup with marker, relay-state/needed-event diagnostics, and clear-on-READY rearm

This commit is contained in:
Didactyl User
2026-06-13 06:56:04 -04:00
parent 37e51f88a8
commit b8afa40c35
30 changed files with 3545 additions and 4 deletions
+2 -2
View File
@@ -54,11 +54,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.2.48
## Current Status — v0.2.49
**Active build — this project is barely working. Experiment at your own risk.**
> Last release update: v0.2.48Remove admin kind 10123 from subscription and upsert, add debug logging
> Last release update: v0.2.49Add startup-failure DM de-dup with marker, relay-state/needed-event diagnostics, and clear-on-READY rearm
- Connects to configured relays with auto-reconnect and relay state transition logging
- Publishes configured startup events per relay as each relay becomes connected
+58
View File
@@ -0,0 +1,58 @@
# Remove Dead DM-History Helper Functions in `agent.c`
## Background
While investigating how Didactyl maintains continuity across a DM "chat session", two functions in [`src/agent.c`](../src/agent.c) were found to be compiled-but-unreferenced, marked with `__attribute__((unused))` to suppress compiler warnings:
- [`append_recent_admin_dm_history`](../src/agent.c:1065)
- [`build_recent_admin_dm_history_messages`](../src/agent.c:1800) (wraps the above)
These were part of an older design where the agent automatically injected the last N admin DM turns into every LLM call. The current architecture is **skill-driven**: DM history only reaches the LLM when an adopted, triggered skill explicitly pulls it in via the `{{dm_history}}` / `{{nostr_dm_history(...)}}` template variables or the `nostr_dm_history` tool (see [`tool_agent.c`](../src/tools/tool_agent.c:284) and [`tools_schema.c`](../src/tools/tools_schema.c:1606)). The dead functions are now a source of confusion for anyone reading the code to understand chat-session behavior.
## Goal
Remove the dead functions and any symbols used exclusively by them, without changing runtime behavior.
## Scope Analysis (verified before planning)
A repo-wide search for each symbol confirmed the following:
| Symbol | Only callers | Disposition |
|---|---|---|
| [`append_recent_admin_dm_history`](../src/agent.c:1065) | called by `build_recent_admin_dm_history_messages` (also dead) | **delete** |
| [`build_recent_admin_dm_history_messages`](../src/agent.c:1800) | no callers | **delete** |
| [`AGENT_HISTORY_TURNS`](../src/agent.c:38) | referenced only inside the dead `append_recent_admin_dm_history` | **delete** |
| [`AGENT_HISTORY_QUERY_LIMIT`](../src/agent.c:39) | defined but zero references repo-wide | **delete** |
| [`append_simple_message`](../src/agent.c:187) | many live callers throughout `agent.c` | **keep** |
| [`nostr_handler_get_dm_history_json`](../src/nostr_handler.c:4384) | live via [`tool_agent.c`](../src/tools/tool_agent.c:318) | **keep** |
No non-source references (Makefile, tests, docs) depend on these symbols.
## Risks
Very low. Both functions carry `__attribute__((unused))` so they are not linked into any runtime path. The only failure modes are accidental deletion of something still live, which the scope analysis above rules out.
## Verification Strategy
1. Clean build with `make` — must succeed with no new warnings.
2. Existing tests under [`tests/`](../tests/) pass (`python tests/run_tests.py` or the project's usual invocation).
3. Manual sanity check: start an agent, send a DM, confirm normal reply — no regression, since the deleted code was never on the hot path.
## Mermaid: before/after
```mermaid
flowchart LR
subgraph Before
A1[agent.c dead funcs] -. unused attr .- B1[compiler silences warning]
A1 --> C1[reader assumes auto DM history replay]
C1 --> D1[confusion about session behavior]
end
subgraph After
A2[agent.c clean] --> E2[skill-driven history only]
E2 --> F2[intent matches code]
end
```
## Follow-on (out of scope for this change)
The documentation in [`docs/CONTEXT.md`](../docs/CONTEXT.md) already describes the skill-driven assembly model correctly, but neither that file nor [`docs/SKILLS.md`](../docs/SKILLS.md) explicitly states "DM history is not automatic — it only appears when a skill references it." A brief clarifying paragraph could be added in a separate change.
+285
View File
@@ -0,0 +1,285 @@
# Startup Failure Admin DM Notification
> **STATUS UPDATE (follow-up phase):** The base feature (send a failure DM) is
> implemented and verified on VM410. However, because the failure happens inside the
> systemd `Restart=on-failure` loop (`RestartSec=10`), the admin now receives a *new*
> failure DM roughly every ~25 seconds, indefinitely (observed in the live message box).
> This follow-up adds **throttling/de-duplication** so the failure DM is sent **once per
> failure type until the next successful startup**, and makes the message **more
> descriptive** (per-relay connect state + the event kinds that were needed).
> See the "Follow-up: Throttling + Descriptive Failure DM" section at the end.
# Startup Failure Admin DM Notification (original plan)
## Goal
When the agent fails to start, send a best-effort encrypted DM to the administrator
describing which startup step failed and why, so the operator learns about the failure
without having to SSH in and read `journalctl`.
This directly addresses the real-world incident on VM410 where both `didactyl.service`
and `simon.service` were stuck restart-looping at startup step 14
(`Subscribe self-skill cache: failed (no skill events found after EOSE)`) and silently
stopped answering DMs.
## Background / Code References
- Startup is a linear checklist in [`main()`](src/main.c:1012). Each step uses helpers:
- [`startup_step_begin()`](src/main.c:303)
- [`startup_step_ok()`](src/main.c:309)
- [`startup_step_fail()`](src/main.c:320)
- On any fatal failure, the current pattern is:
`startup_step_fail(...)` -> `fprintf(stderr, ...)` -> cleanup calls -> `return 1;`
(e.g. the step-14 self-skill abort at [`src/main.c:1520`](src/main.c:1520)).
- The success path already sends an admin "started up" DM at
[`src/main.c:1663`](src/main.c:1663) via
[`nostr_handler_send_dm_auto()`](src/nostr_handler.c:3264).
- DM delivery requires (see [`nostr_handler_send_dm_with_role()`](src/nostr_handler.c:3133)):
- `g_cfg` and `g_pool` set (relay pool initialized),
- at least one **connected** relay (otherwise the kind-4 event is dropped:
"kind 4 event not queued: no connected relays" at [`src/nostr_handler.c:3203`](src/nostr_handler.c:3203)),
- a valid `cfg.admin.pubkey` (validated at step 4, [`src/main.c:1310`](src/main.c:1310)),
- the private key derived (always done before the checklist).
### Delivery-window reality
A failure DM is only *deliverable* from roughly step 11 onward (relay pool created +
relays connected + admin known). The step-14 failure we actually hit is inside that
window, so it will be delivered. Earlier failures (bad nsec, missing admin, LLM config,
no relay connection) have no working channel; per decision, those are **logged only**
(best-effort, no blocking retries).
## Design Decision (confirmed)
**Best-effort only.** Attempt the failure DM whenever relays + admin are available; if
the relay pool isn't connected or admin pubkey is unknown, skip the DM and rely on
existing stderr/journal logging. No blocking retry loop, no self-healing of the
underlying failure (that can be a separate plan).
## Approach
Add a single helper that builds and sends the failure DM, then call it from every fatal
startup-abort site (the points that currently do `startup_step_fail(...) ... return 1;`).
### 1. New helper in [`src/main.c`](src/main.c)
Add a static function near the other startup helpers (after
[`startup_step_fail()`](src/main.c:320)):
```c
static void notify_admin_startup_failure(const didactyl_config_t* cfg,
int step,
const char* label,
const char* detail);
```
Behavior:
- Guard clauses (skip + DEBUG_WARN if any precondition is missing):
- `cfg == NULL` or `cfg->admin.pubkey[0] == '\0'` -> log "admin unknown; cannot notify".
- `nostr_handler_connected_relay_count() <= 0` -> log "no connected relay; cannot notify".
- Build a concise human-readable message, e.g.:
```
<DisplayName> FAILED to start at <YYYY-MM-DD HH:MM:SS>.
Startup step [14] Subscribe self-skill cache failed: no skill events found after EOSE.
Version <X>. Connected relays: <n>/<m>. The agent is NOT online and will not answer DMs until fixed.
```
- Reuse `nostr_handler_get_startup_display_name()` and `DIDACTYL_VERSION` exactly like
the success DM at [`src/main.c:1645`](src/main.c:1645) for naming/version consistency.
- Include `step`, `label`, and `detail` so each failure site is self-describing.
- Send via `nostr_handler_send_dm_auto(cfg->admin.pubkey, msg)`; if it returns non-zero,
`DEBUG_WARN` that the failure DM could not be delivered (do not change the exit code).
- Pump the poll loop briefly after sending so the async publish can flush before process
exit: call `nostr_handler_poll(...)` a few times (e.g. ~300--500 ms total) so the
queued kind-4 event is actually written to the relay sockets before cleanup/`return 1`.
(Without this, async publish may be discarded on immediate exit.)
### 2. Wire the helper into fatal abort sites
For each fatal `startup_step_fail(...)` that ends in `return 1;`, insert a call to
`notify_admin_startup_failure(&cfg, <step>, "<label>", "<detail>")` immediately after the
`startup_step_fail(...)` line and before the cleanup/`return 1`.
Priority sites (inside the deliverable window — relay pool up + admin known):
- Step 11 — discover self relay list failures
([`src/main.c:1420`](src/main.c:1420), [`src/main.c:1437`](src/main.c:1437)).
- Step 14 — self-skill cache failures (the incident we hit):
- subscribe failed ([`src/main.c:1481`](src/main.c:1481)),
- EOSE timeout ([`src/main.c:1496`](src/main.c:1496)),
- no skill events after EOSE ([`src/main.c:1521`](src/main.c:1521)).
- Step 15 — Subscribe DMs failed ([`src/main.c:1552`](src/main.c:1552)).
Earlier-window sites (relay/admin may not be ready — helper will self-skip and just log,
but we still call it uniformly for completeness):
- Step 1/3/4/5/6/7/8/9 fatal aborts. The helper's guard clauses make these safe no-ops
when delivery isn't possible.
Keep the existing `fprintf(stderr, ...)` and cleanup unchanged; the DM is purely additive
and must never alter the exit code or cleanup ordering.
### 3. Message size / safety
- Use a fixed stack buffer (e.g. `char msg[768];`) like the success DM at
[`src/main.c:1644`](src/main.c:1644).
- `snprintf` with truncation is acceptable; `detail` strings are short and controlled.
## Out of Scope
- No blocking retry / wait-for-relay loop (explicitly declined).
- No auto-remediation of the step-14 self-skill cause (e.g. auto-publishing the default
skill). Tracked separately if desired.
- No change to `deploy_lt.sh` post-deploy health checks (could be a follow-up: have the
deploy script verify each service reaches `READY` after restart).
## Verification
1. Build the static binary (`build_static.sh`) and confirm no warnings.
2. Local reproduction of step-14 failure: run an `--nsec`-only agent for an identity that
has connected relays but **no** published skill events, confirm:
- startup still aborts with exit code 1 (unchanged behavior),
- the admin receives a DM naming step 14 and the "no skill events found after EOSE"
detail.
3. Negative case: kill relay connectivity (or use an unreachable relay) and confirm the
helper logs "no connected relay; cannot notify" and does not crash or hang.
4. Confirm the success-path startup DM at [`src/main.c:1663`](src/main.c:1663) is
unaffected.
5. Deploy to VM410, restart `didactyl.service` / `simon.service`, and confirm the admin
npub receives the failure DM while the skill events are still missing; then publish a
skill and confirm normal `READY` + startup DM resumes.
---
# Follow-up: Throttling + Descriptive Failure DM
## Problems observed in production
1. **DM flood.** With `Restart=on-failure` / `RestartSec=10`, the step-14 failure recurs
on every restart and the agent reaches the deliverable window each time, so the admin
gets a fresh failure DM every ~25s indefinitely (confirmed in the live message box).
2. **Insufficient detail.** The current message names the step + detail, but not which
relays were attempted, whether each connected, nor which event kinds were required.
## Decisions (confirmed with user)
- **Throttle semantics:** send exactly once per failure type (keyed by step) until the
agent next starts successfully. The marker is cleared on `READY`. No periodic
reminders. A different failing step is a different "type" and notifies once.
- **Descriptive content:** include the attempted relay list with per-relay connect state,
and the event kinds that step 14 needs (31123 / 31124 skill events; 10123 adoption list).
## Part A -- Throttle / de-duplicate via on-disk marker
### Marker file location (systemd-sandbox safe)
- The unit runs with `WorkingDirectory=/home/<user>` and (hardened variant)
`ReadWritePaths=/home/<user>`, so only the agent home is writable.
- `cfg.tools.shell.working_directory` defaults to `"."` (see
[`config.c`](src/config.c:1459)), which resolves to the home dir at runtime.
- Use a hidden marker in the working directory: `./.didactyl_startup_failure`.
- For `didactyl` -> `/home/didactyl/.didactyl_startup_failure`
- For `simon` -> `/home/simon/.didactyl_startup_failure`
- Both inside the writable `ReadWritePaths`, so writes succeed under the sandbox.
- Resolve the directory the same way the local-file tools do: prefer
`cfg->tools.shell.working_directory` when non-empty, else `"."`
(mirror [`tool_local.c`](src/tools/tool_local.c:49)).
### Marker contents
Plain text, one record, easy to parse and inspect manually:
- `step=14`
- `label=Subscribe self-skill cache`
- `detail=no skill events found after EOSE`
- `last_sent_epoch=1781314692`
(Only `step` is strictly needed for the de-dup key; the rest aids debugging.)
### New helpers in [`src/main.c`](src/main.c)
Add small static helpers near
[`notify_admin_startup_failure()`](src/main.c:331):
- `startup_failure_marker_path(cfg, out, out_size)` -- builds
`<workdir>/.didactyl_startup_failure`.
- `startup_failure_already_notified(cfg, step)` -- returns 1 if the marker exists AND its
`step=` matches the current `step` (suppress); 0 otherwise (allow). Missing/unreadable
marker -> 0 (allow).
- `startup_failure_marker_write(cfg, step, label, detail)` -- writes/overwrites the marker
after an attempted send.
- `startup_failure_marker_clear(cfg)` -- `remove()` the marker; ignore ENOENT.
### Wiring
- In [`notify_admin_startup_failure()`](src/main.c:331): after the existing guard
clauses (config/admin/relay), check `startup_failure_already_notified(cfg, step)`.
If it returns 1, log a DEBUG_INFO suppression line and return without sending.
- On a successful send, call `startup_failure_marker_write(cfg, step, label, detail)`.
- If the same step keeps failing, only the first restart in the episode sends a DM;
subsequent restarts find the matching marker and stay silent.
- If a different step fails later, the `step=` mismatch allows exactly one new DM and
rewrites the marker with the new step.
- On the success path, clear the marker so the next failure episode notifies again. Add
`startup_failure_marker_clear(&cfg);` next to the READY success DM at
[`src/main.c:1663`](src/main.c:1663).
### Edge cases
- Marker write failure (e.g. read-only FS): log DEBUG_WARN and continue. Worst case we
fall back to current behavior (may re-send on next restart) -- acceptable, never fatal.
- Two services share the binary but use different home dirs, so markers never collide.
## Part B -- Descriptive failure message
Enhance the message built in
[`notify_admin_startup_failure()`](src/main.c:331) to append:
1. **Attempted relays + per-relay state.** Add a compact accessor to the nostr handler:
- New `nostr_handler_relay_state_summary(void)` in
[`nostr_handler.c`](src/nostr_handler.c) / [`nostr_handler.h`](src/nostr_handler.h)
returning a caller-freed compact string like
`relay.laantungir.net=connected; relay.damus.io=connected; relay.primal.net=connecting`.
- Implement by reusing the existing loop over `g_cfg->relays[]` +
`nostr_relay_pool_get_relay_status()` + `relay_status_str()` (patterns at
[`src/nostr_handler.c:3183`](src/nostr_handler.c:3183) and
[`src/nostr_handler.c:419`](src/nostr_handler.c:419)).
- Preferred over embedding raw JSON from
[`nostr_handler_relay_status_json()`](src/nostr_handler.c:3971) to keep the DM short.
2. **Needed event kinds (step-specific).** For step 14 append a fixed clause naming the
required events: kind 31123/31124 (skills) and kind 10123 (adoption list). Implement as
a small `startup_step_needed_events(step)` lookup in [`src/main.c`](src/main.c) that
returns a clause for known steps (14, 11, ...) and empty for others.
### Resulting message shape (example)
- `Didactyl FAILED to start at 2026-06-13 10:38:13.`
- `Startup step [14] Subscribe self-skill cache failed: no skill events found after EOSE.`
- `Version v0.2.48. Connected relays: 3/3.`
- `Relays: relay.laantungir.net=connected; relay.damus.io=connected; relay.primal.net=connected.`
- `Needed events: kind 31123/31124 (skills) and kind 10123 (adoption list) for this agent's pubkey.`
- `The agent is NOT online and will not answer DMs until fixed.`
Keep within the existing `failure_dm` buffer (bump to ~1536 if needed); `snprintf`
truncation remains safe.
## Implementation order
1. Add `nostr_handler_relay_state_summary()` to handler `.c`/`.h`.
2. Add marker helpers + `startup_step_needed_events()` to [`src/main.c`](src/main.c).
3. Update [`notify_admin_startup_failure()`](src/main.c:331): de-dup check, richer
message, marker write on send.
4. Add `startup_failure_marker_clear(&cfg)` on the READY success path
([`src/main.c:1663`](src/main.c:1663)).
5. Build (`make`), then `build_static.sh`, deploy, verify.
## Verification (follow-up)
1. **Throttle:** reproduce step-14 failure; confirm exactly one DM on the first failing
restart and no further DMs across subsequent restart-loop iterations (journal shows a
suppression line).
2. **Clear-on-success:** publish a skill so startup reaches `READY`; confirm marker is
removed and the normal startup DM is sent.
3. **Re-arm:** break startup again and confirm a single new DM is delivered.
4. **Descriptive content:** confirm the DM includes the per-relay state line and the
needed-events clause.
5. **Sandbox write:** on VM410 confirm the marker is created at
`/home/didactyl/.didactyl_startup_failure` (and `/home/simon/...`) without permission
errors under the systemd sandbox.
+203
View File
@@ -328,6 +328,174 @@ static void startup_step_fail(int step, const char* label, const char* detail) {
fflush(stderr);
}
static void startup_failure_marker_path(const didactyl_config_t* cfg, char* out, size_t out_size) {
if (!out || out_size == 0) {
return;
}
const char* cwd = ".";
if (cfg && cfg->tools.shell.working_directory[0] != '\0') {
cwd = cfg->tools.shell.working_directory;
}
size_t cwd_len = strlen(cwd);
if (cwd_len > 0 && cwd[cwd_len - 1] == '/') {
snprintf(out, out_size, "%s.didactyl_startup_failure", cwd);
} else {
snprintf(out, out_size, "%s/.didactyl_startup_failure", cwd);
}
}
static int startup_failure_already_notified(const didactyl_config_t* cfg, int step) {
char marker_path[512] = {0};
startup_failure_marker_path(cfg, marker_path, sizeof(marker_path));
FILE* fp = fopen(marker_path, "rb");
if (!fp) {
return 0;
}
int marker_step = -1;
char line[512];
while (fgets(line, sizeof(line), fp)) {
if (sscanf(line, "step=%d", &marker_step) == 1) {
break;
}
}
fclose(fp);
return marker_step == step ? 1 : 0;
}
static void startup_failure_marker_write(const didactyl_config_t* cfg,
int step,
const char* label,
const char* detail) {
char marker_path[512] = {0};
startup_failure_marker_path(cfg, marker_path, sizeof(marker_path));
FILE* fp = fopen(marker_path, "wb");
if (!fp) {
DEBUG_WARN("[didactyl] startup failure marker write failed: path=%s errno=%d", marker_path, errno);
return;
}
const char* effective_label = (label && label[0] != '\0') ? label : "Unknown startup step";
const char* effective_detail = (detail && detail[0] != '\0') ? detail : "no detail provided";
time_t now = time(NULL);
fprintf(fp, "step=%d\n", step);
fprintf(fp, "label=%s\n", effective_label);
fprintf(fp, "detail=%s\n", effective_detail);
fprintf(fp, "last_sent_epoch=%ld\n", (long)now);
fclose(fp);
}
static void startup_failure_marker_clear(const didactyl_config_t* cfg) {
char marker_path[512] = {0};
startup_failure_marker_path(cfg, marker_path, sizeof(marker_path));
if (remove(marker_path) != 0 && errno != ENOENT) {
DEBUG_WARN("[didactyl] startup failure marker clear failed: path=%s errno=%d", marker_path, errno);
}
}
static const char* startup_step_needed_events(int step) {
if (step == 14) {
return "kind 31123/31124 (skills) and kind 10123 (adoption list) for this agent pubkey";
}
if (step == 11) {
return "kind 10002 relay list for this agent pubkey";
}
return NULL;
}
static void notify_admin_startup_failure(const didactyl_config_t* cfg,
int step,
const char* label,
const char* detail) {
if (!cfg) {
DEBUG_WARN("[didactyl] startup failure DM skipped: config unavailable (step=%d)", step);
return;
}
if (cfg->admin.pubkey[0] == '\0') {
DEBUG_WARN("[didactyl] startup failure DM skipped: admin pubkey unavailable (step=%d)", step);
return;
}
int connected_relays = nostr_handler_connected_relay_count();
if (connected_relays <= 0) {
DEBUG_WARN("[didactyl] startup failure DM skipped: no connected relays (step=%d)", step);
return;
}
if (startup_failure_already_notified(cfg, step)) {
DEBUG_INFO("[didactyl] startup failure DM suppressed (already notified for step %d)", step);
return;
}
const char* effective_label = (label && label[0] != '\0') ? label : "Unknown startup step";
const char* effective_detail = (detail && detail[0] != '\0') ? detail : "no detail provided";
const char* startup_name = nostr_handler_get_startup_display_name();
const char* needed_events = startup_step_needed_events(step);
char* relay_summary = nostr_handler_relay_state_summary();
time_t now = time(NULL);
struct tm tm_now;
char time_str[32] = {0};
if (localtime_r(&now, &tm_now)) {
(void)strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm_now);
} else {
snprintf(time_str, sizeof(time_str), "%ld", (long)now);
}
char failure_dm[1536];
if (needed_events && needed_events[0] != '\0') {
snprintf(failure_dm,
sizeof(failure_dm),
"%s FAILED to start at %s. Startup step [%02d] %s failed: %s. Version %s. Connected relays: %d/%d. Relays: %s. Needed events: %s. The agent is NOT online and will not answer DMs until fixed.",
(startup_name && startup_name[0] != '\0') ? startup_name : "Didactyl",
time_str,
step,
effective_label,
effective_detail,
DIDACTYL_VERSION,
connected_relays,
cfg->relay_count,
relay_summary ? relay_summary : "unavailable",
needed_events);
} else {
snprintf(failure_dm,
sizeof(failure_dm),
"%s FAILED to start at %s. Startup step [%02d] %s failed: %s. Version %s. Connected relays: %d/%d. Relays: %s. The agent is NOT online and will not answer DMs until fixed.",
(startup_name && startup_name[0] != '\0') ? startup_name : "Didactyl",
time_str,
step,
effective_label,
effective_detail,
DIDACTYL_VERSION,
connected_relays,
cfg->relay_count,
relay_summary ? relay_summary : "unavailable");
}
if (nostr_handler_send_dm_auto(cfg->admin.pubkey, failure_dm) != 0) {
DEBUG_WARN("[didactyl] startup failure DM send failed (step=%d)", step);
free(relay_summary);
return;
}
startup_failure_marker_write(cfg, step, effective_label, effective_detail);
DEBUG_INFO("[didactyl] startup failure DM sent to admin for step %d", step);
for (int i = 0; i < 4; i++) {
(void)nostr_handler_poll(100);
}
free(relay_summary);
}
static int relay_list_contains(char** relays, int relay_count, const char* relay_url) {
if (!relays || relay_count <= 0 || !relay_url || relay_url[0] == '\0') {
return 0;
@@ -1297,6 +1465,10 @@ int main(int argc, char** argv) {
startup_step_begin(3, "Validate LLM config");
if (!llm_config_is_complete(&cfg.llm)) {
startup_step_fail(3, "Validate LLM config", "missing user-settings.global_llm (model/base_url/api_key)");
notify_admin_startup_failure(&cfg,
3,
"Validate LLM config",
"missing user-settings.global_llm (model/base_url/api_key)");
fprintf(stderr,
"Missing LLM config: provide genesis file values or store d=user-settings with global_llm\n");
nostr_block_list_cleanup();
@@ -1310,6 +1482,7 @@ int main(int argc, char** argv) {
startup_step_begin(4, "Validate admin config");
if (!admin_config_is_complete(&cfg)) {
startup_step_fail(4, "Validate admin config", "missing admin pubkey");
notify_admin_startup_failure(&cfg, 4, "Validate admin config", "missing admin pubkey");
fprintf(stderr,
"Missing admin config: provide admin.pubkey in genesis, pass --admin, or store d=user-settings with didactyl.admin_pubkey\n");
nostr_block_list_cleanup();
@@ -1323,6 +1496,7 @@ int main(int argc, char** argv) {
startup_step_begin(5, "Initialize LLM client");
if (llm_init(&cfg.llm) != 0) {
startup_step_fail(5, "Initialize LLM client", "llm_init failed");
notify_admin_startup_failure(&cfg, 5, "Initialize LLM client", "llm_init failed");
fprintf(stderr, "Failed to initialize llm client\n");
nostr_block_list_cleanup();
nostr_handler_cleanup();
@@ -1341,6 +1515,10 @@ int main(int argc, char** argv) {
if (bootstrap_mode || first_run) {
if (nostr_handler_reconcile_startup_events() != 0) {
startup_step_fail(7, "Reconcile/persist startup state", "startup event reconciliation failed");
notify_admin_startup_failure(&cfg,
7,
"Reconcile/persist startup state",
"startup event reconciliation failed");
fprintf(stderr, "Failed to publish startup events; aborting startup\n");
nostr_block_list_cleanup();
nostr_handler_cleanup();
@@ -1369,6 +1547,7 @@ int main(int argc, char** argv) {
startup_step_begin(8, "Initialize agent");
if (agent_init(&cfg) != 0) {
startup_step_fail(8, "Initialize agent", "agent_init failed");
notify_admin_startup_failure(&cfg, 8, "Initialize agent", "agent_init failed");
fprintf(stderr, "Failed to initialize agent\n");
nostr_block_list_cleanup();
nostr_handler_cleanup();
@@ -1383,6 +1562,7 @@ int main(int argc, char** argv) {
trigger_manager_t trigger_manager;
if (trigger_manager_init(&trigger_manager, &cfg) != 0) {
startup_step_fail(9, "Initialize trigger manager", "trigger_manager_init failed");
notify_admin_startup_failure(&cfg, 9, "Initialize trigger manager", "trigger_manager_init failed");
fprintf(stderr, "Failed to initialize trigger manager\n");
agent_cleanup();
nostr_block_list_cleanup();
@@ -1418,6 +1598,10 @@ int main(int argc, char** argv) {
int discovered_count = 0;
if (wait_for_self_kind10002_relays(&cfg, kind10002_timeout_ms, 200, &discovered_relays, &discovered_count) <= 0) {
startup_step_fail(11, "Discover self relay list via kind 10002", "required relay list not retrievable; aborting startup");
notify_admin_startup_failure(&cfg,
11,
"Discover self relay list via kind 10002",
"required relay list not retrievable; aborting startup");
fprintf(stderr, "Startup aborted: could not retrieve valid self kind 10002 within %d ms\n", kind10002_timeout_ms);
agent_cleanup();
nostr_block_list_cleanup();
@@ -1435,6 +1619,10 @@ int main(int argc, char** argv) {
if (added_relays < 0 || nostr_handler_sync_relays_from_config() != 0) {
startup_step_fail(11, "Discover self relay list via kind 10002", "failed to apply discovered relay list to pool");
notify_admin_startup_failure(&cfg,
11,
"Discover self relay list via kind 10002",
"failed to apply discovered relay list to pool");
agent_cleanup();
nostr_block_list_cleanup();
trigger_manager_cleanup(&trigger_manager);
@@ -1479,6 +1667,10 @@ int main(int argc, char** argv) {
DEBUG_INFO("[didactyl] startup phase: subscribe self skill cache begin");
if (nostr_handler_subscribe_self_skills() != 0) {
startup_step_fail(14, "Subscribe self-skill cache", "nostr_handler_subscribe_self_skills failed");
notify_admin_startup_failure(&cfg,
14,
"Subscribe self-skill cache",
"nostr_handler_subscribe_self_skills failed");
DEBUG_ERROR("[didactyl] startup phase: subscribe self skill cache failed");
fprintf(stderr, "Startup aborted: failed to subscribe self-skill cache\n");
agent_cleanup();
@@ -1496,6 +1688,10 @@ int main(int argc, char** argv) {
startup_step_fail(14,
"Subscribe self-skill cache",
"self-skill EOSE not received within timeout");
notify_admin_startup_failure(&cfg,
14,
"Subscribe self-skill cache",
"self-skill EOSE not received within timeout");
fprintf(stderr,
"Startup aborted: self-skill EOSE not received within %d ms\n",
self_skill_eose_timeout_ms);
@@ -1521,6 +1717,10 @@ int main(int argc, char** argv) {
startup_step_fail(14,
"Subscribe self-skill cache",
"no skill events found after EOSE");
notify_admin_startup_failure(&cfg,
14,
"Subscribe self-skill cache",
"no skill events found after EOSE");
fprintf(stderr,
"Startup aborted: no skill events (kind 31123/31124) found in self-skill cache\n");
fprintf(stderr,
@@ -1550,6 +1750,7 @@ int main(int argc, char** argv) {
DEBUG_INFO("[didactyl] startup phase: subscribe DMs begin");
if (nostr_handler_subscribe_dms(agent_on_message, NULL) != 0) {
startup_step_fail(15, "Subscribe DMs", "nostr_handler_subscribe_dms failed");
notify_admin_startup_failure(&cfg, 15, "Subscribe DMs", "nostr_handler_subscribe_dms failed");
DEBUG_ERROR("[didactyl] startup phase: subscribe DMs failed");
fprintf(stderr, "Failed to subscribe to DMs\n");
agent_cleanup();
@@ -1664,6 +1865,8 @@ int main(int argc, char** argv) {
DEBUG_WARN("[didactyl] startup phase: failed to send startup status DM to admin");
}
startup_failure_marker_clear(&cfg);
startup_step_ok(18, "READY", "agent online; entering main poll loop");
DEBUG_INFO("[didactyl] entering main poll loop");
DEBUG_INFO("[didactyl] running with pubkey %s", cfg.keys.public_key_hex);
+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 2
#define DIDACTYL_VERSION_PATCH 48
#define DIDACTYL_VERSION "v0.2.48"
#define DIDACTYL_VERSION_PATCH 49
#define DIDACTYL_VERSION "v0.2.49"
// Agent metadata
#define DIDACTYL_NAME "Didactyl"
+44
View File
@@ -3968,6 +3968,50 @@ int nostr_handler_connected_relay_count(void) {
return connected;
}
char* nostr_handler_relay_state_summary(void) {
if (!g_cfg || !g_pool || g_cfg->relay_count <= 0 || !g_cfg->relays) {
return NULL;
}
size_t total = 1;
for (int i = 0; i < g_cfg->relay_count; i++) {
const char* relay = (g_cfg->relays[i] && g_cfg->relays[i][0] != '\0') ? g_cfg->relays[i] : "<unknown>";
const char* status = relay_status_str(nostr_relay_pool_get_relay_status(g_pool, relay));
total += strlen(relay) + 1 + strlen(status) + 2;
}
char* out = (char*)malloc(total);
if (!out) {
return NULL;
}
out[0] = '\0';
size_t used = 0;
for (int i = 0; i < g_cfg->relay_count; i++) {
const char* relay = (g_cfg->relays[i] && g_cfg->relays[i][0] != '\0') ? g_cfg->relays[i] : "<unknown>";
const char* status = relay_status_str(nostr_relay_pool_get_relay_status(g_pool, relay));
int n = snprintf(out + used,
total - used,
"%s%s=%s",
(i == 0) ? "" : "; ",
relay,
status);
if (n < 0) {
free(out);
return NULL;
}
size_t written = (size_t)n;
if (written >= (total - used)) {
used = total - 1;
break;
}
used += written;
}
return out;
}
char* nostr_handler_relay_status_json(void) {
if (!g_pool) {
return NULL;
+1
View File
@@ -81,6 +81,7 @@ int nostr_handler_refresh_self_skill_cache_from_relays(int timeout_ms);
int nostr_handler_is_event_in_self_cache(const char* event_id_hex);
const char* nostr_handler_get_startup_display_name(void);
int nostr_handler_connected_relay_count(void);
char* nostr_handler_relay_state_summary(void);
char* nostr_handler_get_admin_kind0_context(void);
char* nostr_handler_get_admin_kind3_context(void);
char* nostr_handler_get_admin_kind10002_context(void);
@@ -0,0 +1 @@
[2026-04-28 07:18:22] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"npub1REPLACE_WITH_TEST_ADMIN_PUBKEY\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1 @@
[2026-04-28 07:18:40] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"npub1REPLACE_WITH_TEST_ADMIN_PUBKEY\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,434 @@
[2026-04-28 07:27:53] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
[2026-04-28 07:27:53] [INFO ] [nostr_handler.c:2558] [didactyl] initializing relay pool with 2 relays
[2026-04-28 07:27:53] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.damus.io
[2026-04-28 07:27:53] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.primal.net
[2026-04-28 07:27:53] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1777375673", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1777375673", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1777375673"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1777375673"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1777375673"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1777375673"]
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [01] Relay connectivity: begin
[2026-04-28 07:27:54] [INFO ] [main.c:311] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1777375674", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1777375674", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1047>
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1045>
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1777375674"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1777375674"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1777375674"]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1777375674"]
[2026-04-28 07:27:54] [INFO ] [main.c:1007] [didactyl] startup phase: recovered user-settings from Nostr
[2026-04-28 07:27:54] [INFO ] [main.c:311] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok (user-settings recalled)
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [03] Validate LLM config: begin
[2026-04-28 07:27:54] [INFO ] [main.c:314] [didactyl] startup checklist [03] Validate LLM config: ok
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [04] Validate admin config: begin
[2026-04-28 07:27:54] [INFO ] [main.c:314] [didactyl] startup checklist [04] Validate admin config: ok
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [05] Initialize LLM client: begin
[2026-04-28 07:27:54] [INFO ] [main.c:314] [didactyl] startup checklist [05] Initialize LLM client: ok
[2026-04-28 07:27:54] [INFO ] [main.c:304] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1777375674", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1777375674", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1777375674"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1777375674"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1777375674"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1777375674"]
[2026-04-28 07:27:55] [INFO ] [main.c:1337] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
[2026-04-28 07:27:55] [INFO ] [main.c:311] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1777375675", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1777375675", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=a94194d5ba150931... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=e4d54d57a4d7180d... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=827>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=ecaba96e69d6b3ad... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b1ad6f867a2f34f8... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1657] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=a94194d5ba150931... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=e4d54d57a4d7180d... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=829>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=5b96f07025aa928e... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b1ad6f867a2f34f8... created_at=1777375675
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:3676] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
[2026-04-28 07:27:55] [INFO ] [main.c:937] [didactyl] startup phase: skipping user-settings publish because runtime config was recalled from Nostr
[2026-04-28 07:27:55] [INFO ] [main.c:1361] [didactyl] startup phase: persisted encrypted runtime config to Nostr
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [08] Initialize agent: begin
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1777375675", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1777375675", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","a94194d5ba1509318a6b44eece02f47c20ada0a1bb2dd4fdfce7f23d48b9f81e",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","a94194d5ba1509318a6b44eece02f47c20ada0a1bb2dd4fdfce7f23d48b9f81e",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","e4d54d57a4d7180d8476a905e526e3b779a43f167493b67d066465b4eae1f7d9",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","e4d54d57a4d7180d8476a905e526e3b779a43f167493b67d066465b4eae1f7d9",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","5b96f07025aa928e3ca6221f74cfc5ea6292a382acbfac5cb6f4f3ec8786772e",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1777375675"]
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [08] Initialize agent: ok
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [09] Initialize trigger manager: begin
[2026-04-28 07:27:55] [INFO ] [trigger_manager.c:935] [didactyl] trigger manager initialized (capacity=16)
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [09] Initialize trigger manager: ok
[2026-04-28 07:27:55] [INFO ] [main.c:1405] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [10] Load startup triggers: begin
[2026-04-28 07:27:55] [INFO ] [main.c:1408] [didactyl] startup phase: startup-config trigger load begin
[2026-04-28 07:27:55] [INFO ] [trigger_manager.c:1259] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:27:55] [INFO ] [trigger_manager.c:1142] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:27:55] [INFO ] [trigger_manager.c:1150] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
[2026-04-28 07:27:55] [INFO ] [main.c:1412] [didactyl] startup phase: startup-config trigger load end
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [10] Load startup triggers: ok
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
[2026-04-28 07:27:55] [INFO ] [main.c:383] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
[2026-04-28 07:27:55] [INFO ] [main.c:390] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375673,"last_event_time":1777375675},{"url":"wss://relay.primal.net","status":"connected","events_received":2,"events_published":4,"events_published_ok":3,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375673,"last_event_time":1777375675}]}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1777375675", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1777375675", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","ecaba96e69d6b3ad9bde94779fbdfdfcbbd112e6a3eb8dbf508859e9a9230b93",true,""]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1777375675"]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1777375675"]
[2026-04-28 07:27:55] [INFO ] [main.c:410] [didactyl] kind10002 query received event_count=1
[2026-04-28 07:27:55] [INFO ] [main.c:507] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
[2026-04-28 07:27:55] [INFO ] [main.c:612] [didactyl] kind10002 wait success: relay_count=2
[2026-04-28 07:27:55] [INFO ] [main.c:614] [didactyl] kind10002 relay[0]=wss://relay.damus.io
[2026-04-28 07:27:55] [INFO ] [main.c:614] [didactyl] kind10002 relay[1]=wss://relay.primal.net
[2026-04-28 07:27:55] [INFO ] [main.c:618] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375673,"last_event_time":1777375675},{"url":"wss://relay.primal.net","status":"connected","events_received":2,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375673,"last_event_time":1777375675}]}
[2026-04-28 07:27:55] [INFO ] [main.c:311] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [12] Subscribe admin context: begin
[2026-04-28 07:27:55] [INFO ] [main.c:1463] [didactyl] startup phase: subscribe admin context begin
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1777375675", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1777375675", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1777375675", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1777375675", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:2703] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
[2026-04-28 07:27:55] [INFO ] [main.c:1467] [didactyl] startup phase: subscribe admin context end
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [12] Subscribe admin context: ok
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [13] Subscribe agent self context: begin
[2026-04-28 07:27:55] [INFO ] [main.c:1471] [didactyl] startup phase: subscribe agent self context begin
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1777375675", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1777375675", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1777375675", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1777375675", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:2791] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:27:55] [INFO ] [main.c:1475] [didactyl] startup phase: subscribe agent self context end
[2026-04-28 07:27:55] [INFO ] [main.c:314] [didactyl] startup checklist [13] Subscribe agent self context: ok
[2026-04-28 07:27:55] [INFO ] [main.c:304] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
[2026-04-28 07:27:55] [INFO ] [main.c:1479] [didactyl] startup phase: subscribe self skill cache begin
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:2827] [didactyl] self-skill subscription filter: {"kinds":[31123,31124,10123],"authors":["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],"limit":300}
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1777375675", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1777375675", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1777375675", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:27:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1777375675", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:27:55] [INFO ] [nostr_handler.c:2887] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6 created_at=1777375675 via wss://relay.primal.net
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b1ad6f867a2f34f8... created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=816>
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=ecaba96e69d6b3ad9bde94779fbdfdfcbbd112e6a3eb8dbf508859e9a9230b93 created_at=1777375675 via wss://relay.damus.io
[2026-04-28 07:27:56] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=ecaba96e69d6b3ad... created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=818>
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=5b96f07025aa928e3ca6221f74cfc5ea6292a382acbfac5cb6f4f3ec8786772e created_at=1777375675 via wss://relay.primal.net
[2026-04-28 07:27:56] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=5b96f07025aa928e... created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6 created_at=1777375675 via wss://relay.damus.io
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b1ad6f867a2f34f8... created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375675)
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1777375675"]
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2070] [didactyl] self-skill EOSE received: cached skill events=0
[2026-04-28 07:27:56] [INFO ] [main.c:47] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
[2026-04-28 07:27:56] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:27:56] [INFO ] [trigger_manager.c:1039] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
[2026-04-28 07:27:56] [INFO ] [main.c:57] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1777375675"]
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=5b96f07025aa928e3ca6221f74cfc5ea6292a382acbfac5cb6f4f3ec8786772e created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=10123 d_tag=- id=b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6 created_at=1777375675
[2026-04-28 07:27:56] [INFO ] [main.c:1546] [didactyl] startup phase: subscribe self skill cache end
[2026-04-28 07:27:56] [INFO ] [main.c:311] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
[2026-04-28 07:27:56] [INFO ] [main.c:304] [didactyl] startup checklist [15] Subscribe DMs: begin
[2026-04-28 07:27:56] [INFO ] [main.c:1550] [didactyl] startup phase: subscribe DMs begin
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:2905] [didactyl] DM subscribe: dm_protocol=2 need_kind4=1 need_kind1059=1 g_start_time=1777375673
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1777375676", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375673,
"limit": 100
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1777375676", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375673,
"limit": 100
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1777375676", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1777375676", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3000] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:3001] [didactyl] DEBUG DM subscription g_start_time=1777375673 now=1777375676 delta=3 relay_count=2
[2026-04-28 07:27:56] [INFO ] [main.c:1565] [didactyl] startup phase: subscribe DMs end
[2026-04-28 07:27:56] [INFO ] [main.c:314] [didactyl] startup checklist [15] Subscribe DMs: ok
[2026-04-28 07:27:56] [INFO ] [main.c:304] [didactyl] startup checklist [16] Subscribe wallet events: begin
[2026-04-28 07:27:56] [INFO ] [main.c:1569] [didactyl] startup phase: subscribe wallet events begin
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1777375676", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375673,
"limit": 500
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1777375676", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375673,
"limit": 500
}]
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3053] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:27:56] [INFO ] [main.c:1573] [didactyl] startup phase: subscribe wallet events end
[2026-04-28 07:27:56] [INFO ] [main.c:314] [didactyl] startup checklist [16] Subscribe wallet events: ok
[2026-04-28 07:27:56] [INFO ] [main.c:304] [didactyl] startup checklist [17] Initialize cashu wallet: begin
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1777375676", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1777375676", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1777375675"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1777375676"]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1777375676"]
[2026-04-28 07:27:56] [WARN ] [main.c:1589] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
[2026-04-28 07:27:56] [INFO ] [main.c:311] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
[2026-04-28 07:27:56] [INFO ] [http_api.c:1662] [didactyl] http api listening on http://127.0.0.1:8485
[2026-04-28 07:27:56] [INFO ] [main.c:1629] [didactyl] HTTP API listening at http://127.0.0.1:8485
[2026-04-28 07:27:56] [INFO ] [main.c:1632] [didactyl] HTTP API endpoints: http://127.0.0.1:8485/api/context/current http://127.0.0.1:8485/api/context/parts
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:1844] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-28 07:27:56 (version v0.2.48, connected relays: 2/2).
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:1836] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1777375676,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"4M2CHJPV80ujTCckvsFEbZXfDAoYlTt95OJ36vFCVNktDiLEcugD1i75WDGY+nH/kmYQY4E4GOYnBQ9cRPc9z5K4URJa4NomXGQaLpyjVWqKpVd557s6t2HA/9mT5UiohdkfLEcv1fhFWHLlQZdHV1AfEklYwP9D7ZuOdobShsU=?iv=bjxvVALQI+GlATrv3iurcw==","id":"2a1530bcf8fb2b5e63022e96cd369b88ad302187179ed892cc146e769c7ebd15","sig":"f63c084fd0bf131f952c934d0e8ced20a6bda170e4d43c5c40ee9111337ec8748caf65434fd0937bf2463d5681e2ada89514d80f97f0e688126cefae163628d6"}
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:920] [didactyl] publish DM target relays (2):
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.damus.io (async)
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.primal.net (async)
[2026-04-28 07:27:56] [INFO ] [nostr_handler.c:3209] [didactyl] sent DM 2a1530bcf8fb2b5e... to 254d7a7f68b4443f... via 2 connected relay(s)
[2026-04-28 07:27:56] [INFO ] [main.c:311] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
[2026-04-28 07:27:56] [INFO ] [main.c:1668] [didactyl] entering main poll loop
[2026-04-28 07:27:56] [INFO ] [main.c:1669] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","2a1530bcf8fb2b5e63022e96cd369b88ad302187179ed892cc146e769c7ebd15",true,""]
[2026-04-28 07:27:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","2a1530bcf8fb2b5e63022e96cd369b88ad302187179ed892cc146e769c7ebd15",true,""]
[2026-04-28 07:27:56] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=30991 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Save test harness probe to memory, then recall your memory"},{"role":"user","content":"Save test harness probe to memory, then recall your memory","_ts":1777375676}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr_react","description":"React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)","parameters":{"type":"object","properties":{"event_id":{"type":"string","description":"Target event ID to react to"},"event_pubkey":{"type":"string","description":"Author pubkey of target event"},"event_kind":{"type":"integer","description":"Optional kind of target event"},"reaction":{"type":"string","description":"Reaction content such as +, -, ❤️, or emoji"}},"required":["event_id","event_pubkey"]}}},{"type":"function","function":{"name":"nostr_profile_get","description":"Look up a Nostr profile (kind 0 metadata) by pubkey","parameters":{"type":"object","properties":{"pubkey":{"type":"string","desc...
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:920] [didactyl] publish kind event target relays (2):
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:27:59] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=836>
[2026-04-28 07:27:59] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=838>
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:3323] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:3323] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=30078 author=1eb171136dbb1ba6... id=6311c65cf9b52fe1... created_at=1777375679
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:27:59] [INFO ] [nostr_handler.c:3391] [didactyl] published kind 30078 event via 2 connected relay(s)
[2026-04-28 07:27:59] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=31689 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Save test harness probe to memory, then recall your memory"},{"role":"user","content":"Save test harness probe to memory, then recall your memory","_ts":1777375676},{"role":"assistant","content":"I'll save a test harness probe to memory and then recall it.","tool_calls":[{"id":"toolu_bdrk_01GBGt8MaQjzZj4i23ij5caL","type":"function","function":{"name":"memory_save","arguments":"{\"content\": \"Test harness probe - system verification checkpoint. Agent memory subsystem operational. Timestamp: current session. This entry confirms memory_save and memory_recall functions are working correctly.\"}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_01GBGt8MaQjzZj4i23ij5caL","content":"{\"success\":true,\"d_tag\":\"memory\",\"kind\":30078,\"entry_length\":199,\"truncated\":false,\"event_id\":\"6311c65cf9b52fe1fe9bce8052a09f594d6b3dc1f83f8030f45106b8b3a108e2\"}"}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr...
[2026-04-28 07:28:02] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=32229 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Save test harness probe to memory, then recall your memory"},{"role":"user","content":"Save test harness probe to memory, then recall your memory","_ts":1777375676},{"role":"assistant","content":"I'll save a test harness probe to memory and then recall it.","tool_calls":[{"id":"toolu_bdrk_01GBGt8MaQjzZj4i23ij5caL","type":"function","function":{"name":"memory_save","arguments":"{\"content\": \"Test harness probe - system verification checkpoint. Agent memory subsystem operational. Timestamp: current session. This entry confirms memory_save and memory_recall functions are working correctly.\"}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_01GBGt8MaQjzZj4i23ij5caL","content":"{\"success\":true,\"d_tag\":\"memory\",\"kind\":30078,\"entry_length\":199,\"truncated\":false,\"event_id\":\"6311c65cf9b52fe1fe9bce8052a09f594d6b3dc1f83f8030f45106b8b3a108e2\"}"},{"role":"assistant","content":"Great! Now let me recall the memory:","tool_calls":[{"id":"toolu_bdrk_01QgBARiRY5FTx8TJH3GhzU6","type":"function","function":{"name":"memory_recall","arguments":"{}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_01QgBARiRY5FTx8TJH3GhzU6","content":"{\"success\":true,\"content\":\"Test harness probe - system verification checkpoint. Agent memory subsystem operational. Timestamp: current session. This entry confirms memory_save and memory_recall functions are working correctly.\",\"content_length\":199}"}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function",...
[2026-04-28 07:28:19] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","6311c65cf9b52fe1fe9bce8052a09f594d6b3dc1f83f8030f45106b8b3a108e2",false,"rate-limited: you are noting too much"]
[2026-04-28 07:28:19] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","6311c65cf9b52fe1fe9bce8052a09f594d6b3dc1f83f8030f45106b8b3a108e2",true,""]
[2026-04-28 07:28:25] [INFO ] [main.c:1691] [didactyl] shutting down
[2026-04-28 07:28:25] [INFO ] [trigger_manager.c:1734] [didactyl] trigger manager cleaned up
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1777375675"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1777375676"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1777375676"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1777375676"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1777375676"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1777375676"]
[2026-04-28 07:28:25] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1777375676"]
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,403 @@
[2026-04-28 07:28:25] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
[2026-04-28 07:28:25] [INFO ] [nostr_handler.c:2558] [didactyl] initializing relay pool with 2 relays
[2026-04-28 07:28:25] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.damus.io
[2026-04-28 07:28:25] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.primal.net
[2026-04-28 07:28:26] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1777375705", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:28:26] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1777375705"]
[2026-04-28 07:28:26] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1777375705"]
[2026-04-28 07:28:26] [INFO ] [main.c:304] [didactyl] startup checklist [01] Relay connectivity: begin
[2026-04-28 07:28:26] [INFO ] [main.c:311] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 1/2)
[2026-04-28 07:28:26] [INFO ] [main.c:304] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1777375706", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1047>
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1777375706"]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1777375706"]
[2026-04-28 07:28:27] [INFO ] [main.c:1007] [didactyl] startup phase: recovered user-settings from Nostr
[2026-04-28 07:28:27] [INFO ] [main.c:311] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok (user-settings recalled)
[2026-04-28 07:28:27] [INFO ] [main.c:304] [didactyl] startup checklist [03] Validate LLM config: begin
[2026-04-28 07:28:27] [INFO ] [main.c:314] [didactyl] startup checklist [03] Validate LLM config: ok
[2026-04-28 07:28:27] [INFO ] [main.c:304] [didactyl] startup checklist [04] Validate admin config: begin
[2026-04-28 07:28:27] [INFO ] [main.c:314] [didactyl] startup checklist [04] Validate admin config: ok
[2026-04-28 07:28:27] [INFO ] [main.c:304] [didactyl] startup checklist [05] Initialize LLM client: begin
[2026-04-28 07:28:27] [INFO ] [main.c:314] [didactyl] startup checklist [05] Initialize LLM client: ok
[2026-04-28 07:28:27] [INFO ] [main.c:304] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1777375707", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1777375707", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1777375707"]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1777375707"]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1777375707"]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1777375707"]
[2026-04-28 07:28:27] [INFO ] [main.c:1337] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
[2026-04-28 07:28:27] [INFO ] [main.c:311] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
[2026-04-28 07:28:27] [INFO ] [main.c:304] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1777375707", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1777375707", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1777375707"]
[2026-04-28 07:28:27] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1777375707"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1777375707"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1777375707"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=d19395f4a4826b36... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=1bdbec7b70533806... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=827>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=7ddb16d25587f2d8... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=3940625df170eddc... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1657] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=d19395f4a4826b36... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=1bdbec7b70533806... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=829>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=1ab607d36b07b8a7... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375708)
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=3940625df170eddc... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375708)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3676] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
[2026-04-28 07:28:28] [INFO ] [main.c:937] [didactyl] startup phase: skipping user-settings publish because runtime config was recalled from Nostr
[2026-04-28 07:28:28] [INFO ] [main.c:1361] [didactyl] startup phase: persisted encrypted runtime config to Nostr
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [08] Initialize agent: begin
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1777375708", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1777375708", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","1bdbec7b70533806ccad4e1224cd17aca8dedbc200499dc70687716f08eb6009",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","1bdbec7b70533806ccad4e1224cd17aca8dedbc200499dc70687716f08eb6009",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","d19395f4a4826b36b58d3d2c71b993233615df0d613eea7cc6e6b958d8ea6c12",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","d19395f4a4826b36b58d3d2c71b993233615df0d613eea7cc6e6b958d8ea6c12",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=824>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1777375708"]
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [08] Initialize agent: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [09] Initialize trigger manager: begin
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:935] [didactyl] trigger manager initialized (capacity=16)
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [09] Initialize trigger manager: ok
[2026-04-28 07:28:28] [INFO ] [main.c:1405] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [10] Load startup triggers: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1408] [didactyl] startup phase: startup-config trigger load begin
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1259] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1142] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1150] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
[2026-04-28 07:28:28] [INFO ] [main.c:1412] [didactyl] startup phase: startup-config trigger load end
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [10] Load startup triggers: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
[2026-04-28 07:28:28] [INFO ] [main.c:383] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
[2026-04-28 07:28:28] [INFO ] [main.c:390] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375705,"last_event_time":1777375708,"last_connection_error":"Failed to create WebSocket client for relay wss://relay.damus.io"},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375705,"last_event_time":1777375708}]}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1777375708", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1777375708", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","7ddb16d25587f2d80a59fd576141a8baec5a30b245969305fbe1628c42e73b2b",false,"rate-limited: you are noting too much"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","1ab607d36b07b8a7f7afc54319e3426754f22f8676829b3c8b7a5e50b21d7222",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","3940625df170eddc0770d0b334a1759e945d3261af94fa15c21f48fe0e6d5c90",false,"rate-limited: you are noting too much"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","3940625df170eddc0770d0b334a1759e945d3261af94fa15c21f48fe0e6d5c90",true,""]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1777375708"]
[2026-04-28 07:28:28] [INFO ] [main.c:410] [didactyl] kind10002 query received event_count=1
[2026-04-28 07:28:28] [INFO ] [main.c:507] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
[2026-04-28 07:28:28] [INFO ] [main.c:612] [didactyl] kind10002 wait success: relay_count=2
[2026-04-28 07:28:28] [INFO ] [main.c:614] [didactyl] kind10002 relay[0]=wss://relay.damus.io
[2026-04-28 07:28:28] [INFO ] [main.c:614] [didactyl] kind10002 relay[1]=wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [main.c:618] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":4,"events_published_ok":2,"events_published_failed":2,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375705,"last_event_time":1777375708,"last_publish_error":"rate-limited: you are noting too much","last_connection_error":"Failed to create WebSocket client for relay wss://relay.damus.io"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375705,"last_event_time":1777375708}]}
[2026-04-28 07:28:28] [INFO ] [main.c:311] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [12] Subscribe admin context: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1463] [didactyl] startup phase: subscribe admin context begin
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1777375708", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1777375708", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1777375708", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1777375708", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2703] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
[2026-04-28 07:28:28] [INFO ] [main.c:1467] [didactyl] startup phase: subscribe admin context end
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [12] Subscribe admin context: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [13] Subscribe agent self context: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1471] [didactyl] startup phase: subscribe agent self context begin
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1777375708", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1777375708", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1777375708", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1777375708", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2791] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:28:28] [INFO ] [main.c:1475] [didactyl] startup phase: subscribe agent self context end
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [13] Subscribe agent self context: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1479] [didactyl] startup phase: subscribe self skill cache begin
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2827] [didactyl] self-skill subscription filter: {"kinds":[31123,31124,10123],"authors":["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],"limit":300}
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1777375708", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1777375708", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1777375708", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1777375708", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2887] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=816>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=ecaba96e69d6b3ad9bde94779fbdfdfcbbd112e6a3eb8dbf508859e9a9230b93 created_at=1777375675 via wss://relay.damus.io
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=ecaba96e69d6b3ad... created_at=1777375675
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777375708 >= new created_at=1777375675)
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=3940625df170eddc0770d0b334a1759e945d3261af94fa15c21f48fe0e6d5c90 created_at=1777375708 via wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=3940625df170eddc... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375708)
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=b1ad6f867a2f34f881f5032b8e8ffe9c1472819822a4c32ba8f566cc2bcfaee6 created_at=1777375675 via wss://relay.damus.io
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b1ad6f867a2f34f8... created_at=1777375675
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777375708 >= new created_at=1777375675)
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=818>
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=1ab607d36b07b8a7f7afc54319e3426754f22f8676829b3c8b7a5e50b21d7222 created_at=1777375708 via wss://relay.primal.net
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=1ab607d36b07b8a7... created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375708)
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1777375708"]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2070] [didactyl] self-skill EOSE received: cached skill events=0
[2026-04-28 07:28:28] [INFO ] [main.c:47] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:28:28] [INFO ] [trigger_manager.c:1039] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
[2026-04-28 07:28:28] [INFO ] [main.c:57] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=1ab607d36b07b8a7f7afc54319e3426754f22f8676829b3c8b7a5e50b21d7222 created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=10123 d_tag=- id=3940625df170eddc0770d0b334a1759e945d3261af94fa15c21f48fe0e6d5c90 created_at=1777375708
[2026-04-28 07:28:28] [INFO ] [main.c:1546] [didactyl] startup phase: subscribe self skill cache end
[2026-04-28 07:28:28] [INFO ] [main.c:311] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [15] Subscribe DMs: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1550] [didactyl] startup phase: subscribe DMs begin
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:2905] [didactyl] DM subscribe: dm_protocol=2 need_kind4=1 need_kind1059=1 g_start_time=1777375705
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1777375708", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375705,
"limit": 100
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1777375708", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375705,
"limit": 100
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1777375708", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1777375708", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3000] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:3001] [didactyl] DEBUG DM subscription g_start_time=1777375705 now=1777375708 delta=3 relay_count=2
[2026-04-28 07:28:28] [INFO ] [main.c:1565] [didactyl] startup phase: subscribe DMs end
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [15] Subscribe DMs: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [16] Subscribe wallet events: begin
[2026-04-28 07:28:28] [INFO ] [main.c:1569] [didactyl] startup phase: subscribe wallet events begin
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1777375708", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375705,
"limit": 500
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1777375708", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375705,
"limit": 500
}]
[2026-04-28 07:28:28] [INFO ] [nostr_handler.c:3053] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:28:28] [INFO ] [main.c:1573] [didactyl] startup phase: subscribe wallet events end
[2026-04-28 07:28:28] [INFO ] [main.c:314] [didactyl] startup checklist [16] Subscribe wallet events: ok
[2026-04-28 07:28:28] [INFO ] [main.c:304] [didactyl] startup checklist [17] Initialize cashu wallet: begin
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1777375708", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1777375708", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1777375708"]
[2026-04-28 07:28:28] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1777375708"]
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1777375708"]
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1777375708"]
[2026-04-28 07:28:29] [WARN ] [main.c:1589] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
[2026-04-28 07:28:29] [INFO ] [main.c:311] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
[2026-04-28 07:28:29] [INFO ] [http_api.c:1662] [didactyl] http api listening on http://127.0.0.1:8485
[2026-04-28 07:28:29] [INFO ] [main.c:1629] [didactyl] HTTP API listening at http://127.0.0.1:8485
[2026-04-28 07:28:29] [INFO ] [main.c:1632] [didactyl] HTTP API endpoints: http://127.0.0.1:8485/api/context/current http://127.0.0.1:8485/api/context/parts
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:1844] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-28 07:28:29 (version v0.2.48, connected relays: 2/2).
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:1836] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1777375709,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"HQoPu71Z+V2fjBIgRpwDhDnJjzRc840nyhTNrgx3SpIqnEAueVKmRDeHzZMmaFSBbi9/Q774ZyLE80+XWqLI0OKjIReusdnzOQyZNi7939Fx+jZeTCuJHPKdLHw2gaghM23iPD9/5KdCwTzeXTfwX4jm8qpNGgkieacGigkdzjs=?iv=s3i0OGmiQdnmil6/6vtT4A==","id":"a0da6a4e741285abaec758df98b67b24cf87b4395ce4b13429276711809db95c","sig":"d8721548e9353ad3ca007becc37a8f84bf7426e8f6bfbcf9ba1d18598390af723c447f45f90e63cb6c8d1fac897c051a128293e589e60aad3a47035fa1e417b4"}
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:920] [didactyl] publish DM target relays (2):
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.damus.io (async)
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.primal.net (async)
[2026-04-28 07:28:29] [INFO ] [nostr_handler.c:3209] [didactyl] sent DM a0da6a4e741285ab... to 254d7a7f68b4443f... via 2 connected relay(s)
[2026-04-28 07:28:29] [INFO ] [main.c:311] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
[2026-04-28 07:28:29] [INFO ] [main.c:1668] [didactyl] entering main poll loop
[2026-04-28 07:28:29] [INFO ] [main.c:1669] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","a0da6a4e741285abaec758df98b67b24cf87b4395ce4b13429276711809db95c",true,""]
[2026-04-28 07:28:29] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","a0da6a4e741285abaec758df98b67b24cf87b4395ce4b13429276711809db95c",false,"rate-limited: you are noting too much"]
[2026-04-28 07:28:30] [INFO ] [main.c:1691] [didactyl] shutting down
[2026-04-28 07:28:30] [INFO ] [trigger_manager.c:1734] [didactyl] trigger manager cleaned up
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1777375708"]
[2026-04-28 07:28:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1777375708"]
@@ -0,0 +1,67 @@
{
"run_meta": {
"run_timestamp": "2026-04-28T11:28:30.755354+00:00",
"base_url": "http://127.0.0.1:8485",
"config": "tests/results/20260428T112825Z/runtime_test_genesis.jsonc",
"binary": "didactyl",
"test_count": 4
},
"results": [
{
"suite": "test_health",
"name": "status_returns_200",
"status": "pass",
"message": "status success",
"duration_seconds": 0.329037634015549,
"agent_errors": [],
"details": {
"keys": [
"success",
"name",
"version",
"pubkey",
"relay_count",
"connected_relays",
"active_triggers"
]
}
},
{
"suite": "test_health",
"name": "status_has_fields",
"status": "pass",
"message": "required fields present",
"duration_seconds": 0.3310440799978096,
"agent_errors": [],
"details": {}
},
{
"suite": "test_health",
"name": "context_current_returns_messages",
"status": "pass",
"message": "context current ok",
"duration_seconds": 0.3324761890107766,
"agent_errors": [],
"details": {
"message_count": 2
}
},
{
"suite": "test_health",
"name": "context_parts_has_system_prompt",
"status": "pass",
"message": "context parts ok",
"duration_seconds": 0.3313834259752184,
"agent_errors": [],
"details": {
"parts": [
"system_prompt",
"dm_history"
]
}
}
],
"summary": {
"pass": 4
}
}
@@ -0,0 +1,22 @@
== Didactyl Test Results ==
Run: 2026-04-28T11:28:30.755354+00:00
Agent base URL: http://127.0.0.1:8485
Pass: 4
Fail: 0
Error: 0
Timeout: 0
Skip: 0
Total: 4
[PASS] test_health::status_returns_200 (0.33s)
status success
[PASS] test_health::status_has_fields (0.33s)
required fields present
[PASS] test_health::context_current_returns_messages (0.33s)
context current ok
[PASS] test_health::context_parts_has_system_prompt (0.33s)
context parts ok
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,421 @@
[2026-04-28 07:29:45] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
[2026-04-28 07:29:45] [INFO ] [nostr_handler.c:2558] [didactyl] initializing relay pool with 2 relays
[2026-04-28 07:29:45] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.damus.io
[2026-04-28 07:29:45] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.primal.net
[2026-04-28 07:29:46] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1777375785", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:46] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1777375785", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:46] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1777375785"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1777375785"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1777375785"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1777375785"]
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [01] Relay connectivity: begin
[2026-04-28 07:29:47] [INFO ] [main.c:311] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1777375787", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1777375787", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1047>
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1045>
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1777375787"]
[2026-04-28 07:29:47] [INFO ] [main.c:1007] [didactyl] startup phase: recovered user-settings from Nostr
[2026-04-28 07:29:47] [INFO ] [main.c:311] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok (user-settings recalled)
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [03] Validate LLM config: begin
[2026-04-28 07:29:47] [INFO ] [main.c:314] [didactyl] startup checklist [03] Validate LLM config: ok
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [04] Validate admin config: begin
[2026-04-28 07:29:47] [INFO ] [main.c:314] [didactyl] startup checklist [04] Validate admin config: ok
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [05] Initialize LLM client: begin
[2026-04-28 07:29:47] [INFO ] [main.c:314] [didactyl] startup checklist [05] Initialize LLM client: ok
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1777375787", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1777375787", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1777375787"]
[2026-04-28 07:29:47] [INFO ] [main.c:1337] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
[2026-04-28 07:29:47] [INFO ] [main.c:311] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1777375787", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1777375787", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1777375787"]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=addbd253f977c8de... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=ff65d5864097fe6c... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=827>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=78b0aaddaf99b7dc... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=dc138a7c573943b8... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1657] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=addbd253f977c8de... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=ff65d5864097fe6c... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=829>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=63ffd51f9c14691d... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=dc138a7c573943b8... created_at=1777375787
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:29:47] [INFO ] [nostr_handler.c:3676] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
[2026-04-28 07:29:47] [INFO ] [main.c:937] [didactyl] startup phase: skipping user-settings publish because runtime config was recalled from Nostr
[2026-04-28 07:29:47] [INFO ] [main.c:1361] [didactyl] startup phase: persisted encrypted runtime config to Nostr
[2026-04-28 07:29:47] [INFO ] [main.c:314] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
[2026-04-28 07:29:47] [INFO ] [main.c:304] [didactyl] startup checklist [08] Initialize agent: begin
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1777375787", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:29:47] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1777375787", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=824>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","addbd253f977c8de882830e3029a78eea0ffa736bbfbeaecae7c5ac65fb9a2ec",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1777375787"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","ff65d5864097fe6cbffd211784f62ce93e67bad0ff5a6032a1fc8488b227009a",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","63ffd51f9c14691d8496ed68da75fdad71a6bd6f6a5669d023fd8dc0ad6771af",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1777375787"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","addbd253f977c8de882830e3029a78eea0ffa736bbfbeaecae7c5ac65fb9a2ec",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1777375787"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1777375787"]
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [08] Initialize agent: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [09] Initialize trigger manager: begin
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:935] [didactyl] trigger manager initialized (capacity=16)
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [09] Initialize trigger manager: ok
[2026-04-28 07:29:48] [INFO ] [main.c:1405] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [10] Load startup triggers: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1408] [didactyl] startup phase: startup-config trigger load begin
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1259] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1142] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1150] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
[2026-04-28 07:29:48] [INFO ] [main.c:1412] [didactyl] startup phase: startup-config trigger load end
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [10] Load startup triggers: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
[2026-04-28 07:29:48] [INFO ] [main.c:383] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
[2026-04-28 07:29:48] [INFO ] [main.c:390] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375785,"last_event_time":1777375788},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375785,"last_event_time":1777375788}]}
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1777375788", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1777375788", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","78b0aaddaf99b7dc66a8094c036551a416542ef87e7701ef53a4efbfe5f2d85d",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","ff65d5864097fe6cbffd211784f62ce93e67bad0ff5a6032a1fc8488b227009a",true,""]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1777375788"]
[2026-04-28 07:29:48] [INFO ] [main.c:410] [didactyl] kind10002 query received event_count=1
[2026-04-28 07:29:48] [INFO ] [main.c:507] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
[2026-04-28 07:29:48] [INFO ] [main.c:612] [didactyl] kind10002 wait success: relay_count=2
[2026-04-28 07:29:48] [INFO ] [main.c:614] [didactyl] kind10002 relay[0]=wss://relay.damus.io
[2026-04-28 07:29:48] [INFO ] [main.c:614] [didactyl] kind10002 relay[1]=wss://relay.primal.net
[2026-04-28 07:29:48] [INFO ] [main.c:618] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375785,"last_event_time":1777375788},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375785,"last_event_time":1777375788}]}
[2026-04-28 07:29:48] [INFO ] [main.c:311] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [12] Subscribe admin context: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1463] [didactyl] startup phase: subscribe admin context begin
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1777375788", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1777375788", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1777375788", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1777375788", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2703] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
[2026-04-28 07:29:48] [INFO ] [main.c:1467] [didactyl] startup phase: subscribe admin context end
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [12] Subscribe admin context: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [13] Subscribe agent self context: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1471] [didactyl] startup phase: subscribe agent self context begin
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1777375788", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1777375788", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1777375788", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1777375788", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2791] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:29:48] [INFO ] [main.c:1475] [didactyl] startup phase: subscribe agent self context end
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [13] Subscribe agent self context: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1479] [didactyl] startup phase: subscribe self skill cache begin
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2827] [didactyl] self-skill subscription filter: {"kinds":[31123,31124,10123],"authors":["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],"limit":300}
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1777375788", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1777375788", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1777375788", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1777375788", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2887] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b created_at=1777375787 via wss://relay.damus.io
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=dc138a7c573943b8... created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b created_at=1777375787 via wss://relay.primal.net
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=dc138a7c573943b8... created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=816>
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=78b0aaddaf99b7dc66a8094c036551a416542ef87e7701ef53a4efbfe5f2d85d created_at=1777375787 via wss://relay.damus.io
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=78b0aaddaf99b7dc... created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=818>
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=63ffd51f9c14691d8496ed68da75fdad71a6bd6f6a5669d023fd8dc0ad6771af created_at=1777375787 via wss://relay.primal.net
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=63ffd51f9c14691d... created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375787)
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1777375788"]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2070] [didactyl] self-skill EOSE received: cached skill events=0
[2026-04-28 07:29:48] [INFO ] [main.c:47] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:29:48] [INFO ] [trigger_manager.c:1039] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
[2026-04-28 07:29:48] [INFO ] [main.c:57] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=63ffd51f9c14691d8496ed68da75fdad71a6bd6f6a5669d023fd8dc0ad6771af created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=10123 d_tag=- id=dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b created_at=1777375787
[2026-04-28 07:29:48] [INFO ] [main.c:1546] [didactyl] startup phase: subscribe self skill cache end
[2026-04-28 07:29:48] [INFO ] [main.c:311] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [15] Subscribe DMs: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1550] [didactyl] startup phase: subscribe DMs begin
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:2905] [didactyl] DM subscribe: dm_protocol=2 need_kind4=1 need_kind1059=1 g_start_time=1777375785
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1777375788", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375785,
"limit": 100
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1777375788", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375785,
"limit": 100
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1777375788", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1777375788", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3000] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:3001] [didactyl] DEBUG DM subscription g_start_time=1777375785 now=1777375788 delta=3 relay_count=2
[2026-04-28 07:29:48] [INFO ] [main.c:1565] [didactyl] startup phase: subscribe DMs end
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [15] Subscribe DMs: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [16] Subscribe wallet events: begin
[2026-04-28 07:29:48] [INFO ] [main.c:1569] [didactyl] startup phase: subscribe wallet events begin
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1777375788", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375785,
"limit": 500
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1777375788", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375785,
"limit": 500
}]
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3053] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:29:48] [INFO ] [main.c:1573] [didactyl] startup phase: subscribe wallet events end
[2026-04-28 07:29:48] [INFO ] [main.c:314] [didactyl] startup checklist [16] Subscribe wallet events: ok
[2026-04-28 07:29:48] [INFO ] [main.c:304] [didactyl] startup checklist [17] Initialize cashu wallet: begin
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1777375788", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1777375788", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1777375788"]
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1777375788"]
[2026-04-28 07:29:48] [WARN ] [main.c:1589] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
[2026-04-28 07:29:48] [INFO ] [main.c:311] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
[2026-04-28 07:29:48] [INFO ] [http_api.c:1662] [didactyl] http api listening on http://127.0.0.1:8491
[2026-04-28 07:29:48] [INFO ] [main.c:1629] [didactyl] HTTP API listening at http://127.0.0.1:8491
[2026-04-28 07:29:48] [INFO ] [main.c:1632] [didactyl] HTTP API endpoints: http://127.0.0.1:8491/api/context/current http://127.0.0.1:8491/api/context/parts
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:1844] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-28 07:29:48 (version v0.2.48, connected relays: 2/2).
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:1836] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1777375788,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"LFGqdsk1HPY08BtLcfL6tfxlVqeG7laUblZvMP2ailVXIf8bOJPtjI+tZQnQTQp1uRhsxDDFfKZCaPaXB8KHwfjLMWiDdqU1TAFginaVtzmaR17KVPY3p3+id+gwjbNhdPVIHx+jBqAf54ER/H3wB8gyg35o1D4o3UH6fhPIvPM=?iv=69XXqTTdJgGC48Ivw3NUgw==","id":"4d4b2b6f443460a14310cf37d239f9c6ffb49499029fe5c32508278e5ce9367c","sig":"373445bfd668a547d25f59929f9dd1a624847ecdce579b430f4814926afb0d48ce42397a227cece59386bf6e5011132c2130c3aa397ce2cdb14b9614e6514c50"}
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:920] [didactyl] publish DM target relays (2):
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
[2026-04-28 07:29:48] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.damus.io (async)
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.primal.net (async)
[2026-04-28 07:29:48] [INFO ] [nostr_handler.c:3209] [didactyl] sent DM 4d4b2b6f443460a1... to 254d7a7f68b4443f... via 2 connected relay(s)
[2026-04-28 07:29:48] [INFO ] [main.c:311] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
[2026-04-28 07:29:48] [INFO ] [main.c:1668] [didactyl] entering main poll loop
[2026-04-28 07:29:48] [INFO ] [main.c:1669] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
[2026-04-28 07:29:49] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","4d4b2b6f443460a14310cf37d239f9c6ffb49499029fe5c32508278e5ce9367c",true,""]
[2026-04-28 07:29:49] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","4d4b2b6f443460a14310cf37d239f9c6ffb49499029fe5c32508278e5ce9367c",false,"rate-limited: you are noting too much"]
[2026-04-28 07:29:49] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=50875 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
[2026-04-28 07:29:54] [INFO ] [main.c:1691] [didactyl] shutting down
[2026-04-28 07:29:54] [INFO ] [trigger_manager.c:1734] [didactyl] trigger manager cleaned up
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1777375788"]
[2026-04-28 07:29:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1777375788"]
@@ -0,0 +1,57 @@
{
"run_meta": {
"run_timestamp": "2026-04-28T11:29:54.142514+00:00",
"base_url": "http://127.0.0.1:8491",
"config": "tests/results/20260428T112851Z/runtime_test_genesis.jsonc",
"binary": "didactyl",
"test_count": 4
},
"results": [
{
"suite": "test_conversation",
"name": "simple_greeting",
"status": "pass",
"message": "greeting response ok",
"duration_seconds": 4.47363213999779,
"agent_errors": [],
"details": {
"response": "Hello! I'm a Didactyl Agent - a test agent designed to help you with various tasks. I can assist with things like:\n\n- **Nostr protocol operations** (posting, querying events, managing profiles, etc.)\n"
}
},
{
"suite": "test_conversation",
"name": "agent_responds_about_itself",
"status": "pass",
"message": "self description ok",
"duration_seconds": 5.864955286990153,
"agent_errors": [],
"details": {
"response": "i'm **didactyl**, a nostr-native ai agent. here's what i do:\n\n**core identity:**\n- i'm an autonomous agent running on the nostr protocol, designed to interact with decentralized networks and handle bo"
}
},
{
"suite": "test_conversation",
"name": "empty_message_handling",
"status": "timeout",
"message": "timed out",
"duration_seconds": 43.47824207498343,
"agent_errors": [],
"details": {}
},
{
"suite": "test_conversation",
"name": "very_long_message",
"status": "pass",
"message": "long message handled",
"duration_seconds": 4.959190360998036,
"agent_errors": [],
"details": {
"success": true
}
}
],
"summary": {
"pass": 3,
"timeout": 1
}
}
@@ -0,0 +1,22 @@
== Didactyl Test Results ==
Run: 2026-04-28T11:29:54.142514+00:00
Agent base URL: http://127.0.0.1:8491
Pass: 3
Fail: 0
Error: 0
Timeout: 1
Skip: 0
Total: 4
[PASS] test_conversation::simple_greeting (4.47s)
greeting response ok
[PASS] test_conversation::agent_responds_about_itself (5.86s)
self description ok
[TIMEOUT] test_conversation::empty_message_handling (43.48s)
timed out
[PASS] test_conversation::very_long_message (4.96s)
long message handled
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,420 @@
[2026-04-28 07:31:29] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
[2026-04-28 07:31:29] [INFO ] [nostr_handler.c:2558] [didactyl] initializing relay pool with 2 relays
[2026-04-28 07:31:29] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.damus.io
[2026-04-28 07:31:29] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.primal.net
[2026-04-28 07:31:30] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1777375889", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1777375889", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1777375889"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1777375889"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1777375889"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1777375889"]
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [01] Relay connectivity: begin
[2026-04-28 07:31:31] [INFO ] [main.c:311] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1777375891", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1777375891", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1047>
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1045>
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1777375891"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1777375891"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1777375891"]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1777375891"]
[2026-04-28 07:31:31] [INFO ] [main.c:1007] [didactyl] startup phase: recovered user-settings from Nostr
[2026-04-28 07:31:31] [INFO ] [main.c:311] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok (user-settings recalled)
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [03] Validate LLM config: begin
[2026-04-28 07:31:31] [INFO ] [main.c:314] [didactyl] startup checklist [03] Validate LLM config: ok
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [04] Validate admin config: begin
[2026-04-28 07:31:31] [INFO ] [main.c:314] [didactyl] startup checklist [04] Validate admin config: ok
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [05] Initialize LLM client: begin
[2026-04-28 07:31:31] [INFO ] [main.c:314] [didactyl] startup checklist [05] Initialize LLM client: ok
[2026-04-28 07:31:31] [INFO ] [main.c:304] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1777375891", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:31] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1777375891", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1777375891"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1777375891"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1777375891"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1777375891"]
[2026-04-28 07:31:32] [INFO ] [main.c:1337] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
[2026-04-28 07:31:32] [INFO ] [main.c:311] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1777375892", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1777375892", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=3fe6071b53da897c... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=b479ae241442d8a9... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=827>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=8837248dc5163739... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=be5d4be2386c8715... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1657] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=3fe6071b53da897c... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=b479ae241442d8a9... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=829>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=0ad4dcde6efcb420... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375892)
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=be5d4be2386c8715... created_at=1777375892
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375892)
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:3676] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
[2026-04-28 07:31:32] [INFO ] [main.c:937] [didactyl] startup phase: skipping user-settings publish because runtime config was recalled from Nostr
[2026-04-28 07:31:32] [INFO ] [main.c:1361] [didactyl] startup phase: persisted encrypted runtime config to Nostr
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [08] Initialize agent: begin
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1777375892", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1777375892", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","3fe6071b53da897c7a173d4ee4d9ed03b969fb476a8f7f9a7a50f131f475d1ee",true,""]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b479ae241442d8a9457fd83cef39b269e7415c22963dbde30d2ebb79c36ef4c0",false,"rate-limited: you are noting too much"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b479ae241442d8a9457fd83cef39b269e7415c22963dbde30d2ebb79c36ef4c0",true,""]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","3fe6071b53da897c7a173d4ee4d9ed03b969fb476a8f7f9a7a50f131f475d1ee",true,""]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=824>
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","8837248dc5163739b290229b0bfbc1bd6e171863d2d9afa300e97ce327fbd578",false,"rate-limited: you are noting too much"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","be5d4be2386c8715d0a548b725f2df3e075775913c991f84f3ca513d7360ac48",false,"rate-limited: you are noting too much"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","0ad4dcde6efcb420185e65ef1758654e79381c5c32982027b590ac5c76655dbb",true,""]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","be5d4be2386c8715d0a548b725f2df3e075775913c991f84f3ca513d7360ac48",true,""]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1777375892"]
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [08] Initialize agent: ok
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [09] Initialize trigger manager: begin
[2026-04-28 07:31:32] [INFO ] [trigger_manager.c:935] [didactyl] trigger manager initialized (capacity=16)
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [09] Initialize trigger manager: ok
[2026-04-28 07:31:32] [INFO ] [main.c:1405] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [10] Load startup triggers: begin
[2026-04-28 07:31:32] [INFO ] [main.c:1408] [didactyl] startup phase: startup-config trigger load begin
[2026-04-28 07:31:32] [INFO ] [trigger_manager.c:1259] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:31:32] [INFO ] [trigger_manager.c:1142] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:31:32] [INFO ] [trigger_manager.c:1150] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
[2026-04-28 07:31:32] [INFO ] [main.c:1412] [didactyl] startup phase: startup-config trigger load end
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [10] Load startup triggers: ok
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
[2026-04-28 07:31:32] [INFO ] [main.c:383] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
[2026-04-28 07:31:32] [INFO ] [main.c:390] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":4,"events_published_ok":1,"events_published_failed":3,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375889,"last_event_time":1777375892,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375889,"last_event_time":1777375892}]}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1777375892", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1777375892", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1777375892"]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1777375892"]
[2026-04-28 07:31:32] [INFO ] [main.c:410] [didactyl] kind10002 query received event_count=2
[2026-04-28 07:31:32] [INFO ] [main.c:507] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
[2026-04-28 07:31:32] [INFO ] [main.c:612] [didactyl] kind10002 wait success: relay_count=2
[2026-04-28 07:31:32] [INFO ] [main.c:614] [didactyl] kind10002 relay[0]=wss://relay.damus.io
[2026-04-28 07:31:32] [INFO ] [main.c:614] [didactyl] kind10002 relay[1]=wss://relay.primal.net
[2026-04-28 07:31:32] [INFO ] [main.c:618] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":2,"events_published":4,"events_published_ok":1,"events_published_failed":3,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375889,"last_event_time":1777375892,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777375889,"last_event_time":1777375892}]}
[2026-04-28 07:31:32] [INFO ] [main.c:311] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [12] Subscribe admin context: begin
[2026-04-28 07:31:32] [INFO ] [main.c:1463] [didactyl] startup phase: subscribe admin context begin
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1777375892", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1777375892", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1777375892", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1777375892", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:2703] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
[2026-04-28 07:31:32] [INFO ] [main.c:1467] [didactyl] startup phase: subscribe admin context end
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [12] Subscribe admin context: ok
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [13] Subscribe agent self context: begin
[2026-04-28 07:31:32] [INFO ] [main.c:1471] [didactyl] startup phase: subscribe agent self context begin
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1777375892", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1777375892", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1777375892", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1777375892", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:2791] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:31:32] [INFO ] [main.c:1475] [didactyl] startup phase: subscribe agent self context end
[2026-04-28 07:31:32] [INFO ] [main.c:314] [didactyl] startup checklist [13] Subscribe agent self context: ok
[2026-04-28 07:31:32] [INFO ] [main.c:304] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
[2026-04-28 07:31:32] [INFO ] [main.c:1479] [didactyl] startup phase: subscribe self skill cache begin
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:2827] [didactyl] self-skill subscription filter: {"kinds":[31123,31124,10123],"authors":["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],"limit":300}
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1777375892", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1777375892", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1777375892", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:31:32] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1777375892", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:31:32] [INFO ] [nostr_handler.c:2887] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=dc138a7c573943b81100e3d41471840a3bfa6bc662809fc30b47af87276aa54b created_at=1777375787 via wss://relay.damus.io
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=dc138a7c573943b8... created_at=1777375787
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777375892 >= new created_at=1777375787)
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=816>
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=78b0aaddaf99b7dc66a8094c036551a416542ef87e7701ef53a4efbfe5f2d85d created_at=1777375787 via wss://relay.damus.io
[2026-04-28 07:31:33] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=78b0aaddaf99b7dc... created_at=1777375787
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777375892 >= new created_at=1777375787)
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=be5d4be2386c8715d0a548b725f2df3e075775913c991f84f3ca513d7360ac48 created_at=1777375892 via wss://relay.primal.net
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=be5d4be2386c8715... created_at=1777375892
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375892)
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=818>
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=0ad4dcde6efcb420185e65ef1758654e79381c5c32982027b590ac5c76655dbb created_at=1777375892 via wss://relay.primal.net
[2026-04-28 07:31:33] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=0ad4dcde6efcb420... created_at=1777375892
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777375892)
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1777375892"]
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2070] [didactyl] self-skill EOSE received: cached skill events=0
[2026-04-28 07:31:33] [INFO ] [main.c:47] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
[2026-04-28 07:31:33] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:31:33] [INFO ] [trigger_manager.c:1039] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
[2026-04-28 07:31:33] [INFO ] [main.c:57] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=0ad4dcde6efcb420185e65ef1758654e79381c5c32982027b590ac5c76655dbb created_at=1777375892
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=10123 d_tag=- id=be5d4be2386c8715d0a548b725f2df3e075775913c991f84f3ca513d7360ac48 created_at=1777375892
[2026-04-28 07:31:33] [INFO ] [main.c:1546] [didactyl] startup phase: subscribe self skill cache end
[2026-04-28 07:31:33] [INFO ] [main.c:311] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
[2026-04-28 07:31:33] [INFO ] [main.c:304] [didactyl] startup checklist [15] Subscribe DMs: begin
[2026-04-28 07:31:33] [INFO ] [main.c:1550] [didactyl] startup phase: subscribe DMs begin
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:2905] [didactyl] DM subscribe: dm_protocol=2 need_kind4=1 need_kind1059=1 g_start_time=1777375889
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1777375893", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375889,
"limit": 100
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1777375893", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375889,
"limit": 100
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1777375893", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1777375893", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3000] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:3001] [didactyl] DEBUG DM subscription g_start_time=1777375889 now=1777375893 delta=4 relay_count=2
[2026-04-28 07:31:33] [INFO ] [main.c:1565] [didactyl] startup phase: subscribe DMs end
[2026-04-28 07:31:33] [INFO ] [main.c:314] [didactyl] startup checklist [15] Subscribe DMs: ok
[2026-04-28 07:31:33] [INFO ] [main.c:304] [didactyl] startup checklist [16] Subscribe wallet events: begin
[2026-04-28 07:31:33] [INFO ] [main.c:1569] [didactyl] startup phase: subscribe wallet events begin
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1777375893", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375889,
"limit": 500
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1777375893", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777375889,
"limit": 500
}]
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3053] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:31:33] [INFO ] [main.c:1573] [didactyl] startup phase: subscribe wallet events end
[2026-04-28 07:31:33] [INFO ] [main.c:314] [didactyl] startup checklist [16] Subscribe wallet events: ok
[2026-04-28 07:31:33] [INFO ] [main.c:304] [didactyl] startup checklist [17] Initialize cashu wallet: begin
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1777375893", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1777375893", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1777375892"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1777375893"]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1777375893"]
[2026-04-28 07:31:33] [WARN ] [main.c:1589] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
[2026-04-28 07:31:33] [INFO ] [main.c:311] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
[2026-04-28 07:31:33] [INFO ] [http_api.c:1662] [didactyl] http api listening on http://127.0.0.1:8492
[2026-04-28 07:31:33] [INFO ] [main.c:1629] [didactyl] HTTP API listening at http://127.0.0.1:8492
[2026-04-28 07:31:33] [INFO ] [main.c:1632] [didactyl] HTTP API endpoints: http://127.0.0.1:8492/api/context/current http://127.0.0.1:8492/api/context/parts
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:1844] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-28 07:31:33 (version v0.2.48, connected relays: 2/2).
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:1836] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1777375893,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"Okz4VaTNjFWFv/ege6fWWTOq6Vn+A4xlLURHP+qvNO6kRfdZrIEToVeBqJnMWtx9IzuFeB3fBK4qzxs74ANTn0aFNwD4mDetdRD0/TcDU8zSgwOV5D6FgIWk64aR0xvQ3beE9Fbq0PXezu8DwvfjvtKBqsasqhQ3PJWhPUi4kLY=?iv=UIBiCRfNQRnh4TN4zU02/w==","id":"2bd1a4c12247eee64f0a8e0f6ae2f663c78ba357c42768a8311e0e066c549502","sig":"eae6b86703c549c6bb1f567add1b411c8db5b84c18a3659ff929c2fc6cb2d4aa13be36d8e48106fd72675d67adc591e0872ab11a1f78b604e7fd5e571d109c15"}
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:920] [didactyl] publish DM target relays (2):
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.damus.io (async)
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.primal.net (async)
[2026-04-28 07:31:33] [INFO ] [nostr_handler.c:3209] [didactyl] sent DM 2bd1a4c12247eee6... to 254d7a7f68b4443f... via 2 connected relay(s)
[2026-04-28 07:31:33] [INFO ] [main.c:311] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
[2026-04-28 07:31:33] [INFO ] [main.c:1668] [didactyl] entering main poll loop
[2026-04-28 07:31:33] [INFO ] [main.c:1669] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","2bd1a4c12247eee64f0a8e0f6ae2f663c78ba357c42768a8311e0e066c549502",true,""]
[2026-04-28 07:31:33] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","2bd1a4c12247eee64f0a8e0f6ae2f663c78ba357c42768a8311e0e066c549502",false,"rate-limited: you are noting too much"]
[2026-04-28 07:31:33] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=50875 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
[2026-04-28 07:31:37] [INFO ] [main.c:1691] [didactyl] shutting down
[2026-04-28 07:31:37] [INFO ] [trigger_manager.c:1734] [didactyl] trigger manager cleaned up
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1777375892"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1777375893"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1777375893"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1777375893"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1777375893"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1777375893"]
[2026-04-28 07:31:37] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1777375893"]
@@ -0,0 +1,57 @@
{
"run_meta": {
"run_timestamp": "2026-04-28T11:31:37.668616+00:00",
"base_url": "http://127.0.0.1:8492",
"config": "tests/results/20260428T113005Z/runtime_test_genesis.jsonc",
"binary": "didactyl",
"test_count": 4
},
"results": [
{
"suite": "test_conversation",
"name": "simple_greeting",
"status": "pass",
"message": "greeting response ok",
"duration_seconds": 3.2006136770069133,
"agent_errors": [],
"details": {
"response": "Hello! I'm a test agent powered by Didactyl. I don't have a specific personal name, but you can think of me as your Didactyl assistant. I'm here to help you with various tasks using the tools and capa"
}
},
{
"suite": "test_conversation",
"name": "agent_responds_about_itself",
"status": "pass",
"message": "self description ok",
"duration_seconds": 6.3043079580238555,
"agent_errors": [],
"details": {
"response": "i'm **didactyl**, a nostr-based ai agent. here's a brief description of what i am:\n\n## core identity\n- a decentralized autonomous agent that operates on the nostr protocol\n- i can publish, query, and "
}
},
{
"suite": "test_conversation",
"name": "empty_message_handling",
"status": "timeout",
"message": "timed out",
"duration_seconds": 74.4663479780138,
"agent_errors": [],
"details": {}
},
{
"suite": "test_conversation",
"name": "very_long_message",
"status": "pass",
"message": "long message handled",
"duration_seconds": 4.021215749002295,
"agent_errors": [],
"details": {
"success": true
}
}
],
"summary": {
"pass": 3,
"timeout": 1
}
}
@@ -0,0 +1,22 @@
== Didactyl Test Results ==
Run: 2026-04-28T11:31:37.668616+00:00
Agent base URL: http://127.0.0.1:8492
Pass: 3
Fail: 0
Error: 0
Timeout: 1
Skip: 0
Total: 4
[PASS] test_conversation::simple_greeting (3.20s)
greeting response ok
[PASS] test_conversation::agent_responds_about_itself (6.30s)
self description ok
[TIMEOUT] test_conversation::empty_message_handling (74.47s)
timed out
[PASS] test_conversation::very_long_message (4.02s)
long message handled
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,420 @@
[2026-04-28 07:33:54] [INFO ] [main.c:1103] Didactyl v0.2.48 starting
[2026-04-28 07:33:54] [INFO ] [nostr_handler.c:2558] [didactyl] initializing relay pool with 2 relays
[2026-04-28 07:33:54] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.damus.io
[2026-04-28 07:33:54] [INFO ] [nostr_handler.c:2582] [didactyl] added relay: wss://relay.primal.net
[2026-04-28 07:33:54] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1777376034", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1777376034", {
"kinds": [10000],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1777376034"]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1777376034"]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1777376034"]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1777376034"]
[2026-04-28 07:33:55] [INFO ] [main.c:304] [didactyl] startup checklist [01] Relay connectivity: begin
[2026-04-28 07:33:55] [INFO ] [main.c:311] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
[2026-04-28 07:33:55] [INFO ] [main.c:304] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1777376035", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1777376035", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["user-settings"],
"limit": 20
}]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1047>
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1777376035"]
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=1045>
[2026-04-28 07:33:55] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1777376035"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1777376035"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1777376035"]
[2026-04-28 07:33:56] [INFO ] [main.c:1007] [didactyl] startup phase: recovered user-settings from Nostr
[2026-04-28 07:33:56] [INFO ] [main.c:311] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok (user-settings recalled)
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [03] Validate LLM config: begin
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [03] Validate LLM config: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [04] Validate admin config: begin
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [04] Validate admin config: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [05] Initialize LLM client: begin
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [05] Initialize LLM client: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1777376036", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1777376036", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1777376036"]
[2026-04-28 07:33:56] [INFO ] [main.c:1337] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
[2026-04-28 07:33:56] [INFO ] [main.c:311] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1777376036", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1777376036", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=5b81d0953899e3a9... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=fba0d939f4f65546... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=827>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=7e0b33e002ab60a7... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b92a83c390fd9778... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1645] [didactyl] self-skill upsert accepted: new entry added
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1657] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=0 author=1eb171136dbb1ba6... id=5b81d0953899e3a9... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10002 author=1eb171136dbb1ba6... id=fba0d939f4f65546... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1540] [didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=829>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=af34bcfae6b03bbd... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777376036)
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3323] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b92a83c390fd9778... created_at=1777376036
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777376036)
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3664] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
[2026-04-28 07:33:56] [INFO ] [nostr_handler.c:3676] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
[2026-04-28 07:33:56] [INFO ] [main.c:937] [didactyl] startup phase: skipping user-settings publish because runtime config was recalled from Nostr
[2026-04-28 07:33:56] [INFO ] [main.c:1361] [didactyl] startup phase: persisted encrypted runtime config to Nostr
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [08] Initialize agent: begin
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1777376036", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1777376036", {
"kinds": [30078],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"#d": ["memory"],
"limit": 1
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","5b81d0953899e3a93924791661281c26127575ad0469a818c0efdc4d1d7aa824",true,""]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","fba0d939f4f655465a2b4aed4ec8ed0b6f3780137874881f0715d10647c90c7a",false,"rate-limited: you are noting too much"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","fba0d939f4f655465a2b4aed4ec8ed0b6f3780137874881f0715d10647c90c7a",true,""]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","5b81d0953899e3a93924791661281c26127575ad0469a818c0efdc4d1d7aa824",true,""]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=824>
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1777376036"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1777376036"]
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [08] Initialize agent: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [09] Initialize trigger manager: begin
[2026-04-28 07:33:56] [INFO ] [trigger_manager.c:935] [didactyl] trigger manager initialized (capacity=16)
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [09] Initialize trigger manager: ok
[2026-04-28 07:33:56] [INFO ] [main.c:1405] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [10] Load startup triggers: begin
[2026-04-28 07:33:56] [INFO ] [main.c:1408] [didactyl] startup phase: startup-config trigger load begin
[2026-04-28 07:33:56] [INFO ] [trigger_manager.c:1259] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:33:56] [INFO ] [trigger_manager.c:1142] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:33:56] [INFO ] [trigger_manager.c:1150] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
[2026-04-28 07:33:56] [INFO ] [main.c:1412] [didactyl] startup phase: startup-config trigger load end
[2026-04-28 07:33:56] [INFO ] [main.c:314] [didactyl] startup checklist [10] Load startup triggers: ok
[2026-04-28 07:33:56] [INFO ] [main.c:304] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
[2026-04-28 07:33:56] [INFO ] [main.c:383] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
[2026-04-28 07:33:56] [INFO ] [main.c:390] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":4,"events_published_ok":1,"events_published_failed":1,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777376034,"last_event_time":1777376036,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":4,"events_published_ok":2,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777376034,"last_event_time":1777376036}]}
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1777376036", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1777376036", {
"kinds": [10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 16
}]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","7e0b33e002ab60a76e630503ab86ce56a6e27c75f07c17d3f359c24a7233a5d2",false,"rate-limited: you are noting too much"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","af34bcfae6b03bbdabc704228be682239cf327cc2ffc2dbf4f95d58e227310ae",true,""]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b92a83c390fd97786654c10249b1a4f48b6a53cab4ad448833341ce3433b57ce",false,"rate-limited: you are noting too much"]
[2026-04-28 07:33:56] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b92a83c390fd97786654c10249b1a4f48b6a53cab4ad448833341ce3433b57ce",true,""]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1777376036"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1777376036"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1777376036"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1777376036"]
[2026-04-28 07:33:57] [INFO ] [main.c:410] [didactyl] kind10002 query received event_count=2
[2026-04-28 07:33:57] [INFO ] [main.c:507] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
[2026-04-28 07:33:57] [INFO ] [main.c:612] [didactyl] kind10002 wait success: relay_count=2
[2026-04-28 07:33:57] [INFO ] [main.c:614] [didactyl] kind10002 relay[0]=wss://relay.damus.io
[2026-04-28 07:33:57] [INFO ] [main.c:614] [didactyl] kind10002 relay[1]=wss://relay.primal.net
[2026-04-28 07:33:57] [INFO ] [main.c:618] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":4,"events_published_ok":1,"events_published_failed":3,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777376034,"last_event_time":1777376036,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":4,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1777376034,"last_event_time":1777376036}]}
[2026-04-28 07:33:57] [INFO ] [main.c:311] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [12] Subscribe admin context: begin
[2026-04-28 07:33:57] [INFO ] [main.c:1463] [didactyl] startup phase: subscribe admin context begin
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1777376037", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1777376037", {
"kinds": [0, 3, 10002],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 32
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1777376037", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1777376037", {
"kinds": [1],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 10
}]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2703] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
[2026-04-28 07:33:57] [INFO ] [main.c:1467] [didactyl] startup phase: subscribe admin context end
[2026-04-28 07:33:57] [INFO ] [main.c:314] [didactyl] startup checklist [12] Subscribe admin context: ok
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [13] Subscribe agent self context: begin
[2026-04-28 07:33:57] [INFO ] [main.c:1471] [didactyl] startup phase: subscribe agent self context begin
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1777376037", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1777376037", {
"kinds": [0, 3, 10002],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 64
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1777376037", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1777376037", {
"kinds": [1],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 10
}]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2791] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:33:57] [INFO ] [main.c:1475] [didactyl] startup phase: subscribe agent self context end
[2026-04-28 07:33:57] [INFO ] [main.c:314] [didactyl] startup checklist [13] Subscribe agent self context: ok
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
[2026-04-28 07:33:57] [INFO ] [main.c:1479] [didactyl] startup phase: subscribe self skill cache begin
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2827] [didactyl] self-skill subscription filter: {"kinds":[31123,31124,10123],"authors":["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],"limit":300}
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1777376037", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1777376037", {
"kinds": [31123, 31124, 10123],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 300
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1777376037", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1777376037", {
"kinds": [31123],
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
"limit": 150
}]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2887] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=4949970fdf8382fa8a44ec78d9d37a77713df7e20121f7f1d49520829aef8165 created_at=1777376025 via wss://relay.damus.io
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=4949970fdf8382fa... created_at=1777376025
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777376036 >= new created_at=1777376025)
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=816>
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=91d20999ae0370494c7a7d789aef531cc80b85758175f5e16ac703d0c66ba56b created_at=1777376025 via wss://relay.damus.io
[2026-04-28 07:33:57] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=91d20999ae037049... created_at=1777376025
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1609] [didactyl] self-skill upsert rejected: stale (existing created_at=1777376036 >= new created_at=1777376025)
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=10123 d_tag=- id=b92a83c390fd97786654c10249b1a4f48b6a53cab4ad448833341ce3433b57ce created_at=1777376036 via wss://relay.primal.net
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=10123 author=1eb171136dbb1ba6... id=b92a83c390fd9778... created_at=1777376036
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777376036)
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1634] [didactyl] kind 10123 accepted with 1 'a' tags
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=818>
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2500] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=af34bcfae6b03bbdabc704228be682239cf327cc2ffc2dbf4f95d58e227310ae created_at=1777376036 via wss://relay.primal.net
[2026-04-28 07:33:57] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1502] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1526] [didactyl] self-skill upsert candidate: kind=31124 author=1eb171136dbb1ba6... id=af34bcfae6b03bbd... created_at=1777376036
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:1622] [didactyl] self-skill upsert accepted: replaced existing (old created_at=1777376036)
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1777376037"]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2070] [didactyl] self-skill EOSE received: cached skill events=0
[2026-04-28 07:33:57] [INFO ] [main.c:47] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
[2026-04-28 07:33:57] [INFO ] [trigger_manager.c:1485] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
[2026-04-28 07:33:57] [INFO ] [trigger_manager.c:1039] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
[2026-04-28 07:33:57] [INFO ] [main.c:57] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=af34bcfae6b03bbdabc704228be682239cf327cc2ffc2dbf4f95d58e227310ae created_at=1777376036
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3114] [didactyl] self-skill cache event: kind=10123 d_tag=- id=b92a83c390fd97786654c10249b1a4f48b6a53cab4ad448833341ce3433b57ce created_at=1777376036
[2026-04-28 07:33:57] [INFO ] [main.c:1546] [didactyl] startup phase: subscribe self skill cache end
[2026-04-28 07:33:57] [INFO ] [main.c:311] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [15] Subscribe DMs: begin
[2026-04-28 07:33:57] [INFO ] [main.c:1550] [didactyl] startup phase: subscribe DMs begin
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:2905] [didactyl] DM subscribe: dm_protocol=2 need_kind4=1 need_kind1059=1 g_start_time=1777376034
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1777376037", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777376034,
"limit": 100
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1777376037", {
"kinds": [4],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777376034,
"limit": 100
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1777376037", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1777376037", {
"kinds": [1059],
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"limit": 400
}]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3000] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:3001] [didactyl] DEBUG DM subscription g_start_time=1777376034 now=1777376037 delta=3 relay_count=2
[2026-04-28 07:33:57] [INFO ] [main.c:1565] [didactyl] startup phase: subscribe DMs end
[2026-04-28 07:33:57] [INFO ] [main.c:314] [didactyl] startup checklist [15] Subscribe DMs: ok
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [16] Subscribe wallet events: begin
[2026-04-28 07:33:57] [INFO ] [main.c:1569] [didactyl] startup phase: subscribe wallet events begin
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1777376037", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777376034,
"limit": 500
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1777376037", {
"kinds": [17375, 7375, 5],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
"since": 1777376034,
"limit": 500
}]
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3053] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
[2026-04-28 07:33:57] [INFO ] [main.c:1573] [didactyl] startup phase: subscribe wallet events end
[2026-04-28 07:33:57] [INFO ] [main.c:314] [didactyl] startup checklist [16] Subscribe wallet events: ok
[2026-04-28 07:33:57] [INFO ] [main.c:304] [didactyl] startup checklist [17] Initialize cashu wallet: begin
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1777376037", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1777376037", {
"kinds": [17375, 7375],
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
}]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:2063] [didactyl] DEBUG on_eose called: event_count=0
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1777376037"]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1777376037"]
[2026-04-28 07:33:57] [WARN ] [main.c:1589] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
[2026-04-28 07:33:57] [INFO ] [main.c:311] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
[2026-04-28 07:33:57] [INFO ] [http_api.c:1662] [didactyl] http api listening on http://127.0.0.1:8495
[2026-04-28 07:33:57] [INFO ] [main.c:1629] [didactyl] HTTP API listening at http://127.0.0.1:8495
[2026-04-28 07:33:57] [INFO ] [main.c:1632] [didactyl] HTTP API endpoints: http://127.0.0.1:8495/api/context/current http://127.0.0.1:8495/api/context/parts
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:1844] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-28 07:33:57 (version v0.2.48, connected relays: 2/2).
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:1836] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1777376037,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"4p/sJF1duSvs+UYfkSCgqI1Kh5THpuvq9LdjqG3QIqEM2815CGdjDJNU4vC008/hOGPQ0DOgQCJzwWpVUOdk1o4jYPMTfy4Dhx/h6G6rIVyPeUXZM0ChwueW3pijjBaZZFncCbFkP5TUV/bIfmBFNSe2L8RPyPMTkJvdl3lid80=?iv=XxaWd5flFRnNVMHxLKvoMw==","id":"1cc56bcf91cb665579cc89b38229097826ea5bc548a7823d123968cb2458cebe","sig":"3c87772d5063f753f6c6dc03f080a9540e749a1a6e3d601e6d209fad757528449932cd36572907ed7d1159596d4f481f5f46432521861c5524f94c3af08d5ec2"}
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:920] [didactyl] publish DM target relays (2):
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.damus.io
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:922] [didactyl] -> wss://relay.primal.net
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:176] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.damus.io (async)
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3200] [didactyl] kind 4 event published to wss://relay.primal.net (async)
[2026-04-28 07:33:57] [INFO ] [nostr_handler.c:3209] [didactyl] sent DM 1cc56bcf91cb6655... to 254d7a7f68b4443f... via 2 connected relay(s)
[2026-04-28 07:33:57] [INFO ] [main.c:311] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
[2026-04-28 07:33:57] [INFO ] [main.c:1668] [didactyl] entering main poll loop
[2026-04-28 07:33:57] [INFO ] [main.c:1669] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","1cc56bcf91cb665579cc89b38229097826ea5bc548a7823d123968cb2458cebe",true,""]
[2026-04-28 07:33:57] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","1cc56bcf91cb665579cc89b38229097826ea5bc548a7823d123968cb2458cebe",false,"rate-limited: you are noting too much"]
[2026-04-28 07:33:59] [INFO ] [llm.c:125] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=30927 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Say hello in one sentence."},{"role":"user","content":"Say hello in one sentence.","_ts":1777376039}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr_react","description":"React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)","parameters":{"type":"object","properties":{"event_id":{"type":"string","description":"Target event ID to react to"},"event_pubkey":{"type":"string","description":"Author pubkey of target event"},"event_kind":{"type":"integer","description":"Optional kind of target event"},"reaction":{"type":"string","description":"Reaction content such as +, -, ❤️, or emoji"}},"required":["event_id","event_pubkey"]}}},{"type":"function","function":{"name":"nostr_profile_get","description":"Look up a Nostr profile (kind 0 metadata) by pubkey","parameters":{"type":"object","properties":{"pubkey":{"type":"string","description":"Hex pubkey of the profile to fetch"}},"required":["pub...
[2026-04-28 07:34:02] [INFO ] [main.c:1691] [didactyl] shutting down
[2026-04-28 07:34:02] [INFO ] [trigger_manager.c:1734] [didactyl] trigger manager cleaned up
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1777376037"]
[2026-04-28 07:34:02] [TRACE] [nostr_handler.c:183] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1777376037"]
+100
View File
@@ -0,0 +1,100 @@
{
"run_meta": {
"run_timestamp": "2026-04-28T11:34:02.786131+00:00",
"base_url": "http://127.0.0.1:8495",
"config": "tests/results/20260428T113354Z/runtime_test_genesis.jsonc",
"binary": "didactyl",
"test_count": 7
},
"results": [
{
"suite": "test_health",
"name": "status_returns_200",
"status": "pass",
"message": "status success",
"duration_seconds": 0.32880259698140435,
"agent_errors": [],
"details": {
"keys": [
"success",
"name",
"version",
"pubkey",
"relay_count",
"connected_relays",
"active_triggers"
]
}
},
{
"suite": "test_health",
"name": "status_has_fields",
"status": "pass",
"message": "required fields present",
"duration_seconds": 0.33118895199731924,
"agent_errors": [],
"details": {}
},
{
"suite": "test_health",
"name": "context_current_returns_messages",
"status": "pass",
"message": "context current ok",
"duration_seconds": 0.3325634880166035,
"agent_errors": [],
"details": {
"message_count": 2
}
},
{
"suite": "test_health",
"name": "context_parts_has_system_prompt",
"status": "pass",
"message": "context parts ok",
"duration_seconds": 0.3308573659742251,
"agent_errors": [],
"details": {
"parts": [
"system_prompt",
"dm_history"
]
}
},
{
"suite": "test_timeouts",
"name": "response_within_timeout",
"status": "pass",
"message": "response within timeout",
"duration_seconds": 2.608836165018147,
"agent_errors": [],
"details": {
"elapsed": 2.6088266609876882
}
},
{
"suite": "test_timeouts",
"name": "status_responds_fast",
"status": "pass",
"message": "status fast",
"duration_seconds": 0.3307172780041583,
"agent_errors": [],
"details": {
"elapsed": 0.3307107430009637
}
},
{
"suite": "test_timeouts",
"name": "context_responds_fast",
"status": "pass",
"message": "context fast",
"duration_seconds": 0.33165748399915174,
"agent_errors": [],
"details": {
"elapsed": 0.33165288498275913
}
}
],
"summary": {
"pass": 7
}
}
@@ -0,0 +1,31 @@
== Didactyl Test Results ==
Run: 2026-04-28T11:34:02.786131+00:00
Agent base URL: http://127.0.0.1:8495
Pass: 7
Fail: 0
Error: 0
Timeout: 0
Skip: 0
Total: 7
[PASS] test_health::status_returns_200 (0.33s)
status success
[PASS] test_health::status_has_fields (0.33s)
required fields present
[PASS] test_health::context_current_returns_messages (0.33s)
context current ok
[PASS] test_health::context_parts_has_system_prompt (0.33s)
context parts ok
[PASS] test_timeouts::response_within_timeout (2.61s)
response within timeout
[PASS] test_timeouts::status_responds_fast (0.33s)
status fast
[PASS] test_timeouts::context_responds_fast (0.33s)
context fast
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}
@@ -0,0 +1,59 @@
{
// TEST CONFIGURATION
// Use disposable keys/accounts only.
"key": {
"nsec": "nsec1REPLACE_WITH_DISPOSABLE_TEST_NSEC"
},
"admin": {
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
},
"llm": {
"provider": "https://api.ppq.ai",
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
"model": "claude-haiku-4.5",
"base_url": "https://api.ppq.ai",
"max_tokens": 10000,
"temperature": 0.7
},
"api": {
"enabled": true,
"port": 8485,
"bind_address": "127.0.0.1"
},
"encrypted_events": [
{
"kind": 30078,
"d_tag": "user-settings",
"content": "{\"v\":2,\"updatedAt\":0,\"global_llm\":{\"provider\":\"https://api.ppq.ai\",\"api_key\":\"sk-SBI2Pga0J6n8jpPorHbRHC\",\"model\":\"claude-haiku-4.5\",\"base_url\":\"https://api.ppq.ai\",\"max_tokens\":10000,\"temperature\":0.7},\"didactyl\":{\"admin_pubkey\":\"254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac\",\"dm_protocol\":\"both\",\"max_turns\":40}}"
}
],
"startup_events": [
{
"kind": 0,
"content_fields": {
"name": "Didactyl Test Agent",
"about": "Automated test instance"
},
"tags": []
},
{
"kind": 10002,
"content": "",
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://relay.primal.net"]
]
},
{
"kind": 31124,
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
"tags": [
["d", "identity_and_rules"],
["app", "didactyl"],
["scope", "private"],
["trigger", "dm"],
["filter", "{\"from\":\"admin\"}"]
]
}
]
}