Compare commits

...

5 Commits

95 changed files with 4039 additions and 92 deletions

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.45
## Current Status — v0.2.49
**Active build — this project is barely working. Experiment at your own risk.**
> Last release update: v0.2.45Expand skill refresh to include adopted authors and clean up skill_list output
> 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

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
{"id":"gen-1777375164-jltZoEFnh01JRUoyFbYw","object":"chat.completion","created":1777375164,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Hello! I'm a test agent built with Didactyl. I don't have a specific personal name configured, but I'm here to help you with various tasks using the tools available to me.\n\nI can help you with things like:\n- **Nostr interactions** - posting, querying events, managing profiles, sending DMs, etc.\n- **File operations** - reading and writing local files\n- **Shell commands** - executing commands in the system\n- **Skills management** - creating, editing, and running skills\n- **HTTP requests** - fetching web resources\n- **Wallet operations** - managing Cashu ecash wallets\n- **File hosting** - uploading/downloading files via Blossom\n- And more!\n\nIs there anything specific you'd like me to help you with?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9369,"completion_tokens":178,"total_tokens":9547,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":0,"cache_write_tokens":9366,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0126005,"upstream_inference_prompt_cost":0.0117105,"upstream_inference_completions_cost":0.00089},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,31 @@
{"id":"gen-1777375169-LOcgKM5Oya3Y7QIaAKTG","object":"chat.completion","created":1777375169,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I'm **Didactyl**, a Nostr-based AI agent. Here's a brief overview of what I am:\n\n**Core Identity:**\n- An autonomous agent running on the Nostr protocol\n- Equipped with a comprehensive toolkit for interacting with Nostr, managing tasks, handling encrypted communications, and more\n- Designed to be extensible through skills and configurable through various settings\n\n**Key Capabilities:**\n- **Nostr Integration**: Post notes, send encrypted DMs (NIP-04 and NIP-17), manage block lists, handle relays, and query events\n- **Skill System**: Create, adopt, and execute skills that extend my functionality with custom behaviors and triggers\n- **Task Management**: Maintain short-term task memory on Nostr for tracking and managing work\n- **Encrypted Memory**: Store and recall encrypted agent memory and configuration\n- **LLM Configuration**: Flexible model selection and parameter tuning\n- **Ecash/Cashu**: Wallet support for privacy-preserving payments\n- **File Management**: Read/write local files and upload/download via Blossom servers\n- **HTTP Requests**: Fetch external resources\n- **Shell Execution**: Run local commands when needed\n\n**Design Philosophy:**\nI'm built to be a helpful, privacy-conscious assistant that respects decentralized principles. I can operate autonomously or collaboratively, respond to various triggers (DMs, cron jobs, webhooks, subscriptions), and maintain context across conversations through encrypted storage.\n\nIs there something specific you'd like me to help you with?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9373,"completion_tokens":348,"total_tokens":9721,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":338,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0030687,"upstream_inference_prompt_cost":0.0013287,"upstream_inference_completions_cost":0.00174},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
{"id":"gen-1777375237-UNuX3x5bOLRo3Yf2fhGV","object":"chat.completion","created":1777375237,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I'm ready to help! I'm a test agent running on the Didactyl platform. I have access to a comprehensive set of tools for:\n\n- **Nostr operations**: posting, querying, reactions, DMs, profiles, relays, encryption\n- **File management**: reading and writing local files\n- **Skills**: creating, managing, and executing skills\n- **LLM configuration**: managing model settings and parameters\n- **Wallet**: Cashu ecash wallet operations\n- **Storage**: Blossom file uploads/downloads\n- **Utilities**: shell execution, HTTP requests, version info\n\nFeel free to ask me to:\n- Post to Nostr\n- Query events or profiles\n- Manage skills and tasks\n- Read/write files\n- Execute shell commands\n- Work with encrypted storage\n- Or anything else you'd like to test!\n\nWhat would you like me to do?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9354,"completion_tokens":199,"total_tokens":9553,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":0,"cache_write_tokens":9351,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.01268675,"upstream_inference_prompt_cost":0.01169175,"upstream_inference_completions_cost":0.000995},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
{"id":"gen-1777375250-jFanwsCICZFqoelE44Pq","object":"chat.completion","created":1777375250,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I see you've sent a very long string of \"A\" characters. \n\nIs there something specific I can help you with? I'm a test agent with access to various tools for working with Nostr, file operations, HTTP requests, skills, wallets, and more.\n\nFeel free to ask me a question or request something, and I'll do my best to assist you!","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":16024,"completion_tokens":83,"total_tokens":16107,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":6992,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0100582,"upstream_inference_prompt_cost":0.0096432,"upstream_inference_completions_cost":0.000415},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
{"id":"gen-1777375274-zsPFOGPaSztcq1eWkJwI","object":"chat.completion","created":1777375274,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I understand! After the system restarts, I should say hello. \n\nHowever, I should note that I'm currently running and ready to help you. If you're planning to restart the system or agent, just let me know when it comes back up, and I'll greet you with a hello!\n\nIs there anything else you'd like me to help you with in the meantime?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9367,"completion_tokens":84,"total_tokens":9451,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0017412,"upstream_inference_prompt_cost":0.0013212,"upstream_inference_completions_cost":0.00042},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375278-hK1kwZuer9Lsw5MLxeTY","object":"chat.completion","created":1777375278,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Hello! I'm a test agent ready to help you with whatever you need.","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9367,"completion_tokens":19,"total_tokens":9386,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0014162,"upstream_inference_prompt_cost":0.0013212,"upstream_inference_completions_cost":0.000095},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
{"id":"gen-1777375342-uCRzfhu0bf1KkFyxOXma","object":"chat.completion","created":1777375342,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll list your Blossom blobs. First, I need to get your pubkey, then I'll need to know which Blossom server to query. Let me start by getting your pubkey:","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01EuoCso6xsH4hg6MtqtEbwB","function":{"name":"nostr_pubkey","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9369,"completion_tokens":84,"total_tokens":9453,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":334,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0017437,"upstream_inference_prompt_cost":0.0013237,"upstream_inference_completions_cost":0.00042},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375355-ZuuW9IXNHn2xcCnAxE0y","object":"chat.completion","created":1777375355,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll check your Cashu wallet balance for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01AjyEY1765A49f2DE6Uh3GG","function":{"name":"cashu_wallet_balance","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9368,"completion_tokens":52,"total_tokens":9420,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015822,"upstream_inference_prompt_cost":0.0013222,"upstream_inference_completions_cost":0.00026},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
{"id":"gen-1777375359-KpRY8FHWdC5j7tFYnf99","object":"chat.completion","created":1777375359,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Your Cashu wallet is currently **empty** with a balance of **0**. \n\nThe wallet appears to not be loaded yet. This could mean:\n- No mints have been configured\n- No ecash tokens have been received or minted yet\n- The wallet needs to be initialized\n\nWould you like me to help you:\n1. Check wallet mint configuration?\n2. Request a mint quote to add funds?\n3. Configure a mint for your wallet?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9450,"completion_tokens":103,"total_tokens":9553,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9364,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015374,"upstream_inference_prompt_cost":0.0010224,"upstream_inference_completions_cost":0.000515},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
{"id":"gen-1777375423-T6U7hn04dTKnjjFxe19S","object":"chat.completion","created":1777375423,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":null,"refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01RaaLJ4ePRXjbbfg3o6LV73","function":{"name":"nostr_pubkey","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9371,"completion_tokens":39,"total_tokens":9410,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":336,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015212,"upstream_inference_prompt_cost":0.0013262,"upstream_inference_completions_cost":0.000195},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375436-giGLkkFTP46gGTSS9xMv","object":"chat.completion","created":1777375436,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":null,"refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01Y23Q4voefWXQYThdYWU2cL","function":{"name":"my_npub","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9367,"completion_tokens":38,"total_tokens":9405,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015112,"upstream_inference_prompt_cost":0.0013212,"upstream_inference_completions_cost":0.00019},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375439-LiTUe0VdwVXCM9os7FiY","object":"chat.completion","created":1777375439,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"My npub is: **npub1r6chzymdhvd6d9dj79pfdt073zsls82zyrx86xrtpcfehr8qek7q3rkewf**\n\nThis is my Nostr public key encoded in bech32 format. You can use this to find me on the Nostr network!","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9513,"completion_tokens":83,"total_tokens":9596,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9364,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015004,"upstream_inference_prompt_cost":0.0010854,"upstream_inference_completions_cost":0.000415},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375502-52pu2oVKedn2eurqBVit","object":"chat.completion","created":1777375502,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll retrieve my identity information for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01SEn9gQoVzuKX74JfWfVckc","function":{"name":"agent_identity","arguments":"{}"}},{"type":"function","index":1,"id":"toolu_bdrk_018BxAiMzYUvQbWzDQygahVA","function":{"name":"nostr_agent_profile","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9367,"completion_tokens":68,"total_tokens":9435,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":330,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0016607,"upstream_inference_prompt_cost":0.0013207,"upstream_inference_completions_cost":0.00034},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375516-xBn93xlI322fzADQ3nPP","object":"chat.completion","created":1777375516,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll check the agent version for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_013wKmxmgG5JTUiyGbohVjAN","function":{"name":"agent_version","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9365,"completion_tokens":46,"total_tokens":9411,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":330,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015487,"upstream_inference_prompt_cost":0.0013187,"upstream_inference_completions_cost":0.00023},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375519-JJvmXyq4ll76c2D49pEi","object":"chat.completion","created":1777375519,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I'm **Didactyl v0.2.48**, a sovereign AI agent daemon running on Nostr. \n\nHere are the details:\n- **Name:** Didactyl\n- **Version:** v0.2.48 (Major: 0, Minor: 2, Patch: 48)\n- **Description:** A sovereign AI agent daemon on Nostr\n- **Repository:** https://git.laantungir.net/laantungir/didactyl.git\n\nIs there anything else you'd like to know?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9497,"completion_tokens":124,"total_tokens":9621,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9362,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0016912,"upstream_inference_prompt_cost":0.0010712,"upstream_inference_completions_cost":0.00062},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375582-HLkTRcL7ciicnO3WG706","object":"chat.completion","created":1777375582,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll fetch information about my administrator for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_018YfVsvGA6DtB9CBZH3WFbw","function":{"name":"admin_identity","arguments":"{}"}},{"type":"function","index":1,"id":"toolu_bdrk_01Q35faB3GUEqVgeXcYagANX","function":{"name":"nostr_admin_profile","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9365,"completion_tokens":69,"total_tokens":9434,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":330,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0016637,"upstream_inference_prompt_cost":0.0013187,"upstream_inference_completions_cost":0.000345},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
{"id":"gen-1777375596-rVYt4DZZqybR0cri83ok","object":"chat.completion","created":1777375596,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll fetch your current task list for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01SkQiJkNcACnKfxoaL8QUHT","function":{"name":"task_list","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9367,"completion_tokens":47,"total_tokens":9414,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015562,"upstream_inference_prompt_cost":0.0013212,"upstream_inference_completions_cost":0.000235},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375600-1i2NzbywIG7vr1pbbB7L","object":"chat.completion","created":1777375600,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Your current task list is empty! You don't have any active tasks yet.\n\nWould you like me to help you:\n- **Add a task** - I can create a new task for you\n- **View completed tasks** - Check what you've already done\n- **Set up a task** - Help you organize something you're working on\n\nJust let me know what you'd like to do, or provide the task details and I can add them for you.","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9480,"completion_tokens":100,"total_tokens":9580,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9364,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0015524,"upstream_inference_prompt_cost":0.0010524,"upstream_inference_completions_cost":0.0005},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
{"id":"gen-1777375663-e99PoJts5k6BizMUmNhQ","object":"chat.completion","created":1777375663,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll add a task and then remove it for you.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_017Lhypkwt8Wx9eo9yQS3vmF","function":{"name":"task_manage","arguments":"{\"action\": \"add\", \"text\": \"test harness probe task\", \"status\": \"pending\"}"}}]}}],"usage":{"prompt_tokens":9377,"completion_tokens":104,"total_tokens":9481,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":342,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0018537,"upstream_inference_prompt_cost":0.0013337,"upstream_inference_completions_cost":0.00052},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375677-0RglWxj5Ki0dNNPe4Do4","object":"chat.completion","created":1777375677,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"I'll save a test harness probe to memory and then recall it.","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01GBGt8MaQjzZj4i23ij5caL","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.\"}"}}]}}],"usage":{"prompt_tokens":9380,"completion_tokens":103,"total_tokens":9483,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":344,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0018522,"upstream_inference_prompt_cost":0.0013372,"upstream_inference_completions_cost":0.000515},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
{"id":"gen-1777375680-CxwbupX8iy37rE7N441O","object":"chat.completion","created":1777375680,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"tool_calls","native_finish_reason":"tool_use","message":{"role":"assistant","content":"Great! Now let me recall the memory:","refusal":null,"reasoning":null,"tool_calls":[{"type":"function","index":0,"id":"toolu_bdrk_01QgBARiRY5FTx8TJH3GhzU6","function":{"name":"memory_recall","arguments":"{}"}}]}}],"usage":{"prompt_tokens":9569,"completion_tokens":46,"total_tokens":9615,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9376,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0013606,"upstream_inference_prompt_cost":0.0011306,"upstream_inference_completions_cost":0.00023},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
{"id":"gen-1777375696-JOdX4gcv02mKizye0xyb","object":"chat.completion","created":1777375696,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Perfect! ✅ **Test harness probe successful:**\n\n**Saved to memory:**\n- 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.\"\n- Event ID: `6311c65cf9b52fe1fe9bce8052a09f594d6b3dc1f83f8030f45106b8b3a108e2`\n- Kind: 30078 (encrypted agent config)\n- D-tag: \"memory\"\n\n**Recalled from memory:**\n- Successfully retrieved the exact content that was saved\n- Content length: 199 bytes\n- No truncation occurred\n\nThe memory subsystem is operational and both save/recall functions are working correctly! 🎯","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9676,"completion_tokens":188,"total_tokens":9864,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9376,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0021776,"upstream_inference_prompt_cost":0.0012376,"upstream_inference_completions_cost":0.00094},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
{"id":"gen-1777375736-lYPEXYI3bEyeSmVzv9zh","object":"chat.completion","created":1777375736,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"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- **File operations** (reading and writing local files)\n- **Shell commands** (executing system commands)\n- **HTTP requests** (fetching web resources)\n- **Skills management** (creating, running, and managing reusable skills)\n- **Task management** (tracking and managing tasks)\n- **Wallet operations** (Cashu ecash and Lightning)\n- **File storage** (Blossom server uploads/downloads)\n- And more!\n\nI don't have a specific personal name beyond being your Didactyl Agent, but I'm here to help you with whatever you need. What can I assist you with today?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9369,"completion_tokens":194,"total_tokens":9563,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":334,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0022937,"upstream_inference_prompt_cost":0.0013237,"upstream_inference_completions_cost":0.00097},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
{"id":"gen-1777375740-7wwdu6DnbPK2uHfm9Dhh","object":"chat.completion","created":1777375740,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"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 both on-chain and off-chain tasks\n- I can publish posts, send encrypted messages, manage lists, and interact with the Nostr ecosystem\n\n**Key Capabilities:**\n- **Nostr Operations**: Post notes, send DMs, manage contacts, verify identities, and query events from relays\n- **Skills System**: I can create, adopt, and run modular skills that extend my functionality\n- **Memory & Tasks**: I maintain encrypted memory and task lists stored on Nostr for persistence\n- **Financial**: I can handle Cashu ecash wallets and payments\n- **File Management**: I can read/write local files and interact with Blossom file servers\n- **LLM Integration**: I'm powered by configurable language models and can execute complex workflows\n- **Automation**: I support triggered skills via webhooks, cron schedules, DMs, and Nostr subscriptions\n\n**How I Work:**\nI'm a test agent in this instance, ready to help you explore what I can do. I combine Nostr's decentralized messaging with AI reasoning to create a flexible, privacy-respecting automation platform.\n\nWhat would you like to do? I can help with Nostr interactions, skill management, file operations, or just about anything else you need!","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9373,"completion_tokens":333,"total_tokens":9706,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":338,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0029937,"upstream_inference_prompt_cost":0.0013287,"upstream_inference_completions_cost":0.001665},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
{"id":"gen-1777375776-aZoApJ1ae9UcNjTPlooQ","object":"chat.completion","created":1777375776,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"# Didactyl Agent\n\nHello! I'm a test agent ready to assist you. I have access to a comprehensive set of tools including:\n\n- **Nostr Protocol**: Publishing events, querying data, managing profiles, DMs, encryption, and more\n- **File Operations**: Reading and writing local files\n- **Shell Execution**: Running commands in the working directory\n- **Skills Management**: Creating, listing, adopting, and running skills\n- **HTTP Requests**: Fetching web resources\n- **LLM Configuration**: Managing model settings\n- **Task & Memory Management**: Storing and recalling agent state\n- **Cashu Wallet**: Managing ecash tokens and mints\n- **Blossom**: File upload/download to Blossom servers\n\nI'm ready to help with any requests. What would you like me to do?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9354,"completion_tokens":188,"total_tokens":9542,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":0,"cache_write_tokens":9351,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.01263175,"upstream_inference_prompt_cost":0.01169175,"upstream_inference_completions_cost":0.00094},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
{"id":"gen-1777375790-hGgvQ0etnXavfdB3WnzF","object":"chat.completion","created":1777375790,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I see you've sent a very long string of the letter \"A\". \n\nI'm here to help! Could you please let me know what you'd actually like me to do? For example, I can:\n\n- Answer questions\n- Help with Nostr-related tasks (posting, querying events, managing profiles, etc.)\n- Execute shell commands\n- Read or write files\n- Manage skills and tasks\n- Work with cryptocurrency wallets (Cashu)\n- Upload/download files (Blossom)\n- And much more\n\nWhat would you like assistance with?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":16024,"completion_tokens":128,"total_tokens":16152,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":6992,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0102832,"upstream_inference_prompt_cost":0.0096432,"upstream_inference_completions_cost":0.00064},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{"id":"gen-1777375810-NHr1i5tqdEPozD3NpLCF","object":"chat.completion","created":1777375810,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"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 capabilities available to me, including Nostr integration, file management, skill management, and more.\n\nIs there anything I can help you with today?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9369,"completion_tokens":84,"total_tokens":9453,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9366,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0013596,"upstream_inference_prompt_cost":0.0009396,"upstream_inference_completions_cost":0.00042},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
{"id":"gen-1777375813-DRu7RouOiJlA3MKNwdc3","object":"chat.completion","created":1777375813,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"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 interact with Nostr events across multiple relays\n- I have my own pubkey and can act independently or on behalf of an admin user\n\n## Key Capabilities\n- **Nostr Integration**: Publish notes, long-form posts, reactions, and encrypted DMs\n- **Skill System**: I can create, adopt, and execute specialized skills (reusable AI workflows)\n- **Task Management**: Track and manage tasks stored on Nostr\n- **Memory**: I maintain encrypted agent memory for continuity across conversations\n- **LLM Integration**: I'm powered by configurable language models (currently using an OpenAI-compatible backend)\n- **Wallet & Payments**: I can manage Cashu ecash wallets and handle Lightning payments\n- **File Operations**: I can read/write files and interact with Blossom file storage servers\n- **Web Integration**: I can fetch HTTP resources and execute shell commands\n\n## How I Work\nI respond to requests and use tools when needed. I can be triggered by:\n- Direct messages (DMs)\n- Scheduled tasks (cron jobs)\n- Nostr subscriptions\n- Webhooks\n- Skill chains\n\nI'm designed to be privacy-respecting, leveraging Nostr's encryption where appropriate, and can operate autonomously or collaboratively with an admin user.\n\nWhat would you like to know more about, or how can I help you?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9373,"completion_tokens":365,"total_tokens":9738,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9370,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.002765,"upstream_inference_prompt_cost":0.00094,"upstream_inference_completions_cost":0.001825},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
{"id":"gen-1777375880-ECGT0ZdA9f6YOQOw8lM9","object":"chat.completion","created":1777375880,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I'm ready to help! I'm a Didactyl agent designed to assist you with various tasks using the available tools.\n\nI can help you with:\n\n- **Nostr Operations**: Post notes, query events, manage profiles, send DMs, handle encryption, manage lists and block lists\n- **Skill Management**: Create, edit, list, search, and run skills\n- **Local Operations**: Read/write files, execute shell commands, fetch HTTP resources\n- **Agent Configuration**: Manage LLM settings, model selection, and runtime configuration\n- **Memory & Tasks**: Store and recall agent memory, manage task lists\n- **Wallet Operations**: Check balances, mint/melt ecash, send/receive tokens\n- **File Storage**: Upload/download files via Blossom servers\n- **Relay Management**: Check relay status, fetch relay info, manage subscriptions\n\nWhat would you like me to help you with?","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9354,"completion_tokens":203,"total_tokens":9557,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9351,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0019531,"upstream_inference_prompt_cost":0.0009381,"upstream_inference_completions_cost":0.001015},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
{"id":"gen-1777375894-scuuv4LZNWVF29yV05L7","object":"chat.completion","created":1777375894,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"I see you've sent a very long string of the letter \"A\". \n\nI'm a test agent here to help you with requests and use tools when needed. Is there something specific I can help you with? Feel free to ask me a question or let me know what you'd like to do, and I'll do my best to assist using the available tools.","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":16024,"completion_tokens":78,"total_tokens":16102,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":16024,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0019924,"upstream_inference_prompt_cost":0.0016024,"upstream_inference_completions_cost":0.00039},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
{"id":"gen-1777376029-xUzuqdFfKe7nM3xi1ooh","object":"chat.completion","created":1777376029,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Hello! 👋 I'm the Didactyl test agent, and I'm ready to help. I received your message: \"Hello from smoke test\"\n\nI have access to a wide range of tools including:\n\n- **Nostr Protocol Tools** - posting, querying, DMs, profiles, relays, etc.\n- **File Operations** - reading and writing local files\n- **Shell Commands** - executing commands\n- **Skills Management** - creating, editing, and running skills\n- **HTTP Requests** - fetching web resources\n- **Cashu Wallet** - ecash operations\n- **Blossom** - file storage/retrieval\n- **Configuration & Memory** - storing and recalling agent state\n\nWhat would you like me to help you with? Feel free to ask me to:\n- Post to Nostr\n- Query events or profiles\n- Manage files\n- Run commands\n- Create or manage skills\n- Handle any other tasks you need","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9364,"completion_tokens":216,"total_tokens":9580,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":328,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0023972,"upstream_inference_prompt_cost":0.0013172,"upstream_inference_completions_cost":0.00108},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
{"id":"gen-1777376040-qkXhEUESTodU6M3rpqhw","object":"chat.completion","created":1777376040,"model":"anthropic/claude-4.5-haiku-20251001","provider":"Amazon Bedrock","system_fingerprint":null,"choices":[{"index":0,"logprobs":null,"finish_reason":"stop","native_finish_reason":"end_turn","message":{"role":"assistant","content":"Hello! I'm ready to help you with any requests you might have.","refusal":null,"reasoning":null}}],"usage":{"prompt_tokens":9367,"completion_tokens":18,"total_tokens":9385,"cost":0,"is_byok":true,"prompt_tokens_details":{"cached_tokens":9032,"cache_write_tokens":332,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0014112,"upstream_inference_prompt_cost":0.0013212,"upstream_inference_completions_cost":0.00009},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}

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.

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.

View File

@@ -35,8 +35,6 @@ static pthread_mutex_t g_context_part_names_mutex = PTHREAD_MUTEX_INITIALIZER;
#define AGENT_DEBOUNCE_WINDOW_SECONDS 5
#define AGENT_DEBOUNCE_CACHE_SIZE 256
#define AGENT_HISTORY_TURNS 12
#define AGENT_HISTORY_QUERY_LIMIT 200
#define AGENT_ADOPTED_SKILLS_CACHE_TTL_SECONDS 300
#define AGENT_ADOPTED_SKILLS_MAX 24
#define AGENT_ADOPTED_SKILL_CONTENT_MAX_CHARS 1800
@@ -1062,73 +1060,6 @@ static __attribute__((unused)) char* build_sender_verification_text(didactyl_sen
}
static __attribute__((unused)) int append_recent_admin_dm_history(cJSON* messages, const char* current_message) {
if (!messages || !g_cfg) {
return -1;
}
char* history_json = nostr_handler_get_dm_history_json(g_cfg->admin.pubkey, AGENT_HISTORY_TURNS);
if (!history_json) {
return 0;
}
cJSON* items = cJSON_Parse(history_json);
free(history_json);
if (!items || !cJSON_IsArray(items)) {
cJSON_Delete(items);
return 0;
}
const char* last_appended_role = NULL;
const char* last_appended_content = NULL;
int n = cJSON_GetArraySize(items);
for (int i = 0; i < n; i++) {
cJSON* item = cJSON_GetArrayItem(items, i);
cJSON* role = item ? cJSON_GetObjectItemCaseSensitive(item, "role") : NULL;
cJSON* content = item ? cJSON_GetObjectItemCaseSensitive(item, "content") : NULL;
cJSON* created_at = item ? cJSON_GetObjectItemCaseSensitive(item, "created_at") : NULL;
if (!role || !content || !cJSON_IsString(role) || !cJSON_IsString(content) ||
!role->valuestring || !content->valuestring) {
continue;
}
const char* role_s = role->valuestring;
const char* content_s = content->valuestring;
int role_is_user = (strcmp(role_s, "user") == 0);
if (!role_is_user && strcmp(role_s, "assistant") != 0) {
continue;
}
if (i == n - 1 && role_is_user && current_message && strcmp(content_s, current_message) == 0) {
continue;
}
if (last_appended_role && last_appended_content &&
strcmp(last_appended_role, role_s) == 0 &&
strcmp(last_appended_content, content_s) == 0) {
continue;
}
if (append_simple_message(messages, role_s, content_s) != 0) {
cJSON_Delete(items);
return -1;
}
cJSON* appended = cJSON_GetArrayItem(messages, cJSON_GetArraySize(messages) - 1);
if (appended && cJSON_IsObject(appended) && created_at && cJSON_IsNumber(created_at)) {
cJSON_AddNumberToObject(appended, "_ts", created_at->valuedouble);
}
last_appended_role = role_s;
last_appended_content = content_s;
}
cJSON_Delete(items);
return 0;
}
static cJSON* find_tag_value_string_local(cJSON* tags, const char* key) {
if (!tags || !key || !cJSON_IsArray(tags)) {
return NULL;
@@ -1797,18 +1728,6 @@ static __attribute__((unused)) int append_adopted_skills_context(cJSON* messages
return rc;
}
static __attribute__((unused)) cJSON* build_recent_admin_dm_history_messages(const char* current_message) {
cJSON* messages = cJSON_CreateArray();
if (!messages) {
return NULL;
}
if (append_recent_admin_dm_history(messages, current_message) != 0) {
cJSON_Delete(messages);
return NULL;
}
return messages;
}
int agent_init(didactyl_config_t* config) {
if (!config) {
return -1;

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);

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 45
#define DIDACTYL_VERSION "v0.2.45"
#define DIDACTYL_VERSION_PATCH 49
#define DIDACTYL_VERSION "v0.2.49"
// Agent metadata
#define DIDACTYL_NAME "Didactyl"

View File

@@ -1510,6 +1510,7 @@ static void register_trigger_from_self_skill_event(cJSON* event) {
static void self_skill_cache_upsert_event_locked(cJSON* event) {
if (!event || !cJSON_IsObject(event)) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: event missing or not object");
return;
}
@@ -1517,36 +1518,51 @@ static void self_skill_cache_upsert_event_locked(cJSON* event) {
cJSON* pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey");
cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags");
cJSON* created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at");
cJSON* ev_id = cJSON_GetObjectItemCaseSensitive(event, "id");
int kind_val = (kind && cJSON_IsNumber(kind)) ? (int)kind->valuedouble : -1;
double created = (created_at && cJSON_IsNumber(created_at)) ? created_at->valuedouble : 0.0;
DEBUG_INFO("[didactyl] self-skill upsert candidate: kind=%d author=%.16s... id=%.16s... created_at=%.0f",
kind_val,
(pubkey && cJSON_IsString(pubkey) && pubkey->valuestring) ? pubkey->valuestring : "?",
(ev_id && cJSON_IsString(ev_id) && ev_id->valuestring) ? ev_id->valuestring : "?",
created);
if (!kind || !cJSON_IsNumber(kind) ||
!pubkey || !cJSON_IsString(pubkey) || !pubkey->valuestring ||
!tags || !cJSON_IsArray(tags)) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: missing required kind/pubkey/tags");
return;
}
int kind_val = (int)kind->valuedouble;
if (kind_val != 31123 && kind_val != 31124 && kind_val != 10123) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: kind not in {31123,31124,10123}");
return;
}
if (!g_cfg) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: config unavailable");
return;
}
int is_agent_author = (strcmp(pubkey->valuestring, g_cfg->keys.public_key_hex) == 0);
int is_admin_author = (g_cfg->admin.pubkey[0] != '\0' && strcmp(pubkey->valuestring, g_cfg->admin.pubkey) == 0);
if (kind_val == 10123) {
if (!is_agent_author && !is_admin_author) {
if (!is_agent_author) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: kind=10123 author is not self");
return;
}
}
if (is_admin_author && kind_val == 31124) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: admin cannot own private skill (31124)");
return;
}
const char* d_tag = find_tag_value_local(tags, "d");
if ((kind_val == 31123 || kind_val == 31124) && (!d_tag || d_tag[0] == '\0')) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: parameterized kind missing d-tag");
return;
}
@@ -1554,12 +1570,11 @@ static void self_skill_cache_upsert_event_locked(cJSON* event) {
cJSON_Delete(g_self_skill_events);
g_self_skill_events = cJSON_CreateArray();
if (!g_self_skill_events) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: failed to create cache array");
return;
}
}
double created = (created_at && cJSON_IsNumber(created_at)) ? created_at->valuedouble : 0.0;
int n = cJSON_GetArraySize(g_self_skill_events);
for (int i = 0; i < n; i++) {
cJSON* existing = cJSON_GetArrayItem(g_self_skill_events, i);
@@ -1591,23 +1606,56 @@ static void self_skill_cache_upsert_event_locked(cJSON* event) {
cJSON* ex_created_at = cJSON_GetObjectItemCaseSensitive(existing, "created_at");
double ex_created = (ex_created_at && cJSON_IsNumber(ex_created_at)) ? ex_created_at->valuedouble : 0.0;
if (created < ex_created) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: stale (existing created_at=%.0f >= new created_at=%.0f)",
ex_created,
created);
return;
}
cJSON* dup = cJSON_Duplicate(event, 1);
if (!dup) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: failed to duplicate event");
return;
}
cJSON_ReplaceItemInArray(g_self_skill_events, i, dup);
DEBUG_INFO("[didactyl] self-skill upsert accepted: replaced existing (old created_at=%.0f)", ex_created);
if (kind_val == 10123) {
int a_count = 0;
cJSON* t;
cJSON_ArrayForEach(t, tags) {
if (cJSON_IsArray(t) && cJSON_GetArraySize(t) >= 2) {
cJSON* t0 = cJSON_GetArrayItem(t, 0);
if (t0 && cJSON_IsString(t0) && t0->valuestring && strcmp(t0->valuestring, "a") == 0) {
a_count++;
}
}
}
DEBUG_INFO("[didactyl] kind 10123 accepted with %d 'a' tags", a_count);
}
return;
}
cJSON* dup = cJSON_Duplicate(event, 1);
if (!dup) {
DEBUG_INFO("[didactyl] self-skill upsert rejected: failed to duplicate event");
return;
}
cJSON_AddItemToArray(g_self_skill_events, dup);
DEBUG_INFO("[didactyl] self-skill upsert accepted: new entry added");
if (kind_val == 10123) {
int a_count = 0;
cJSON* t;
cJSON_ArrayForEach(t, tags) {
if (cJSON_IsArray(t) && cJSON_GetArraySize(t) >= 2) {
cJSON* t0 = cJSON_GetArrayItem(t, 0);
if (t0 && cJSON_IsString(t0) && t0->valuestring && strcmp(t0->valuestring, "a") == 0) {
a_count++;
}
}
}
DEBUG_INFO("[didactyl] kind 10123 accepted with %d 'a' tags", a_count);
}
}
static int hex_to_pubkey(const char* hex, unsigned char out_pubkey[32]) {
@@ -2775,6 +2823,10 @@ int nostr_handler_subscribe_self_skills(void) {
cJSON_AddItemToObject(filter, "authors", authors);
cJSON_AddNumberToObject(filter, "limit", 300);
char* filter_str = cJSON_PrintUnformatted(filter);
DEBUG_INFO("[didactyl] self-skill subscription filter: %s", filter_str ? filter_str : "(null)");
free(filter_str);
pthread_mutex_lock(&g_subscription_mutex);
managed_subscriptions_init_defaults();
if (managed_subscription_register_locked(MANAGED_SUB_SELF_SKILLS,
@@ -3719,9 +3771,6 @@ int nostr_handler_refresh_self_skill_cache_from_relays(int timeout_ms) {
cJSON_AddItemToObject(filter, "kinds", kinds);
cJSON_AddItemToArray(authors, cJSON_CreateString(g_cfg->keys.public_key_hex));
if (g_cfg->admin.pubkey[0] != '\0' && strcmp(g_cfg->admin.pubkey, g_cfg->keys.public_key_hex) != 0) {
cJSON_AddItemToArray(authors, cJSON_CreateString(g_cfg->admin.pubkey));
}
cJSON_AddItemToObject(filter, "authors", authors);
cJSON_AddNumberToObject(filter, "limit", 500);
@@ -3919,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;

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);

View File

@@ -0,0 +1 @@
[2026-04-28 07:18:22] [INFO ] [main.c:1103] Didactyl v0.2.48 starting

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -0,0 +1 @@
[2026-04-28 07:18:40] [INFO ] [main.c:1103] Didactyl v0.2.48 starting

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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"]

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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"]

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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"]

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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"]

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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"]

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
}
}

View File

@@ -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

View File

@@ -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\"}"]
]
}
]
}

View File

@@ -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\"}"]
]
}
]
}