246 lines
12 KiB
Plaintext
246 lines
12 KiB
Plaintext
{
|
||
// ─── 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 `local_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 <admin_kind0_profile source=\"nostr_kind_0\">\n {{admin_kind0_json}}\n </admin_kind0_profile>\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 <admin_contacts source=\"nostr_kind_3\">\n {{admin_kind3_json}}\n </admin_contacts>\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 <admin_relays source=\"nostr_kind_10002\">\n {{admin_kind10002_json}}\n </admin_relays>\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 <admin_notes source=\"nostr_kind_1\">\n {{admin_kind1_json}}\n </admin_notes>\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 local_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"]
|
||
]
|
||
}
|
||
]
|
||
}
|