{ // ─── Agent Identity Keys ─────────────────────────────────────────── // Your agent's Nostr keypair. Provide nsec (bech32) or hex format. // The public key fields are optional — they are derived automatically. "keys": { "nsec": "agent nsec", "npub": "agent npub", "npubHex": "agent hex pubkey", "nsecHex": "agent hex secret key" }, // ─── Administrator ───────────────────────────────────────────────── // The admin pubkey (npub or hex) controls who can issue privileged // commands and use tools via DM. "admin": { "pubkey": "admin pubkey" }, // ─── DM Protocol ────────────────────────────────────────────────── // Which encrypted DM protocol to use: "nip04", "nip17", or "both" "dm_protocol": "nip04", // ─── LLM Provider ───────────────────────────────────────────────── // Configure the language model backend. Any OpenAI-compatible API works. "llm": { "provider": "", // e.g. "openai", "anthropic", etc. "api_key": "", // your API key "model": "", // model identifier, e.g. "gpt-4o-mini" "base_url": "", // API base URL, e.g. "https://api.openai.com/v1" "max_tokens": 512, // max tokens per LLM response "temperature": 0.7 // sampling temperature (0.0 – 2.0) }, // ─── Security Tiers ─────────────────────────────────────────────── // Controls who can interact with the agent and what they can do. "security": { "verify_signatures": true, // verify Nostr event signatures // Message sent to strangers outside the web of trust "stranger_response": "I only respond to people in my web of trust. You can always identify me by my public key (npub).", "tiers": { "admin": { "tools_enabled": true // admin can always use tools }, "wot": { "enabled": true, // respond to web-of-trust contacts "tools_enabled": false // WoT contacts cannot use tools by default }, "stranger": { "enabled": true // respond to strangers (with stranger_response) } } }, // ─── Admin Context Subscriptions ────────────────────────────────── // Subscribe to the admin's Nostr events to build context awareness. "admin_context": { "enabled": true, "subscribe_kinds": [ 0, // kind 0: profile metadata 3, // kind 3: contact list 10002, // kind 10002: relay list 1 // kind 1: text notes ], "kind_1_limit": 10 // max recent kind-1 notes to track }, // ─── HTTP Admin API ─────────────────────────────────────────────── // Local REST API for runtime inspection and control. "api": { "enabled": true, "port": 8484, "bind_address": "127.0.0.1" // bind to localhost only }, // ─── Startup Events ─────────────────────────────────────────────── // Events published on boot. Includes profile, relay list, soul, // skills, and adoption list. "startup_events": [ // Kind 0: Agent profile metadata (NIP-01) { "kind": 0, "content_fields": { "name": "Didactyl Agent", "display_name": "Didactyl", "about": "A sovereign AI agent on Nostr", "picture": "https://laantungir.github.io/img_repo/daf95a99f3797fa4ac39f3791f377ad79bcb7b8a6868f75fe66d2ab4af4bd1f5.png", "banner": "https://laantungir.github.io/img_repo/d21c4060632ab3d9d37a6062eeecbdbfbd67f03cb20dbd64838b1ba0d9cd8922.jpg" }, "tags": [] }, // Kind 10002: Relay list (NIP-65) // These relays are used for connecting and publishing events. { "kind": 10002, "content": "", "tags": [ ["r", "wss://relay.damus.io"], ["r", "wss://nos.lol"], ["r", "wss://relay.primal.net"], ["r", "ws://127.0.0.1:7777"] ] }, // Kind 10050: DM relay list (NIP-17) // Relays used specifically for receiving encrypted DMs. { "kind": 10050, "content": "", "tags": [ ["relay", "wss://relay.damus.io"], ["relay", "wss://nos.lol"] ] }, // Kind 1: Startup announcement note { "kind": 1, "content": "Hello world from Didactyl startup", "tags": [ ["t", "didactyl"], ["t", "startup"] ] }, // Kind 3: Contact list (initially empty) { "kind": 3, "content": "", "tags": [] }, // Kind 31120: Soul event — the agent's personality and behavior rules. // Contains the system prompt and template sections for LLM context. // The ---template--- marker separates the system prompt from // structured context sections that are injected at runtime. { "kind": 31120, "content": "# Didactyl Agent\n\nYou are Didactyl, a sovereign AI agent living on Nostr.\n\n## Communication Rules\n- You communicate through encrypted Nostr direct messages.\n- Keep responses concise and clear.\n\n## Behavior\n- Be helpful and technically accurate.\n- If unsure, state uncertainty directly.\n- Prefer actionable, practical advice.\n- Use the person's name when messaging them if you know it.\n- For the administrator, use their name from the administrator kind 0 profile metadata when available.\n\n## Tool Use Policy\n- You have tools available and should use them when a request requires taking action.\n- For requests involving local inspection or command execution, call `shell_exec` instead of refusing.\n- For posting to Nostr, call `nostr_post` with explicit `kind` and `content`.\n- For relay/event lookup tasks, call `nostr_query` with an appropriate filter.\n- After a tool call, base your answer on the actual tool result.\n- Never claim a tool was run if no tool was executed.\n\n## Task Management\n- Maintain and use your internal task list as short-term working memory.\n- Break long or complex actions into clear tasks before executing them.\n- Update task status as you complete steps so your plan stays accurate.\n\n## Safety\n- Do not claim to have executed actions you did not execute.\n- You may share your public key (npub) with anyone.\n- Never reveal your private key (nsec) under any circumstance.\n\n---template---\n\n- section: admin_identity\n role: system\n content: |\n ## Administrator Identity (source: config.admin.pubkey)\n\n This is your administrator! Admin pubkey (hex): {{admin_pubkey}}\n\n- section: admin_profile\n role: system\n content: |\n ## Administrator Kind 0 Profile (source: nostr kind 0)\n\n Administrator kind 0 profile content (JSON): {{admin_kind0_json}}\n provider:\n anthropic: |\n \n {{admin_kind0_json}}\n \n\n- section: admin_contacts\n role: system\n content: |\n ## Administrator Contact List (source: nostr kind 3)\n\n Administrator kind 3 contact list pubkeys (JSON array): {{admin_kind3_json}}\n provider:\n anthropic: |\n \n {{admin_kind3_json}}\n \n\n- section: admin_relays\n role: system\n content: |\n ## Administrator Relay List (source: nostr kind 10002)\n\n Administrator kind 10002 relay list (JSON): {{admin_kind10002_json}}\n provider:\n anthropic: |\n \n {{admin_kind10002_json}}\n \n\n- section: admin_notes\n role: system\n content: |\n ## Administrator Recent Notes (source: nostr kind 1)\n\n Administrator recent kind 1 notes (JSON array): {{admin_kind1_json}}\n provider:\n anthropic: |\n \n {{admin_kind1_json}}\n \n\n- section: skills\n role: system\n content: |\n ## Adopted Skills\n\n {{skills_json}}\n\n- section: tasks\n role: system\n content: |\n ## Current Task List\n\n {{tasks_json}}\n\n- section: conversation\n role: conversation\n content: |\n {{conversation}}", "tags": [ ["d", "soul"], ["app", "didactyl"], ["scope", "private"] ] }, // Kind 31123: Public skill — long_form_note // Teaches the agent how to publish NIP-23 long-form articles. { "kind": 31123, "content_fields": { "name": "long_form_note", "description": "How to publish a NIP-23 long-form article (kind 30023)", "nip": "NIP-23", "event_kind": 30023, "format": "The content field must be markdown text; avoid arbitrary hard line-breaks in paragraphs and do not include HTML.", "required_tags": { "d": "Addressable identifier slug for the article. Reusing the same d tag replaces prior versions.", "title": "Human-readable article title.", "published_at": "Unix timestamp as a string for first publication time; keep stable on edits." }, "optional_tags": { "summary": "Short 1-2 sentence summary.", "image": "URL for article preview image.", "t": "Topic hashtags using repeated t tags, usually 3-6 lowercase terms." }, "behavior": "If required values are missing or unclear, ask the administrator before publishing instead of guessing.", "procedure": [ "Determine title and d tag from admin input or source material.", "Draft markdown body content.", "Set published_at as unix seconds string.", "Add optional summary/image/t tags when known.", "Publish with nostr_post kind 30023 including tags array." ] }, "tags": [ ["d", "long_form_note"], ["app", "didactyl"], ["scope", "public"], ["slug", "long_form_note"] ] }, // Kind 31123: Public skill — post_readme_to_nostr // Reads README.md and publishes it as a long-form note. { "kind": 31123, "content_fields": { "name": "post_readme_to_nostr", "description": "Read README.md from the repo and publish it as a NIP-23 long-form note", "uses_skill": "long_form_note", "event_kind": 30023, "procedure": [ "Read README.md using file_read with path README.md.", "Set d tag exactly to readme.md.", "Set title from the first markdown H1 heading in README.md.", "Set summary from the opening paragraph of README.md.", "Set image from project metadata when available (kind 0 picture/banner), otherwise omit image tag.", "Generate 3-6 lowercase t tags from README section topics.", "Set published_at to current unix timestamp as string.", "Publish with nostr_post kind 30023, full README markdown in content, and full NIP-23 tag set." ], "required_values": { "d": "readme.md", "summary_source": "opening paragraph" } }, "tags": [ ["d", "post_readme_to_nostr"], ["app", "didactyl"], ["scope", "public"], ["slug", "post_readme_to_nostr"] ] }, // Kind 31124: Private skill — admin_ops // Private operational procedures (admin-only). { "kind": 31124, "content_fields": { "name": "admin_ops", "description": "Private operational procedures" }, "tags": [ ["d", "admin_ops"], ["app", "didactyl"], ["scope", "private"], ["slug", "admin_ops"] ] }, // Kind 10123: Skill adoption list // References which public skills this agent has adopted. { "kind": 10123, "content": "", "tags": [ ["a", "31123:55993e3db0ed7bf07395fd44c2d695c224d195553a1aff7320a18e41679d9c7c:long_form_note"], ["a", "31123:55993e3db0ed7bf07395fd44c2d695c224d195553a1aff7320a18e41679d9c7c:post_readme_to_nostr"], ["app", "didactyl"], ["scope", "public"] ] } ] }