Didactyl
An unstoppable agentic system.
Didactyl boots on any internet-connected machine, connects to Nostr relays, listens for encrypted commands from its administrator, reasons with an LLM, and takes actions — posting events, querying relays, running shell commands — all orchestrated through Nostr.
Philosophy
Nostr-first. Where traditional agents ride on top of Linux — reading files, writing to disk — Didactyl rides on top of Nostr. Events are its files. Relays are its network bus. Blossom is its blob storage. The Linux host is just the runtime substrate.
Because all identity, communication, and memory live on Nostr, the agent is portable (start it anywhere) and sovereign (no single entity can erase its memory).
Current Status
MVP — Working chat agent with relay connectivity and LLM integration.
- Connects to configured Nostr relays with auto-reconnect
- Publishes agent profile (kind 0 metadata)
- Listens for NIP-04 encrypted DMs from authorized admin
- Forwards messages to an OpenAI-compatible LLM API
- Sends LLM responses back as encrypted DMs
- Runtime logging: relay status, connection health, message flow
Next: Agentic tool-use system — see plans/didactyl_agentic.md.
Quick Start
Prerequisites
- GCC with C99 support
- libcurl, libssl, libcrypto, libsecp256k1
- An OpenAI-compatible LLM API key (OpenAI, PPQ, Ollama, etc.)
- A Nostr keypair (nsec)
Build
make deps # builds nostr_core_lib
make # builds didactyl
Configure
Edit config.json:
{
"agent": {
"name": "Didactyl Agent",
"display_name": "Didactyl",
"about": "A sovereign AI agent on Nostr"
},
"keys": {
"nsec": "nsec1..."
},
"admin": {
"pubkey": "npub1... or hex pubkey"
},
"relays": [
"wss://relay.damus.io",
"wss://nos.lol"
],
"llm": {
"provider": "openai",
"api_key": "sk-...",
"model": "gpt-4o-mini",
"base_url": "https://api.openai.com/v1",
"max_tokens": 512,
"temperature": 0.7
}
}
Edit SYSTEM.md to define the agent's personality and instructions.
Run
./didactyl
Options:
./didactyl --config <path> # custom config file (default: ./config.json)
./didactyl --context <path> # custom context file (default: ./SYSTEM.md)
Talk to it
Send an encrypted DM to the agent's pubkey from the admin account using any Nostr client (Damus, Amethyst, Primal, etc.).
Architecture
┌─────────────────────────────────────────────┐
│ Didactyl │
│ │
│ ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│ │ config │ │ context │ │ agent │ │
│ │ loader │ │ loader │ │ loop │ │
│ └────┬────┘ └────┬────┘ └─────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ nostr_handler │ │
│ │ relay pool · subscribe · publish │ │
│ └──────────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────────┴──────────────────┐ │
│ │ LLM client │ │
│ │ OpenAI-compatible chat API │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
│ │
▼ ▼
Nostr Relays LLM API
Project Structure
.
├── config.json # Agent configuration
├── SYSTEM.md # Agent personality/instructions for LLM
├── Makefile # Build system
├── src/
│ ├── main.c # Entry point, signal handling, daemon loop
│ ├── config.c / .h # JSON config parsing, key decoding
│ ├── context.c / .h # SYSTEM.md file loader
│ ├── agent.c / .h # Core agent logic: receive → LLM → respond
│ ├── llm.c / .h # LLM HTTP API client (OpenAI-compatible)
│ ├── nostr_handler.c / .h # Relay pool, subscriptions, publish, DMs
│ └── secp_compat.c # secp256k1 API compatibility shim
├── plans/ # Architecture and planning documents
│ ├── didactyl_mvp.md
│ └── didactyl_agentic.md
└── README.md
Dependencies
| Dependency | Purpose | Source |
|---|---|---|
| nostr_core_lib | Nostr protocol: keys, events, NIPs, relay pool | Workspace (sibling directory) |
| cJSON | JSON parsing | Bundled in nostr_core_lib |
| libcurl | HTTPS for LLM API calls | System package |
| libssl / libcrypto | TLS for WebSocket relay connections | System package |
| libsecp256k1 | Schnorr signatures, ECDH | System package |
Roadmap
- MVP chat agent — DM in, LLM response out
- Relay pool with auto-reconnect and status logging
- Runtime diagnostics — relay health, message flow, LLM calls
- Agentic tool-use — LLM can call tools (nostr_post, nostr_query, shell_exec)
- Upgrade to NIP-17 gift-wrapped DMs
- Nostr-native data storage (kind 30078 app-specific events)
- Blossom blob storage integration
- Conversation memory on Nostr
- Config and SYSTEM.md stored as Nostr events
- Multi-turn conversation context window
- Agent-to-agent communication
License
TBD