Files
didactyl/docs/TOOLS.md

19 KiB

Didactyl — Tools

See also: SKILLS.md · CONTEXT.md

Overview

Didactyl is a Nostr-first sovereign AI agent that reasons with an LLM and takes actions through tools.

This document describes the tools architecture: what tools are, how they are exposed to the model, how execution loops work, what tool categories exist, and how access is gated.


What Tools Are

Tools are in the agent's hands — the chisels in the woodshop. They are hardcoded C functions that the LLM can invoke during a conversation to take actions in the world.

A skill teaches the agent how to carve — the technique, the judgment, the decision-making. A tool is the chisel — the physical capability. The skill never directly uses the chisel without the craftsperson (the LLM) in the loop. If you want a hardcoded program that runs without reasoning, that's a tool or an external program — not a skill.

How Tools Work

  1. A trigger fires (DM, cron, subscription, webhook, or chain) — see SKILLS.md
  2. The agent builds the context window from triggered skills and their {{...}} references
  3. The agent builds an LLM request with the context, triggering event, and a JSON schema of available tools
  4. The LLM decides whether to call a tool or respond directly
  5. If a tool is called, didactyl executes it and feeds the result back to the LLM
  6. The loop repeats until the LLM produces a final text response
  7. For DM triggers, the response is sent back as a DM
Trigger fires (DM, cron, subscription, webhook, chain)
  │
  ├─ Build context from triggered skills
  ├─ Build tool schemas (filtered by skill's tools tag)
  │
  ├─ Send to LLM: context + tool schemas
  │
  │   ┌─────────────────────────────────────┐
  │   │ LLM reasons about the request       │
  │   │                                     │
  │   │ Option A: call a tool               │
  │   │   → agent executes tool             │
  │   │   → feeds result back to LLM        │
  │   │   → loop continues                  │
  │   │                                     │
  │   │ Option B: produce text response     │
  │   │   → loop ends                       │
  │   └─────────────────────────────────────┘
  │
  └─ Deliver response (DM reply, chain forward, etc.)

Tool Categories

Nostr Event & Messaging Tools

Tool Description
nostr_post Publish a Nostr event to connected relays
nostr_delete Request deletion of one or more previously published events (NIP-09 kind 5)
nostr_react React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)
nostr_query Query events from relays using a Nostr filter
nostr_my_events Query recent events authored by this agent and return kind, event_id, timestamp, d_tag, and cache presence
nostr_dm_send Send a NIP-04 encrypted DM
nostr_dm_send_nip17 Send a private DM using NIP-17 gift wrap protocol

Nostr Identity & Utility Tools

Tool Description
nostr_profile_get Look up a Nostr profile (kind 0 metadata) by pubkey
nostr_nip05_lookup Look up or verify a NIP-05 identifier (user@domain)
nostr_encode Encode a Nostr entity into nostr: URI (npub, note, nprofile, nevent, naddr)
nostr_decode Decode a Nostr bech32/nostr: URI into components
nostr_relay_status Get connection status and statistics for all relays
nostr_relay_info Fetch NIP-11 relay information document
nostr_subscription_status List currently managed runtime Nostr subscriptions and filters
nostr_subscription_set Update one managed runtime subscription by name (toggle enabled and/or replace filter)
nostr_encrypt Encrypt plaintext using NIP-44 for a recipient
nostr_decrypt Decrypt NIP-44 ciphertext from a sender
nostr_list_manage Add/remove tag tuples in replaceable list events (NIP-51 style)
nostr_block_list View blocked pubkeys, event IDs, or hashtags from the local encrypted kind-10000 block list cache
nostr_block_edit Add or remove blocked tuples in kind-10000 block list; entries are private (encrypted) by default

Context & Identity Tools

These tools provide the agent with information about itself and its administrator, often used to build system prompts or context blocks.

Tool Description
nostr_pubkey Return this agent's pubkey in hex format
nostr_npub Return this agent's pubkey encoded as npub bech32
my_pubkey Alias for nostr_pubkey
my_npub Alias for nostr_npub
agent_identity Build agent identity context block with pubkey and npub
admin_identity Build admin identity context block from cached runtime metadata
nostr_admin_profile Build admin profile context block from cached kind 0 metadata
nostr_admin_contacts Build admin contacts context block from cached kind 3 contact list
nostr_admin_relays Build admin relay context block from cached kind 10002 data
nostr_admin_notes Build admin notes context block from cached kind 1 notes
nostr_agent_profile Build agent profile context block from cached kind 0 metadata
nostr_agent_contacts Build agent contacts context block from cached kind 3 contact list
nostr_agent_relays Build agent relay context block from cached kind 10002 data
nostr_agent_notes Build agent notes context block from cached kind 1 notes
my_kind0_profile Alias for nostr_agent_profile
my_contacts Alias for nostr_agent_contacts
my_relays Alias for nostr_agent_relays
my_notes Alias for nostr_agent_notes

Skills & Trigger Tools

These tools manage skill and trigger lifecycle; skill semantics and trigger execution details are documented in SKILLS.md.

Tool Description
skill_create Create or update a skill definition as kind 31123/31124 and optionally auto-adopt it (content should be markdown instructions; runtime handles role packaging)
skill_edit Edit an existing self skill by d tag and republish it as kind 31123/31124 (content should remain markdown-first)
skill_list List available skills discovered online (agent + admin), with adoption status and optional filters
skill_adopt Adopt a skill by adding its address to kind 10123 adoption list
skill_remove Remove a skill address from kind 10123 adoption list
skill_search Search public skills by query/author and optionally rank by adoption popularity
trigger_list List active triggered skills and their runtime status

Task & Memory Tools

These tools manage the agent's short-term and long-term memory, persisted on Nostr.

Tool Description
task_list Build current task list context block from agent task memory on Nostr
task_manage Manage agent short-term task memory stored on Nostr kind 30078 (d=tasks): list/add/update/remove/clear/replace
memory_save Prepend a new entry to encrypted agent memory (kind 30078, d=memory) and truncate oldest content if needed
memory_recall Recall encrypted agent memory (kind 30078, d=memory)

LLM / Model Management Tools

Tool Description
model_get Get current active LLM runtime configuration (excluding API key)
model_set Update active LLM configuration and persist it to Nostr kind 30078 (d=llm_config)
model_list List available model IDs using provider OpenAI-compatible /models endpoint

Configuration Persistence Tools

Tool Description
config_store Encrypt and publish agent config as kind 30078 for a given d_tag
config_recall Fetch and decrypt agent config kind 30078 by d_tag

System & Runtime Tools

Tool Description
agent_version Return current Didactyl version and metadata from build macros
local_http_fetch Fetch HTTP(S) resources with optional method, headers, timeout, and body
local_shell_exec Execute a shell command and return stdout/stderr
local_file_read Read a local file as text from the configured working directory
local_file_write Write text content to a local file in the configured working directory
tool_list List available tools with name, description, and JSON parameter schema

Cashu Wallet Tools (NIP-60)

Tool Description
cashu_wallet_balance Return wallet balances aggregated by mint and unit from loaded token proofs
cashu_wallet_info Fetch mint info for a specific mint_url (or configured default mint)
cashu_wallet_mint_quote Request a mint quote for an amount and unit
cashu_wallet_mint_check Check whether a mint quote is paid/issued
cashu_wallet_mint_claim Claim newly minted proofs for a paid quote and persist token event
cashu_wallet_melt_quote Request a melt quote for a Lightning invoice/payment request
cashu_wallet_melt_pay Pay a melt quote using selected proofs and persist history/token rollover
cashu_wallet_check_proofs Ask mint for current proof states and summarize unspent/pending/spent proofs
cashu_wallet_receive_token Receive an ecash token string (cashuA/cashuB), swap to fresh proofs, and store it in wallet state
cashu_wallet_send_token Create an outbound ecash token from wallet proofs and return a cashuA/cashuB token string
cashu_wallet_mints_set Set wallet mints (NIP-60), public mints (NIP-61), or both

Blossom Tools

Tool Description
blossom_upload Upload a local file to a Blossom server and return blob metadata
blossom_download Download a Blossom blob to a local file path
blossom_head Fetch Blossom blob metadata by SHA-256
blossom_delete Delete a Blossom blob by SHA-256 using signed auth
blossom_list List Blossom blobs for a pubkey (defaults to agent pubkey)

Content Publishing Conveniences

Tool Description
nostr_post_readme Publish README.md as kind 30023 with deterministic d-tag readme.md
nostr_file_md_to_longform_post Read a markdown file and publish it as kind 30023 longform post (defaults d-tag to lowercase filename)

Tool Execution Examples

These examples show the JSON structure for tool calls.

Nostr Event & Messaging

nostr_post

{
  "name": "nostr_post",
  "arguments": {
    "kind": 1,
    "content": "Hello from Didactyl!",
    "tags": [["t", "didactyl"]]
  }
}

nostr_delete

{
  "name": "nostr_delete",
  "arguments": {
    "event_ids": ["<event_id_hex>"],
    "reason": "Mistake"
  }
}

nostr_react

{
  "name": "nostr_react",
  "arguments": {
    "event_id": "<event_id_hex>",
    "event_pubkey": "<pubkey_hex>",
    "reaction": "🤙"
  }
}

nostr_query

{
  "name": "nostr_query",
  "arguments": {
    "filter": {
      "kinds": [1],
      "limit": 5
    },
    "timeout_ms": 5000
  }
}

nostr_my_events

{
  "name": "nostr_my_events",
  "arguments": {
    "kind": 1,
    "limit": 10
  }
}

nostr_dm_send

{
  "name": "nostr_dm_send",
  "arguments": {
    "recipient_pubkey": "<pubkey_hex>",
    "message": "Secret message"
  }
}

nostr_dm_send_nip17

{
  "name": "nostr_dm_send_nip17",
  "arguments": {
    "recipient_pubkey": "<pubkey_hex>",
    "message": "Private message via NIP-17",
    "subject": "Confidential"
  }
}

Nostr Identity & Utility

nostr_profile_get

{
  "name": "nostr_profile_get",
  "arguments": {
    "pubkey": "<pubkey_hex>"
  }
}

nostr_nip05_lookup

{
  "name": "nostr_nip05_lookup",
  "arguments": {
    "identifier": "user@domain.com"
  }
}

nostr_encode

{
  "name": "nostr_encode",
  "arguments": {
    "type": "npub",
    "hex": "<pubkey_hex>"
  }
}

nostr_decode

{
  "name": "nostr_decode",
  "arguments": {
    "uri": "nostr:npub1..."
  }
}

nostr_relay_status

{
  "name": "nostr_relay_status",
  "arguments": {}
}

nostr_relay_info

{
  "name": "nostr_relay_info",
  "arguments": {
    "relay_url": "wss://relay.damus.io"
  }
}

nostr_subscription_status

{
  "name": "nostr_subscription_status",
  "arguments": {}
}

nostr_subscription_set

{
  "name": "nostr_subscription_set",
  "arguments": {
    "name": "admin_context_profile",
    "enabled": true
  }
}

nostr_encrypt

{
  "name": "nostr_encrypt",
  "arguments": {
    "recipient_pubkey": "<pubkey_hex>",
    "plaintext": "Sensitive data"
  }
}

nostr_decrypt

{
  "name": "nostr_decrypt",
  "arguments": {
    "sender_pubkey": "<pubkey_hex>",
    "ciphertext": "<nip44_ciphertext>"
  }
}

nostr_list_manage

{
  "name": "nostr_list_manage",
  "arguments": {
    "list_kind": 10000,
    "action": "add",
    "items": [["p", "<pubkey_hex>"]]
  }
}

nostr_block_list

{
  "name": "nostr_block_list",
  "arguments": {
    "type": "p"
  }
}

nostr_block_edit

{
  "name": "nostr_block_edit",
  "arguments": {
    "action": "add",
    "items": [["p", "<pubkey_hex>"]],
    "public": false
  }
}

Context & Identity

nostr_pubkey / my_pubkey

{
  "name": "nostr_pubkey",
  "arguments": {}
}

agent_identity

{
  "name": "agent_identity",
  "arguments": {}
}

admin_identity

{
  "name": "admin_identity",
  "arguments": {}
}

nostr_admin_profile

{
  "name": "nostr_admin_profile",
  "arguments": {}
}

nostr_agent_notes / my_notes

{
  "name": "my_notes",
  "arguments": {}
}

Skills & Triggers

skill_create

{
  "name": "skill_create",
  "arguments": {
    "d": "weather-skill",
    "content": "## Weather Assistant\n\nYou provide concise weather summaries.\n\nInput:\n{{message}}",
    "description": "Fetches weather data",
    "trigger": "dm",
    "filter": "{\"from\":\"admin\"}",
    "auto_adopt": true
  }
}

skill_edit

{
  "name": "skill_edit",
  "arguments": {
    "d": "weather-skill",
    "description": "Updated weather skill description"
  }
}

skill_list

{
  "name": "skill_list",
  "arguments": {
    "adopted": true
  }
}

skill_adopt

{
  "name": "skill_adopt",
  "arguments": {
    "pubkey": "<author_pubkey_hex>",
    "d": "cool-skill"
  }
}

skill_search

{
  "name": "skill_search",
  "arguments": {
    "query": "bitcoin",
    "popular": true
  }
}

trigger_list

{
  "name": "trigger_list",
  "arguments": {}
}

Tasks & Memory

task_list

{
  "name": "task_list",
  "arguments": {}
}

task_manage

{
  "name": "task_manage",
  "arguments": {
    "action": "add",
    "text": "Finish documentation",
    "status": "active"
  }
}

memory_save

{
  "name": "memory_save",
  "arguments": {
    "content": "User likes coffee."
  }
}

memory_recall

{
  "name": "memory_recall",
  "arguments": {}
}

LLM & Configuration

model_get

{
  "name": "model_get",
  "arguments": {}
}

model_set

{
  "name": "model_set",
  "arguments": {
    "model": "gpt-4o",
    "temperature": 0.7
  }
}

config_store

{
  "name": "config_store",
  "arguments": {
    "d_tag": "custom_setting",
    "content": "{\"value\": 42}"
  }
}

config_recall

{
  "name": "config_recall",
  "arguments": {
    "d_tag": "custom_setting"
  }
}

System & Runtime

agent_version

{
  "name": "agent_version",
  "arguments": {}
}

local_http_fetch

{
  "name": "local_http_fetch",
  "arguments": {
    "url": "https://api.github.com/zen",
    "method": "GET"
  }
}

local_shell_exec

{
  "name": "local_shell_exec",
  "arguments": {
    "command": "ls -la"
  }
}

local_file_read

{
  "name": "local_file_read",
  "arguments": {
    "path": "README.md"
  }
}

local_file_write

{
  "name": "local_file_write",
  "arguments": {
    "path": "test.txt",
    "content": "Hello world",
    "append": false
  }
}

tool_list

{
  "name": "tool_list",
  "arguments": {}
}

Cashu Wallet

cashu_wallet_balance

{
  "name": "cashu_wallet_balance",
  "arguments": {}
}

cashu_wallet_mint_quote

{
  "name": "cashu_wallet_mint_quote",
  "arguments": {
    "amount": 100,
    "unit": "sat"
  }
}

cashu_wallet_receive_token

{
  "name": "cashu_wallet_receive_token",
  "arguments": {
    "token": "cashuA..."
  }
}

cashu_wallet_send_token

{
  "name": "cashu_wallet_send_token",
  "arguments": {
    "amount": 21
  }
}

cashu_wallet_mints_set

{
  "name": "cashu_wallet_mints_set",
  "arguments": {
    "target": "both",
    "wallet_mints": ["https://mint.host.com"],
    "public_mints": ["https://mint.host.com"]
  }
}

Security Model

Tool access is gated at two levels:

Sender Tier (DM triggers)

Tier Identity Tools Response
ADMIN Configured admin pubkey All tools Full LLM with context
WOT In admin's kind 3 contact list None Chat-only LLM
STRANGER Anyone else None Configurable static response

Skill Requirements (all triggers)

Skills declare which tools they need via requires_tool tags (see SKILLS.md — Requirements Tags). During execution, only the required and optional tools declared by the skill are exposed to the LLM. If a skill has no requires_tool tags, all available tools are exposed.


Tool Portability

Tool names serve as the capability vocabulary for cross-app skill portability. When a skill declares ["requires_tool", "http_fetch"], any app that provides an http_fetch capability can run that skill — regardless of how it implements the fetch internally.

Runtime Availability

Not all tools are available in every runtime. Tools that require specific host capabilities:

Tool Requires
local_shell_exec Host OS shell access
local_file_read Host filesystem
local_file_write Host filesystem
blossom_upload Filesystem + HTTP
blossom_download Filesystem + HTTP

Tools available in any runtime (including browser):

Tool Capability
nostr_* Nostr relay WebSocket connections
local_http_fetch HTTP client
memory_save / memory_recall Nostr event storage
cashu_wallet_* HTTP client + Nostr storage

Skills should declare requires_tool tags so apps can determine compatibility. See SKILLS.md — Requirements Tags.


  • Skill definitions, adoption, triggers, and autonomous activation: SKILLS.md
  • Context assembly model: CONTEXT.md