Files
didactyl/docs/SKILLS.md

12 KiB

Didactyl — Skills

See also: TOOLS.md

Overview

A skill is a self-contained LLM execution unit stored as a Nostr event. Each skill defines what the LLM sees (context template), which model runs it (LLM specification with fallbacks), what tools are available, and whether the agent's identity (soul) is included.

Skills are portable, shareable, and discoverable — they live on Nostr relays as standard events.


Skill Events

Kind Purpose Replaceable?
31123 Public skill definition Yes, by d-tag
31124 Private skill definition Yes, by d-tag
10123 Skill adoption list Yes, single per pubkey

Skill Content

The skill event's content field is a JSON object that defines the complete execution specification:

{
  "kind": 31123,
  "content": {
    "description": "Check spelling and grammar",
    "context_mode": "full",
    "llm": "openai/gpt-4o-mini, cheap",
    "tools": false,
    "max_tokens": 2000,
    "temperature": 0.1,
    "template": "system:\nYou are a spelling and grammar checker.\n\nRules:\n- Fix spelling errors\n- Fix grammar errors\n- Preserve original formatting\n- Ignore: API, JSON, HTTP, nostr, pubkey, npub, nsec, NIP\n- Canadian English preferred\n- Return ONLY the corrected text, no explanations\n\nuser:\n{{message}}"
  },
  "tags": [
    ["d", "spellcheck"],
    ["scope", "public"],
    ["description", "Spelling and grammar checker"]
  ]
}

Content Fields

Field Type Default Description
description string Human-readable description
context_mode string inject inject, full, or override
llm string default LLM fallback chain
tools bool/array true false = no tools, true = all tools, array = specific tool names
template string Context template (required for full mode)
soul bool true Whether to include the agent's soul in context
max_tokens int Override max tokens for this skill
temperature float Override temperature for this skill

Context Modes

Skills control how the LLM context window is assembled.

inject

The skill's instructions are appended to the agent's soul context. The soul is always present.

┌─────────────────────────────────────┐
│ Soul (agent identity + rules)       │
│                                     │
│  ┌─────────────────────────────┐    │
│  │ Skill instructions          │    │
│  ├─────────────────────────────┤    │
│  │ Admin context, history, etc │    │
│  └─────────────────────────────┘    │
│                                     │
│  User message                       │
└─────────────────────────────────────┘

full

The skill provides its own context template. The soul is not included unless the template explicitly references {{soul}}. This is for specialized, focused tasks that don't need the agent's identity.

┌─────────────────────────────────────┐
│ Skill-defined system prompt         │
│ (from skill template)               │
│                                     │
│  User message                       │
└─────────────────────────────────────┘

A full mode skill can still include the soul if desired:

system:
{{soul}}

You are now in translation mode. Translate the following to {{target_language}}.
Respond ONLY with the translation.

user:
{{message}}

override

The skill replaces the soul's system prompt but keeps the standard context assembly structure (admin context, history, tools, etc.).

Summary

Mode Soul Template Tools Use Case
inject Always Soul's template + skill instructions appended Agent default Behavioral rules, knowledge
full Unless {{soul}} in template Skill provides template Skill specifies Spellcheck, translation, focused analysis
override Replaced by skill Soul's template structure Agent default Different personality, same capabilities

Template Variables

A skill template can reference these context parts:

Variable Source
{{soul}} The agent's identity/system context
{{admin_profile}} Admin kind 0 profile
{{admin_notes}} Admin recent notes
{{admin_relays}} Admin relay list
{{adopted_skills}} Other adopted skill instructions
{{dm_history}} Recent DM conversation
{{message}} Current user message
{{triggering_event}} For triggered skills, the event JSON
{{tools}} Available tool schemas

LLM Specification with Fallback Chains

Each skill specifies which LLM to use with CSS font-family-style fallbacks. The runtime tries each model in order; if one is unavailable (API error, rate limit, not configured), it falls back to the next.

Format

model-spec := model-ref ["," model-ref]*
model-ref  := provider "/" model-name
            | category-alias

Examples

Skill LLM Spec
Spelling checker openai/gpt-4o-mini, cheap
Complex analysis anthropic/claude-sonnet-4-20250514, openai/gpt-4o, smart
Translation openai/gpt-4o-mini, fast
Default behavior default

Category Aliases

Aliases map to models in the agent's config:

{
  "llm": {
    "provider": "openai",
    "model": "gpt-4o",
    "aliases": {
      "fast": "openai/gpt-4o-mini",
      "cheap": "openai/gpt-4o-mini",
      "smart": "anthropic/claude-sonnet-4-20250514"
    }
  }
}

If all specified models fail, the agent's default model is used as a last resort.

sequenceDiagram
    participant Skill as Skill Spec
    participant Resolver as LLM Resolver
    participant API1 as Model 1
    participant API2 as Model 2
    participant Default as Default Model

    Skill->>Resolver: "anthropic/claude-sonnet, openai/gpt-4o-mini, cheap"
    Resolver->>API1: try anthropic/claude-sonnet
    alt Available
        API1-->>Resolver: ✅
    else Unavailable
        API1-->>Resolver: ❌
        Resolver->>API2: try openai/gpt-4o-mini
        alt Available
            API2-->>Resolver: ✅
        else Unavailable
            Resolver->>Default: resolve "cheap" alias
        end
    end

Triggered Skills

A triggered skill has a Nostr subscription filter attached. When matching events arrive, the skill executes automatically.

Trigger Tags

Tag Required Description
trigger Yes Trigger type: nostr-subscription
filter Yes JSON-encoded Nostr subscription filter
action No template or llm (default: llm)
enabled No Whether active (default: true)

Template Actions

Fast, deterministic, no LLM. The skill content is a template with placeholders from the triggering event:

DM admin: '{author_display_name} posted: {content_preview}'

Placeholders: {event_id}, {pubkey}, {author_display_name}, {kind}, {content}, {content_preview}, {created_at}, {relay_url}

Output prefixes: DM admin: ..., DM <pubkey>: ..., POST: ..., LOG: ...

LLM-Mediated Actions

The skill content defines the execution context. The triggering event is available as {{triggering_event}}. The skill's LLM spec, context mode, and tool access all apply.

{
  "kind": 31124,
  "content": {
    "description": "Analyze mentions and notify admin",
    "context_mode": "full",
    "llm": "openai/gpt-4o-mini, cheap",
    "tools": ["nostr_dm_send"],
    "template": "system:\nYou monitor Nostr mentions. When the triggering event mentions Bitcoin or Lightning, summarize it and DM the admin. Otherwise, ignore silently.\n\nTriggering event:\n{{triggering_event}}"
  },
  "tags": [
    ["d", "mention-monitor"],
    ["trigger", "nostr-subscription"],
    ["filter", "{\"#p\":[\"<admin_pubkey>\"],\"kinds\":[1]}"],
    ["action", "llm"],
    ["enabled", "true"]
  ]
}

Trigger Lifecycle

flowchart TD
    subgraph Creation
        ADMIN_CMD[Admin: 'Warn me when @jack posts'] --> LLM_REASON[LLM resolves pubkey + builds skill]
        LLM_REASON --> SKILL_CREATE[skill_create with trigger tags]
        SKILL_CREATE --> PUBLISHED[Skill published to Nostr]
    end

    subgraph Activation
        STARTUP[Didactyl starts up] --> LOAD_SKILLS[Load adopted skills from kind 10123]
        LOAD_SKILLS --> FIND_TRIGGERS[Find skills with trigger tags]
        FIND_TRIGGERS --> SUBSCRIBE[Create Nostr subscriptions for each filter]
    end

    subgraph Execution
        EVENT_IN[Matching event arrives] --> LOOKUP[Find associated skill]
        LOOKUP --> CHECK_TYPE{Action type?}
        CHECK_TYPE -->|template| INTERPOLATE[Interpolate + execute prefix]
        CHECK_TYPE -->|llm| RESOLVE[Resolve LLM + assemble context + run]
    end

    PUBLISHED --> LOAD_SKILLS

Execution Flow

sequenceDiagram
    participant Input as Message/Trigger
    participant Dispatch as Dispatcher
    participant Skill as Skill Resolver
    participant LLM_Res as LLM Resolver
    participant Ctx as Context Assembler
    participant LLM as LLM API

    Input->>Dispatch: message or trigger event
    Dispatch->>Skill: which skill handles this?

    alt No specific skill
        Skill-->>Dispatch: use default soul context
        Dispatch->>LLM_Res: resolve "default" LLM
    else Skill with context_mode=inject
        Skill-->>Dispatch: soul + skill instructions
        Dispatch->>LLM_Res: resolve skill.llm or "default"
    else Skill with context_mode=full
        Skill-->>Dispatch: skill template only
        Dispatch->>LLM_Res: resolve skill.llm
    end

    LLM_Res->>LLM_Res: try models in fallback order
    LLM_Res-->>Dispatch: resolved model

    Dispatch->>Ctx: assemble context per mode
    Ctx->>LLM: request with resolved model + context
    LLM-->>Input: response

The Soul and Skills

The soul is the agent's default identity and context template. Skills interact with it based on their context mode:

  • inject — soul always present; skill instructions layered on top
  • full — soul absent unless template includes {{soul}}
  • override — skill replaces soul prompt, keeps standard context structure

A spelling checker runs with no soul — purely functional, minimal context, cheap model. A complex analysis skill includes the full soul and all context parts. The soul is the default, not a requirement.


Limits and Safety

Limit Default Description
Max concurrent triggers 16 Prevents resource exhaustion
Trigger cooldown 60s per skill Prevents rapid-fire execution
LLM action rate limit 10/min Prevents runaway LLM costs
Template action rate limit 60/min Prevents DM spam

Storage on Nostr

Data Storage
Skills Kind 31123/31124 events
Adopted skills Kind 10123 event
Trigger definitions Tags on skill events

Future Extensions

Extension Description
cron triggers Time-based triggers
webhook triggers HTTP webhook triggers
chain triggers Output of one skill triggers another
Skill composition Pipeline multiple skills
Agent-to-agent sharing Discover and adopt skills across agents
Trigger marketplace Popular triggers rise via adoption count

  • Tool architecture and complete tool catalog: TOOLS.md
  • Project overview and runtime behavior: README.md