Files
didactyl/docs/CONTEXT.md

8.9 KiB

Didactyl — LLM Context

See also: SKILLS.md · TOOLS.md

What Is Context?

Every time Didactyl talks to an LLM, it sends a context — the complete package of information the model needs to reason and respond.

Context is not just a prompt string; it is the full request payload:

  1. Messages — system/user/assistant/tool history
  2. Tool schemas — JSON descriptions of callable tools
  3. Model parameters — model, temperature, max tokens, seed, etc.

The context window is composed of skills — blocks of markdown instructions stacked together. See SKILLS.md for the canonical skill specification.


OpenAI-Compatible Chat Format

Didactyl uses OpenAI-compatible chat completions.

{
  "model": "claude-opus-4.6",
  "messages": [
    {"role": "system", "content": "..."},
    {"role": "user", "content": "..."}
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "nostr_post",
        "description": "Publish a Nostr event",
        "parameters": {"type":"object"}
      }
    }
  ],
  "temperature": 0.7,
  "max_tokens": 512
}

Message Roles

Role Purpose
system Instructions and injected context (from skills)
user Input message or trigger payload
assistant Model responses / tool call envelopes
tool Tool execution results fed back to model

Context Assembly — Two-Layer Model

Context is assembled using a two-layer model driven by triggers and the adoption list.

Layer 1: Triggered Skills

When a trigger event occurs (DM, cron, subscription, webhook, chain), Didactyl walks the 10123 adoption list and finds all skills whose trigger matches the current event. These skills form layer 1 of the context window, in adoption-list order.

Only triggered skills can be in layer 1 — the trigger system is what puts them there.

Layer 2: Referenced Skills

Within each layer 1 skill, {{skill_d_tag}} template variables resolve to adopted skills' content. These are embedded inline — the same way tool-based template variables are resolved.

Non-triggered skills (skills with no trigger tags) can only enter the context window via layer 2 references.

Assembly Steps

Trigger event occurs (DM, cron, subscription, webhook, chain)
  │
  ├─ Walk adoption list (10123)
  │    │
  │    ├─ Skill has trigger matching this event?
  │    │    ├─ YES → add to context (layer 1)
  │    │    │    └─ Resolve {{...}} references (layer 2)
  │    │    │         ├─ Known tool? → execute tool, insert result
  │    │    │         ├─ Adopted skill d-tag? → insert skill content
  │    │    │         └─ Unknown? → resolve to empty
  │    │    │
  │    │    └─ NO → skip (not in this context)
  │    │
  │    └─ Continue to next skill in list
  │
  ├─ Append triggering event payload
  │    └─ For DM triggers: always append raw message content
  │
  ├─ Attach tool schemas (filtered by skill requires_tool tags)
  │
  ├─ Apply execution parameters (llm, temperature, max_tokens)
  │    └─ Walk LLM fallback chain until usable model found
  │
  └─ Send to LLM

Visualization

╔══════════════════════════════════════════╗
║           CONTEXT WINDOW                 ║
║                                          ║
║  ┌────────────────────────────────────┐  ║
║  │ Layer 1: personality (dm trigger)  │  ║
║  │                                    │  ║
║  │  ┌──────────────────────────────┐  │  ║
║  │  │ Layer 2: {{identity}}        │  │  ║
║  │  │ You are Didactyl. npub1...   │  │  ║
║  │  └──────────────────────────────┘  │  ║
║  │                                    │  ║
║  │  You speak concisely and directly. │  ║
║  └────────────────────────────────────┘  ║
║  ┌────────────────────────────────────┐  ║
║  │ Layer 1: chat (dm trigger)         │  ║
║  │                                    │  ║
║  │  Respond helpfully to the admin.   │  ║
║  │  Use tools as needed.              │  ║
║  │                                    │  ║
║  │  tools: [nostr_query, nostr_dm]    │  ║
║  └────────────────────────────────────┘  ║
║  ┌────────────────────────────────────┐  ║
║  │ DM content (always last)           │  ║
║  │                                    │  ║
║  │ "Who mentioned me today?"          │  ║
║  └────────────────────────────────────┘  ║
║                                          ║
╚══════════════════════════════════════════╝

Why Order Matters

  • Earlier skills in the adoption list appear first in the context window.
  • Earlier instructions generally set broader tone/policy.
  • Later instructions can narrow/specialize behavior.
  • If instructions conflict, prompt-order effects apply.

Context Parts

Part Source Description
Layer 1 skills Triggered skills from adoption list Skills whose trigger matches the current event, in adoption-list order
Layer 2 skills {{skill_d_tag}} references Adopted skills embedded inside layer 1 skills
Resolved variables Tool outputs Runtime data inserted into templates via {{...}}
Triggering event DM content / event payload Current request — always appended after skills
Tool schemas Tool registry, filtered by skill requires_tool tags Capability declaration for tool calling
Runtime params Skill event tags + LLM fallback chain Model, temperature, max_tokens, etc.

Template Variable Resolution

When the engine encounters {{variable_name}} in a skill template:

  1. Check known tools — if it matches a tool name, execute the tool and insert the result
  2. Check adopted skills — if it matches an adopted skill's d-tag, insert that skill's content (layer 2)
  3. Neither — resolve to empty (for portability)

This means {{admin_profile}} calls the nostr_admin_profile tool, while {{identity}} inserts the adopted "identity" skill's content. The skill author doesn't need to know which is which — the resolution is transparent.

See SKILLS.md — Template Variables for the full variable table.


Execution Parameters

Execution parameters control the LLM call: which model, what temperature, how many tokens, which tools.

Resolution Order

  1. Start with agent defaults
  2. Apply top-level execution tags from the skill event
  3. Walk the llm fallback chain until a usable model is found
  4. Execute
  5. Restore defaults after the run

LLM Fallback Chain

The llm tag uses a CSS font-stack style fallback: provider/model, provider/model, ..., capability_keyword

["llm", "anthropic/claude-sonnet-4-20250514, openai/gpt-4o-mini, cheap"]

See SKILLS.md — LLM Fallback Chain for the full format and capability keywords.


Context Compaction

During long-running tool loops, the context window can grow as tool call/result pairs accumulate. When context approaches the model's token limit, compaction prevents overflow:

  1. Track approximate token usage of the messages array
  2. When approaching ~70% of the model's context window, inject a summarization request
  3. The LLM summarizes progress so far into a condensed form
  4. Replace detailed tool history with the summary
  5. Continue execution with the compacted context

This allows skills to run complex multi-step tasks without hitting context limits.


Token Budget

Context cost is controlled by:

  • Number of triggered skills matching the event (layer 1 count)
  • Size of referenced skills (layer 2 content)
  • Tool call/result accumulation during execution
  • Context compaction threshold (~70% of model window)
  • Per-skill model/runtime parameter choices

Use runtime context inspection endpoints (GET /api/context/current, GET /api/context/parts) to see the exact payload before LLM calls.