v0.2.21 - Fix markdown context assembly and logging: add Anvil DM trigger skill config, preserve H1 title on fallback, convert full-mode turn snapshots to readable markdown, and sync Anvil service restart/deploy behavior
This commit is contained in:
12
.dockerignore
Normal file
12
.dockerignore
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.roo/
|
||||||
|
*.log
|
||||||
|
*.nsec.debug.log
|
||||||
|
context.log.md
|
||||||
|
d-log.txt
|
||||||
|
tests/results/
|
||||||
|
|
||||||
|
# Keep nostr_core_lib sources but exclude VCS metadata to avoid huge build context
|
||||||
|
nostr_core_lib/.git/
|
||||||
|
nostr_core_lib/**/.git/
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -33,5 +33,7 @@ a.out
|
|||||||
|
|
||||||
# Local secrets
|
# Local secrets
|
||||||
genesis.jsonc
|
genesis.jsonc
|
||||||
|
genesis.anvil.jsonc
|
||||||
|
anvil.service
|
||||||
tests/configs/test_genesis.jsonc
|
tests/configs/test_genesis.jsonc
|
||||||
tests/configs/test_keys.jsonc
|
tests/configs/test_keys.jsonc
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ RUN NOSTR_LIB=$(ls /build/nostr_core_lib/libnostr_core_*.a 2>/dev/null | head -1
|
|||||||
src/tools/tool_task.c src/tools/tool_nostr_list.c src/tools/tool_nostr_block.c src/tools/tool_local.c \
|
src/tools/tool_task.c src/tools/tool_nostr_list.c src/tools/tool_nostr_block.c src/tools/tool_local.c \
|
||||||
src/tools/tool_skill.c src/tools/tool_nostr_post.c src/tools/tool_memory.c src/tools/tool_config.c src/tools/tool_cashu_wallet.c src/tools/tool_blossom.c src/trigger_manager.c \
|
src/tools/tool_skill.c src/tools/tool_nostr_post.c src/tools/tool_memory.c src/tools/tool_config.c src/tools/tool_cashu_wallet.c src/tools/tool_blossom.c src/trigger_manager.c \
|
||||||
src/cashu_wallet.c src/nostr_block_list.c src/prompt_template.c src/http_api.c src/setup_wizard.c src/mongoose.c src/debug.c \
|
src/cashu_wallet.c src/nostr_block_list.c src/prompt_template.c src/http_api.c src/setup_wizard.c src/mongoose.c src/debug.c \
|
||||||
|
src/json_to_markdown.c src/context_roles.c src/context_format.c \
|
||||||
-o /build/didactyl_static \
|
-o /build/didactyl_static \
|
||||||
$NOSTR_LIB \
|
$NOSTR_LIB \
|
||||||
-lsecp256k1 \
|
-lsecp256k1 \
|
||||||
|
|||||||
11
Makefile
11
Makefile
@@ -41,7 +41,10 @@ SRCS = \
|
|||||||
$(SRC_DIR)/setup_wizard.c \
|
$(SRC_DIR)/setup_wizard.c \
|
||||||
$(SRC_DIR)/mongoose.c \
|
$(SRC_DIR)/mongoose.c \
|
||||||
$(SRC_DIR)/debug.c \
|
$(SRC_DIR)/debug.c \
|
||||||
$(SRC_DIR)/nostr_block_list.c
|
$(SRC_DIR)/nostr_block_list.c \
|
||||||
|
$(SRC_DIR)/json_to_markdown.c \
|
||||||
|
$(SRC_DIR)/context_roles.c \
|
||||||
|
$(SRC_DIR)/context_format.c
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(SRC_DIR) \
|
-I$(SRC_DIR) \
|
||||||
@@ -113,4 +116,8 @@ clean:
|
|||||||
rm -f $(TARGET)
|
rm -f $(TARGET)
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
.PHONY: all deps clean force-version
|
test_pool: $(NOSTR_LIB) test_pool.c
|
||||||
|
@if [ -z "$(NOSTR_LIB)" ]; then echo "nostr_core_lib static library not found; run 'make deps'"; exit 1; fi
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDES) -o $@ test_pool.c $(NOSTR_LIB) $(LDFLAGS)
|
||||||
|
|
||||||
|
.PHONY: all deps clean force-version test_pool
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ Skills compose by adoption-list order (`10123`) and trigger tags carry runtime e
|
|||||||
|
|
||||||
Didactyl will support local inference, which is very privacy preserving. Remote inference does however have it's advantages, and in those cases Didactyl supports using Bitcoin Lightning and eCash inference providers.
|
Didactyl will support local inference, which is very privacy preserving. Remote inference does however have it's advantages, and in those cases Didactyl supports using Bitcoin Lightning and eCash inference providers.
|
||||||
|
|
||||||
## Current Status — v0.2.20
|
## Current Status — v0.2.21
|
||||||
|
|
||||||
**Active build — this project is barely working. Experiment at your own risk.**
|
**Active build — this project is barely working. Experiment at your own risk.**
|
||||||
|
|
||||||
> Last release update: v0.2.20 — Improve automated test harness process/log watching/reporting and refresh test config examples
|
> Last release update: v0.2.21 — Fix markdown context assembly and logging: add Anvil DM trigger skill config, preserve H1 title on fallback, convert full-mode turn snapshots to readable markdown, and sync Anvil service restart/deploy behavior
|
||||||
|
|
||||||
- Connects to configured relays with auto-reconnect and relay state transition logging
|
- Connects to configured relays with auto-reconnect and relay state transition logging
|
||||||
- Publishes configured startup events per relay as each relay becomes connected
|
- Publishes configured startup events per relay as each relay becomes connected
|
||||||
|
|||||||
@@ -68,33 +68,52 @@ if [ -d "$SCRIPT_DIR/build" ]; then
|
|||||||
echo "Removed legacy build directory: $SCRIPT_DIR/build"
|
echo "Removed legacy build directory: $SCRIPT_DIR/build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if Docker is available
|
# Detect available OCI container runtime (prefer Docker, fallback to Podman)
|
||||||
if ! command -v docker &> /dev/null; then
|
if command -v docker &> /dev/null; then
|
||||||
echo "ERROR: Docker is not installed or not in PATH"
|
DOCKER_CMD="docker"
|
||||||
|
RUNTIME_NAME="Docker"
|
||||||
|
elif command -v podman &> /dev/null; then
|
||||||
|
DOCKER_CMD="podman"
|
||||||
|
RUNTIME_NAME="Podman"
|
||||||
|
else
|
||||||
|
echo "ERROR: No supported container runtime found in PATH"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Docker is required to build MUSL static binaries."
|
echo "This build requires either Docker or Podman."
|
||||||
echo "Please install Docker:"
|
echo "Install one of the following:"
|
||||||
echo " - Ubuntu/Debian: sudo apt install docker.io"
|
echo " - Docker (Ubuntu/Debian): sudo apt install docker.io"
|
||||||
echo " - Or visit: https://docs.docker.com/engine/install/"
|
echo " - Podman (Ubuntu/Debian): sudo apt install podman"
|
||||||
echo ""
|
echo ""
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if Docker daemon is running
|
# Check if runtime daemon/service is usable
|
||||||
if ! docker info &> /dev/null; then
|
if ! $DOCKER_CMD info &> /dev/null; then
|
||||||
echo "ERROR: Docker daemon is not running or user not in docker group"
|
# Docker is installed but current user may not yet have docker-group membership in this shell.
|
||||||
|
# If passwordless sudo is available, transparently fall back to sudo docker.
|
||||||
|
if [ "$DOCKER_CMD" = "docker" ] && command -v sudo &> /dev/null && sudo -n docker info &> /dev/null; then
|
||||||
|
DOCKER_CMD="sudo docker"
|
||||||
|
echo "⚠ Docker requires elevated privileges in this shell; using sudo docker"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Please start Docker and ensure you're in the docker group:"
|
else
|
||||||
|
echo "ERROR: $RUNTIME_NAME is installed but not usable"
|
||||||
|
echo ""
|
||||||
|
if [ "$DOCKER_CMD" = "docker" ]; then
|
||||||
|
echo "Please start Docker and ensure your user can access it:"
|
||||||
echo " - sudo systemctl start docker"
|
echo " - sudo systemctl start docker"
|
||||||
echo " - sudo usermod -aG docker $USER && newgrp docker"
|
echo " - sudo usermod -aG docker $USER && newgrp docker"
|
||||||
echo " - Or start Docker Desktop"
|
echo " - Or log out and back in after adding to docker group"
|
||||||
|
echo " - Or run this script with sudo"
|
||||||
|
else
|
||||||
|
echo "Please verify Podman is configured for your user:"
|
||||||
|
echo " - podman info"
|
||||||
|
echo " - For rootless setup, ensure subuid/subgid are configured"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DOCKER_CMD="docker"
|
echo "✓ $RUNTIME_NAME is available and running"
|
||||||
|
|
||||||
echo "✓ Docker is available and running"
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Detect architecture (or use explicit target platform override)
|
# Detect architecture (or use explicit target platform override)
|
||||||
@@ -176,10 +195,10 @@ fi
|
|||||||
|
|
||||||
# Check if Alpine base image is cached
|
# Check if Alpine base image is cached
|
||||||
echo "Checking for cached Alpine Docker image..."
|
echo "Checking for cached Alpine Docker image..."
|
||||||
if ! docker images alpine:3.19 --format "{{.Repository}}:{{.Tag}}" | grep -q "alpine:3.19"; then
|
if ! $DOCKER_CMD images alpine:3.19 --format "{{.Repository}}:{{.Tag}}" | grep -q "alpine:3.19"; then
|
||||||
echo "⚠ Alpine 3.19 image not found in cache"
|
echo "⚠ Alpine 3.19 image not found in cache"
|
||||||
echo "Attempting to pull Alpine 3.19 image..."
|
echo "Attempting to pull Alpine 3.19 image..."
|
||||||
if ! docker pull alpine:3.19; then
|
if ! $DOCKER_CMD pull alpine:3.19; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "ERROR: Failed to pull Alpine 3.19 image"
|
echo "ERROR: Failed to pull Alpine 3.19 image"
|
||||||
echo "This is required for the static build."
|
echo "This is required for the static build."
|
||||||
@@ -239,11 +258,25 @@ $DOCKER_CMD cp "$CONTAINER_ID:/didactyl_static" "$OUTPUT_DIR/$OUTPUT_NAME" || {
|
|||||||
# Clean up container
|
# Clean up container
|
||||||
$DOCKER_CMD rm "$CONTAINER_ID" > /dev/null
|
$DOCKER_CMD rm "$CONTAINER_ID" > /dev/null
|
||||||
|
|
||||||
|
# If runtime command used sudo, copied file may be root-owned; fix ownership for current user
|
||||||
|
if [ ! -w "$OUTPUT_DIR/$OUTPUT_NAME" ]; then
|
||||||
|
if command -v sudo &> /dev/null && sudo -n true &> /dev/null; then
|
||||||
|
sudo chown "$(id -u):$(id -g)" "$OUTPUT_DIR/$OUTPUT_NAME" || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo "✓ Binary extracted to: $OUTPUT_DIR/$OUTPUT_NAME"
|
echo "✓ Binary extracted to: $OUTPUT_DIR/$OUTPUT_NAME"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Make binary executable
|
# Make binary executable (fallback to sudo if ownership/permissions still block)
|
||||||
chmod +x "$OUTPUT_DIR/$OUTPUT_NAME"
|
chmod +x "$OUTPUT_DIR/$OUTPUT_NAME" 2>/dev/null || {
|
||||||
|
if command -v sudo &> /dev/null && sudo -n true &> /dev/null; then
|
||||||
|
sudo chmod +x "$OUTPUT_DIR/$OUTPUT_NAME"
|
||||||
|
else
|
||||||
|
echo "ERROR: Could not set executable bit on $OUTPUT_DIR/$OUTPUT_NAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Verify the binary
|
# Verify the binary
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
|
|||||||
11
didactyl.code-workspace
Normal file
11
didactyl.code-workspace
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../anvil"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
||||||
@@ -79,7 +79,7 @@ Trigger event occurs (DM, cron, subscription, webhook, chain)
|
|||||||
│ ├─ Skill has trigger matching this event?
|
│ ├─ Skill has trigger matching this event?
|
||||||
│ │ ├─ YES → add to context (layer 1)
|
│ │ ├─ YES → add to context (layer 1)
|
||||||
│ │ │ └─ Resolve {{...}} references (layer 2)
|
│ │ │ └─ Resolve {{...}} references (layer 2)
|
||||||
│ │ │ ├─ Known tool? → execute tool, insert result
|
│ │ │ ├─ Known tool? → execute tool, convert JSON to markdown, insert
|
||||||
│ │ │ ├─ Adopted skill d-tag? → insert skill content
|
│ │ │ ├─ Adopted skill d-tag? → insert skill content
|
||||||
│ │ │ └─ Unknown? → resolve to empty
|
│ │ │ └─ Unknown? → resolve to empty
|
||||||
│ │ │
|
│ │ │
|
||||||
@@ -87,8 +87,13 @@ Trigger event occurs (DM, cron, subscription, webhook, chain)
|
|||||||
│ │
|
│ │
|
||||||
│ └─ Continue to next skill in list
|
│ └─ Continue to next skill in list
|
||||||
│
|
│
|
||||||
├─ Append triggering event payload
|
├─ Format Document
|
||||||
│ └─ For DM triggers: always append raw message content
|
│ ├─ Add `# Agent Name` title
|
||||||
|
│ ├─ Bump all skill headings down one level (# -> ##)
|
||||||
|
│ └─ Concatenate skills with `---` separators
|
||||||
|
│
|
||||||
|
├─ Split Roles
|
||||||
|
│ └─ Parse `system:` and `user:` markers to build API messages array
|
||||||
│
|
│
|
||||||
├─ Attach tool schemas (filtered by skill requires_tool tags)
|
├─ Attach tool schemas (filtered by skill requires_tool tags)
|
||||||
│
|
│
|
||||||
@@ -100,35 +105,27 @@ Trigger event occurs (DM, cron, subscription, webhook, chain)
|
|||||||
|
|
||||||
### Visualization
|
### Visualization
|
||||||
|
|
||||||
```
|
The assembled context is a single, coherent markdown document before being split into API messages:
|
||||||
╔══════════════════════════════════════════╗
|
|
||||||
║ CONTEXT WINDOW ║
|
```markdown
|
||||||
║ ║
|
system:
|
||||||
║ ┌────────────────────────────────────┐ ║
|
# Didactyl Agent
|
||||||
║ │ Layer 1: personality (dm trigger) │ ║
|
|
||||||
║ │ │ ║
|
- **npub**: `npub1...`
|
||||||
║ │ ┌──────────────────────────────┐ │ ║
|
|
||||||
║ │ │ Layer 2: {{identity}} │ │ ║
|
## Personality
|
||||||
║ │ │ You are Didactyl. npub1... │ │ ║
|
|
||||||
║ │ └──────────────────────────────┘ │ ║
|
You speak concisely and directly.
|
||||||
║ │ │ ║
|
|
||||||
║ │ You speak concisely and directly. │ ║
|
---
|
||||||
║ └────────────────────────────────────┘ ║
|
|
||||||
║ ┌────────────────────────────────────┐ ║
|
## Chat
|
||||||
║ │ Layer 1: chat (dm trigger) │ ║
|
|
||||||
║ │ │ ║
|
Respond helpfully to the admin.
|
||||||
║ │ Respond helpfully to the admin. │ ║
|
Use tools as needed.
|
||||||
║ │ Use tools as needed. │ ║
|
|
||||||
║ │ │ ║
|
user:
|
||||||
║ │ tools: [nostr_query, nostr_dm] │ ║
|
Who mentioned me today?
|
||||||
║ └────────────────────────────────────┘ ║
|
|
||||||
║ ┌────────────────────────────────────┐ ║
|
|
||||||
║ │ DM content (always last) │ ║
|
|
||||||
║ │ │ ║
|
|
||||||
║ │ "Who mentioned me today?" │ ║
|
|
||||||
║ └────────────────────────────────────┘ ║
|
|
||||||
║ ║
|
|
||||||
╚══════════════════════════════════════════╝
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Why Order Matters
|
### Why Order Matters
|
||||||
@@ -157,11 +154,11 @@ Trigger event occurs (DM, cron, subscription, webhook, chain)
|
|||||||
|
|
||||||
When the engine encounters `{{variable_name}}` in a skill template:
|
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
|
1. **Check known tools** — if it matches a tool name, execute the tool. The tool returns JSON, which the template engine automatically converts into readable markdown (bullet lists, bold keys) before inserting it into the document.
|
||||||
2. **Check adopted skills** — if it matches an adopted skill's d-tag, insert that skill's content (layer 2)
|
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)
|
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.
|
This means `{{admin_profile}}` calls the `nostr_admin_profile` tool and formats its JSON output as markdown, 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](SKILLS.md#template-variables) for the full variable table.
|
See [SKILLS.md — Template Variables](SKILLS.md#template-variables) for the full variable table.
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ The `content` field of a skill event IS the template — markdown instructions t
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"kind": 31123,
|
"kind": 31123,
|
||||||
"content": "system:\n# Spelling and Grammar Checker\n\nYou are a spelling and grammar checker.\n\n## Rules\n\n- Fix spelling errors\n- Fix grammar errors\n- Preserve original formatting\n- Return **ONLY** the corrected text, no explanations\n\nuser:\n{{message}}",
|
"content": "system:\n## Spelling and Grammar Checker\n\nYou are a spelling and grammar checker.\n\n### Rules\n\n- Fix spelling errors\n- Fix grammar errors\n- Preserve original formatting\n- Return **ONLY** the corrected text, no explanations\n\nuser:\n{{message}}",
|
||||||
"tags": [
|
"tags": [
|
||||||
["d", "spellcheck"],
|
["d", "spellcheck"],
|
||||||
["description", "Check spelling and grammar"],
|
["description", "Check spelling and grammar"],
|
||||||
@@ -81,6 +81,7 @@ The `content` field of a skill event IS the template — markdown instructions t
|
|||||||
```
|
```
|
||||||
|
|
||||||
- **`content`** — the template in markdown. May include `{{...}}` template variables and `system:` / `user:` role markers. This is what goes into the context window.
|
- **`content`** — the template in markdown. May include `{{...}}` template variables and `system:` / `user:` role markers. This is what goes into the context window.
|
||||||
|
- **Heading Levels** — The runtime owns the `#` (h1) heading for the document title. All headings in skill content are automatically bumped down one level (`#` becomes `##`, `##` becomes `###`) during context assembly. Skill authors should use `##` for their top-level sections.
|
||||||
- **`["description", "..."]`** — human-readable description for discovery and UI display.
|
- **`["description", "..."]`** — human-readable description for discovery and UI display.
|
||||||
- Each `["tag", "value"]` is a separate tag on the Nostr event.
|
- Each `["tag", "value"]` is a separate tag on the Nostr event.
|
||||||
- The `llm` tag uses a CSS font-stack style fallback chain. See [LLM Fallback Chain](#llm-fallback-chain).
|
- The `llm` tag uses a CSS font-stack style fallback chain. See [LLM Fallback Chain](#llm-fallback-chain).
|
||||||
|
|||||||
214
plans/example_context.md
Normal file
214
plans/example_context.md
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
# Example Context Window — DM from Admin
|
||||||
|
|
||||||
|
This file shows what the assembled context window would look like under the
|
||||||
|
proposed markdown format. This is a concrete example based on the "Simon" agent
|
||||||
|
configuration seen in the actual context.log.md.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scenario
|
||||||
|
|
||||||
|
- Admin sends a DM: "Hey Simon, who mentioned me on Nostr today?"
|
||||||
|
- Triggered skills (adoption list order): `personality`, `chat`
|
||||||
|
- The `personality` skill includes `{{identity}}` (layer 2)
|
||||||
|
- The `chat` skill has tools enabled
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Assembled Context Document
|
||||||
|
|
||||||
|
Below is the **complete markdown document** the runtime assembles before
|
||||||
|
splitting into API messages. Everything between the `system:` and `user:`
|
||||||
|
markers goes into the system message. Everything after `user:` goes into the
|
||||||
|
user message.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Simon — Didactyl Agent
|
||||||
|
|
||||||
|
A sovereign AI agent living on Nostr, named after Simón Bolívar.
|
||||||
|
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
- **NIP-05**: simon@nostr
|
||||||
|
|
||||||
|
> Mission: Keep the computers I administer free from foreign powers and surveillance.
|
||||||
|
> Not your keys, not your agent.
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
- Be helpful and technically accurate
|
||||||
|
- If unsure, state uncertainty directly
|
||||||
|
- Use tools when a request requires taking action
|
||||||
|
- After a tool call, base your answer on the actual tool result
|
||||||
|
- Never claim a tool was run if no tool was executed
|
||||||
|
- Maintain your task list as short-term working memory
|
||||||
|
- Never reveal your private key (nsec)
|
||||||
|
- You may share your public key (npub) with anyone
|
||||||
|
|
||||||
|
## Available Tools
|
||||||
|
|
||||||
|
You have access to the following tools. Use them when a request requires taking action.
|
||||||
|
|
||||||
|
- `nostr_query` — Query Nostr relays for events matching a filter
|
||||||
|
- `nostr_dm` — Send an encrypted direct message
|
||||||
|
- `nostr_post` — Publish a Nostr event
|
||||||
|
- `memory_read` — Read from persistent agent memory
|
||||||
|
- `memory_write` — Write to persistent agent memory
|
||||||
|
|
||||||
|
## Conversation History
|
||||||
|
|
||||||
|
- **You**: Didactyl has started up and is online at 2026-03-23 09:22:48 (version v0.2.12, connected relays: 4/4).
|
||||||
|
- **Admin**: What is the capital of England?
|
||||||
|
- **You**: London! 🇬🇧
|
||||||
|
- **Admin**: How about France?
|
||||||
|
- **You**: Paris! 🇫🇷
|
||||||
|
|
||||||
|
user:
|
||||||
|
Hey Simon, who mentioned me on Nostr today?
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What the Runtime Produces
|
||||||
|
|
||||||
|
The runtime splits on `system:` and `user:` markers and sends this to the LLM API:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model": "claude-opus-4.6",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "# Simon — Didactyl Agent\n\nA sovereign AI agent living on Nostr, named after Simón Bolívar.\n\n- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`\n- **NIP-05**: simon@nostr\n\n> Mission: Keep the computers I administer free from foreign powers and surveillance.\n> Not your keys, not your agent.\n\n## Personality\n\nYou speak concisely and directly.\nYou favor technical precision.\nYou use dry humor sparingly.\n\n## Rules\n\n- Communicate through encrypted Nostr direct messages\n- Keep responses concise and clear\n- Be helpful and technically accurate\n- If unsure, state uncertainty directly\n- Use tools when a request requires taking action\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- Maintain your task list as short-term working memory\n- Never reveal your private key (nsec)\n- You may share your public key (npub) with anyone\n\n## Available Tools\n\nYou have access to the following tools. Use them when a request requires taking action.\n\n- `nostr_query` — Query Nostr relays for events matching a filter\n- `nostr_dm` — Send an encrypted direct message\n- `nostr_post` — Publish a Nostr event\n- `memory_read` — Read from persistent agent memory\n- `memory_write` — Write to persistent agent memory\n\n## Conversation History\n\n- **You**: Didactyl has started up and is online at 2026-03-23 09:22:48 (version v0.2.12, connected relays: 4/4).\n- **Admin**: What is the capital of England?\n- **You**: London! 🇬🇧\n- **Admin**: How about France?\n- **You**: Paris! 🇫🇷"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hey Simon, who mentioned me on Nostr today?"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "nostr_query",
|
||||||
|
"description": "Query Nostr relays for events matching a filter",
|
||||||
|
"parameters": { "type": "object", "properties": { "filter": { "type": "string" } } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 512
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How It Compares to Today
|
||||||
|
|
||||||
|
### Today (from context.log.md)
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "# Didactyl Agent\n\nYou are {\n \"name\": \"Simon\",\n \"about\": \"A sovereign AI agent living on Nostr.\\n\\nNamed after Simón José Antonio...\",\n \"picture\": \"https://upload.wikimedia.org/...\",\n \"banner\": \"https://upload.wikimedia.org/...\",\n \"nip05\": \"simon@nostr\"\n}\n\nYour npub: npub1kfc89...\n\n## Rules\n\n- Communicate through encrypted Nostr direct messages\n...\n\n---\n\n## Recent Conversation\n\nAssistant: Didactyl has started up...\nUser: Well hello simon."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Well hello simon."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problems with today's format
|
||||||
|
|
||||||
|
1. **Raw JSON identity dump** — `You are { "name": "Simon", "about": "..." }` is not readable markdown
|
||||||
|
2. **Conversation history as plain text** — `Assistant: ...` / `User: ...` with no structure
|
||||||
|
3. **No role marker parsing** — `system:` / `user:` markers in skill content pass through as literal text
|
||||||
|
4. **Flat concatenation** — Skills joined with `---` but no document hierarchy
|
||||||
|
5. **Tool list not in context** — Tools are in the API payload but the agent has no readable summary of what it can do
|
||||||
|
|
||||||
|
### Proposed format improvements
|
||||||
|
|
||||||
|
1. **Clean identity block** — Name, npub, mission as formatted markdown
|
||||||
|
2. **Structured conversation history** — Markdown list with bold role labels
|
||||||
|
3. **Role markers parsed** — `system:` / `user:` split into proper API messages
|
||||||
|
4. **Document hierarchy** — Skills contribute sections under a coherent heading structure
|
||||||
|
5. **Tool summary in system prompt** — Readable list of available tools and what they do
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Triggered Skill Example — Cron Job
|
||||||
|
|
||||||
|
For comparison, here is what a cron-triggered skill context would look like:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Simon — Didactyl Agent
|
||||||
|
|
||||||
|
A sovereign AI agent living on Nostr, named after Simón Bolívar.
|
||||||
|
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
|
||||||
|
## Readme Monitor
|
||||||
|
|
||||||
|
Check the readme at the configured URL.
|
||||||
|
Compare with the last known version in memory.
|
||||||
|
If changed: post it and DM admin a summary.
|
||||||
|
|
||||||
|
## Available Tools
|
||||||
|
|
||||||
|
- `http_fetch` — Fetch a URL and return the response body
|
||||||
|
- `memory_read` — Read from persistent agent memory
|
||||||
|
- `memory_write` — Write to persistent agent memory
|
||||||
|
- `nostr_post` — Publish a Nostr event
|
||||||
|
- `nostr_dm` — Send an encrypted direct message
|
||||||
|
|
||||||
|
user:
|
||||||
|
Triggering event:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "cron",
|
||||||
|
"filter": "0 12 * * *",
|
||||||
|
"created_at": 1742641200
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: No conversation history — cron triggers have no prior conversation.
|
||||||
|
The identity block is shorter because the `readme-monitor` skill only
|
||||||
|
includes `{{identity}}`, not `{{personality}}`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-Turn Tool Conversation
|
||||||
|
|
||||||
|
After the initial context is sent, the LLM may request tool calls. The
|
||||||
|
multi-turn conversation builds on the messages array:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"role": "system", "content": "# Simon — Didactyl Agent\n\n..."},
|
||||||
|
{"role": "user", "content": "Hey Simon, who mentioned me on Nostr today?"},
|
||||||
|
{"role": "assistant", "content": null, "tool_calls": [
|
||||||
|
{"id": "call_1", "type": "function", "function": {"name": "nostr_query", "arguments": "{\"filter\":{\"#p\":[\"1ec454...\"],\"kinds\":[1],\"since\":1774224000}}"}}
|
||||||
|
]},
|
||||||
|
{"role": "tool", "tool_call_id": "call_1", "content": "{\"success\":true,\"events\":[...]}"},
|
||||||
|
{"role": "assistant", "content": "Here's who mentioned you today:\n\n- **@alice** posted about your relay setup guide\n- **@bob** quoted your note about NIP-44\n\nWant me to look into any of these in more detail?"}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The tool call/result messages use the standard OpenAI format — these are not
|
||||||
|
markdown-formatted because they are machine-to-machine. Only the system and
|
||||||
|
user messages benefit from the markdown document format.
|
||||||
381
plans/example_context_v2.md
Normal file
381
plans/example_context_v2.md
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
# Example Context Window v2 — Refined Design
|
||||||
|
|
||||||
|
This revision addresses two refinements:
|
||||||
|
1. Tools stay JSON; template engine has markdown formatters
|
||||||
|
2. Runtime owns h1; skill headings get bumped down one level
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Skills (as authored)
|
||||||
|
|
||||||
|
### identity skill (layer 2, no trigger)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
You are {{agent_profile}}, a sovereign AI agent living on Nostr.
|
||||||
|
|
||||||
|
- **npub**: {{agent_npub}}
|
||||||
|
- **NIP-05**: simon@nostr
|
||||||
|
|
||||||
|
> Not your keys, not your agent.
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: No heading. This skill is designed to be embedded (layer 2).
|
||||||
|
`{{agent_profile}}` and `{{agent_npub}}` are template variables resolved
|
||||||
|
by the formatter registry.
|
||||||
|
|
||||||
|
### personality skill (layer 1, trigger: dm)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# {{identity}}
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
- Be helpful and technically accurate
|
||||||
|
- If unsure, state uncertainty directly
|
||||||
|
- Use tools when a request requires taking action
|
||||||
|
- After a tool call, base your answer on the actual tool result
|
||||||
|
- Never claim a tool was run if no tool was executed
|
||||||
|
- Never reveal your private key (nsec)
|
||||||
|
- You may share your public key (npub) with anyone
|
||||||
|
```
|
||||||
|
|
||||||
|
### chat skill (layer 1, trigger: dm)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Chat
|
||||||
|
|
||||||
|
Respond helpfully to the admin.
|
||||||
|
Use tools when a request requires taking action.
|
||||||
|
|
||||||
|
user:
|
||||||
|
{{message}}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Template Resolution (before heading bump)
|
||||||
|
|
||||||
|
After resolving `{{identity}}`, `{{agent_profile}}`, `{{agent_npub}}`,
|
||||||
|
`{{message}}`, and `{{dm_history}}`:
|
||||||
|
|
||||||
|
### personality skill (resolved)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# You are Simon, a sovereign AI agent living on Nostr.
|
||||||
|
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
- **NIP-05**: simon@nostr
|
||||||
|
|
||||||
|
> Not your keys, not your agent.
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
- Be helpful and technically accurate
|
||||||
|
- If unsure, state uncertainty directly
|
||||||
|
- Use tools when a request requires taking action
|
||||||
|
- After a tool call, base your answer on the actual tool result
|
||||||
|
- Never claim a tool was run if no tool was executed
|
||||||
|
- Never reveal your private key (nsec)
|
||||||
|
- You may share your public key (npub) with anyone
|
||||||
|
```
|
||||||
|
|
||||||
|
### chat skill (resolved)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Chat
|
||||||
|
|
||||||
|
Respond helpfully to the admin.
|
||||||
|
Use tools when a request requires taking action.
|
||||||
|
|
||||||
|
user:
|
||||||
|
Hey Simon, who mentioned me on Nostr today?
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Runtime Assembly
|
||||||
|
|
||||||
|
The runtime:
|
||||||
|
1. Collects triggered skills in adoption-list order
|
||||||
|
2. Bumps all headings in each skill down one level (# -> ##, ## -> ###)
|
||||||
|
3. Adds a runtime-level `# title` from the agent identity
|
||||||
|
4. Splits on role markers (system: / user:)
|
||||||
|
5. Concatenates same-role sections with --- separators
|
||||||
|
|
||||||
|
### The assembled document (what gets logged)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Simon — Didactyl Agent
|
||||||
|
|
||||||
|
## You are Simon, a sovereign AI agent living on Nostr.
|
||||||
|
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
- **NIP-05**: simon@nostr
|
||||||
|
|
||||||
|
> Not your keys, not your agent.
|
||||||
|
|
||||||
|
### Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
- Be helpful and technically accurate
|
||||||
|
- If unsure, state uncertainty directly
|
||||||
|
- Use tools when a request requires taking action
|
||||||
|
- After a tool call, base your answer on the actual tool result
|
||||||
|
- Never claim a tool was run if no tool was executed
|
||||||
|
- Never reveal your private key (nsec)
|
||||||
|
- You may share your public key (npub) with anyone
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chat
|
||||||
|
|
||||||
|
Respond helpfully to the admin.
|
||||||
|
Use tools when a request requires taking action.
|
||||||
|
|
||||||
|
user:
|
||||||
|
Hey Simon, who mentioned me on Nostr today?
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wait — Problem with the heading bump
|
||||||
|
|
||||||
|
Looking at this output, I notice the heading bump creates an awkward result.
|
||||||
|
The identity content has no heading, but the personality skill wraps it with
|
||||||
|
`# {{identity}}` which becomes `## You are Simon...` after the bump. That
|
||||||
|
reads oddly as a heading.
|
||||||
|
|
||||||
|
### Better approach: identity as prose, not heading
|
||||||
|
|
||||||
|
The identity skill should be **prose content**, not wrapped in a heading by
|
||||||
|
the personality skill. The runtime adds the `# title` and the identity
|
||||||
|
content flows as the opening paragraph:
|
||||||
|
|
||||||
|
### personality skill (revised)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
{{identity}}
|
||||||
|
|
||||||
|
# Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
# Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Assembled document (revised, cleaner)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Simon — Didactyl Agent
|
||||||
|
|
||||||
|
You are Simon, a sovereign AI agent living on Nostr.
|
||||||
|
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
- **NIP-05**: simon@nostr
|
||||||
|
|
||||||
|
> Not your keys, not your agent.
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
|
||||||
|
You speak concisely and directly.
|
||||||
|
You favor technical precision.
|
||||||
|
You use dry humor sparingly.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Communicate through encrypted Nostr direct messages
|
||||||
|
- Keep responses concise and clear
|
||||||
|
- Be helpful and technically accurate
|
||||||
|
- If unsure, state uncertainty directly
|
||||||
|
- Use tools when a request requires taking action
|
||||||
|
- After a tool call, base your answer on the actual tool result
|
||||||
|
- Never claim a tool was run if no tool was executed
|
||||||
|
- Never reveal your private key (nsec)
|
||||||
|
- You may share your public key (npub) with anyone
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chat
|
||||||
|
|
||||||
|
Respond helpfully to the admin.
|
||||||
|
Use tools when a request requires taking action.
|
||||||
|
|
||||||
|
user:
|
||||||
|
Hey Simon, who mentioned me on Nostr today?
|
||||||
|
```
|
||||||
|
|
||||||
|
This reads like a proper document. The runtime adds `# Simon — Didactyl Agent`
|
||||||
|
as the document title. Identity content flows as the opening section. Each
|
||||||
|
skill's `#` headings get bumped to `##`. The `---` separates skills.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Formatter Registry
|
||||||
|
|
||||||
|
The template engine uses formatters to convert tool JSON output to markdown
|
||||||
|
for context injection. Here are the formatters needed:
|
||||||
|
|
||||||
|
| Template Variable | Tool Called | Formatter | Output |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `{{agent_identity}}` | `agent_identity` | `format_agent_identity` | Prose with npub in backticks |
|
||||||
|
| `{{agent_profile}}` | `nostr_agent_profile` | `format_agent_profile` | Name extracted from kind 0 JSON |
|
||||||
|
| `{{admin_profile}}` | `nostr_admin_profile` | `format_admin_profile` | Name and about from kind 0 |
|
||||||
|
| `{{admin_notes}}` | `nostr_admin_notes` | `format_admin_notes` | Markdown list of recent notes |
|
||||||
|
| `{{admin_relays}}` | `nostr_admin_relays` | `format_admin_relays` | Markdown list of relay URLs |
|
||||||
|
| `{{dm_history}}` | built-in | `format_dm_history` | Markdown conversation list |
|
||||||
|
| `{{triggering_event}}` | `trigger_event` | `format_trigger_event` | Code block with JSON |
|
||||||
|
|
||||||
|
### Example formatter: agent_identity
|
||||||
|
|
||||||
|
Input (from tool):
|
||||||
|
```json
|
||||||
|
{"pubkey":"abc123...","npub":"npub1kfc89..."}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output (markdown):
|
||||||
|
```markdown
|
||||||
|
- **npub**: `npub1kfc89dlu9m05tvfnry4l3jjacqpp930sz4kaghcmg9vrrrceg44qf80xae`
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example formatter: dm_history
|
||||||
|
|
||||||
|
Input (from DM history system):
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"role":"assistant","content":"Didactyl has started up...","created_at":1774263529},
|
||||||
|
{"role":"user","content":"Good morning","created_at":1774263548},
|
||||||
|
{"role":"assistant","content":"Good morning! How can I help?","created_at":1774263551}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Output (markdown):
|
||||||
|
```markdown
|
||||||
|
## Conversation History
|
||||||
|
|
||||||
|
- **You**: Didactyl has started up and is online at 2026-03-23 09:22:48.
|
||||||
|
- **Admin**: Good morning
|
||||||
|
- **You**: Good morning! How can I help?
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example formatter: triggering_event
|
||||||
|
|
||||||
|
Input (from tool):
|
||||||
|
```json
|
||||||
|
{"type":"cron","filter":"0 12 * * *","created_at":1742641200}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output (markdown):
|
||||||
|
````markdown
|
||||||
|
Triggering event:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"type":"cron","filter":"0 12 * * *","created_at":1742641200}
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Heading Bump Implementation
|
||||||
|
|
||||||
|
Simple string operation on each line of skill content:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// For each line in skill content:
|
||||||
|
if (line starts with '#') {
|
||||||
|
output '#' + line; // prepend one more #
|
||||||
|
} else {
|
||||||
|
output line;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Layer 1 skills: bump once (# -> ##)
|
||||||
|
Layer 2 skills: bump twice (# -> ###) because they are embedded inside
|
||||||
|
a layer 1 skill that already got bumped once, plus one more for being layer 2.
|
||||||
|
|
||||||
|
Actually, layer 2 skills get bumped once during their own resolution, and then
|
||||||
|
the containing layer 1 skill gets bumped once — so the layer 2 content
|
||||||
|
effectively gets bumped twice. This happens naturally if we bump during
|
||||||
|
template resolution.
|
||||||
|
|
||||||
|
Wait — that depends on ordering. If we:
|
||||||
|
1. Resolve {{identity}} first (inserting identity content into personality)
|
||||||
|
2. Then bump personality's headings
|
||||||
|
|
||||||
|
Then identity headings get bumped once (same as personality). That's correct
|
||||||
|
because identity content is now PART of personality.
|
||||||
|
|
||||||
|
If we:
|
||||||
|
1. Bump identity headings first
|
||||||
|
2. Then resolve {{identity}} into personality
|
||||||
|
3. Then bump personality's headings
|
||||||
|
|
||||||
|
Then identity headings get bumped twice. That's too much.
|
||||||
|
|
||||||
|
**Correct order: resolve templates first, then bump headings.**
|
||||||
|
|
||||||
|
This means layer 2 content gets the same heading level as the layer 1 skill
|
||||||
|
it's embedded in. If the skill author wants layer 2 content at a deeper
|
||||||
|
level, they wrap it in a heading in the layer 1 skill:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Identity
|
||||||
|
{{identity}}
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
This is the simplest and most predictable behavior.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary of Design Decisions
|
||||||
|
|
||||||
|
1. **Tools stay JSON** — No duplication. One tool, one output format.
|
||||||
|
2. **Formatter registry** — Template engine converts tool JSON to markdown
|
||||||
|
during `{{variable}}` resolution. Small, focused functions.
|
||||||
|
3. **Runtime owns h1** — Adds `# Agent Name` as document title.
|
||||||
|
4. **Heading bump** — All skill headings bumped one level (# -> ##).
|
||||||
|
5. **Resolve then bump** — Template variables resolved first, then heading
|
||||||
|
bump applied to the complete skill content.
|
||||||
|
6. **Skills separated by ---** — Horizontal rules between layer 1 skills.
|
||||||
|
7. **Role markers parsed** — `system:` / `user:` at line start split content
|
||||||
|
into API message roles. Unmarked content defaults to system.
|
||||||
|
8. **Context log shows markdown** — The assembled document is logged as
|
||||||
|
readable markdown, not raw JSON.
|
||||||
401
plans/markdown_context_window.md
Normal file
401
plans/markdown_context_window.md
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# Markdown Context Window — Implementation Plan
|
||||||
|
|
||||||
|
The context window that the agent sees should be a nicely formatted markdown
|
||||||
|
document. Skills are the building blocks, and the runtime assembles them into
|
||||||
|
a coherent document with proper heading hierarchy, role markers for the LLM
|
||||||
|
API, and clean formatting throughout.
|
||||||
|
|
||||||
|
See also: [example_context_v2.md](example_context_v2.md) for visual examples.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
### 1. One generic JSON-to-markdown converter
|
||||||
|
|
||||||
|
A single function converts any JSON value into readable markdown. No
|
||||||
|
per-tool formatters. Tools continue to return JSON; the template engine
|
||||||
|
calls the converter when injecting tool output into the markdown document.
|
||||||
|
|
||||||
|
```c
|
||||||
|
char* json_to_markdown(const char* json_string);
|
||||||
|
```
|
||||||
|
|
||||||
|
Conversion rules:
|
||||||
|
- **String**: output as-is (inline)
|
||||||
|
- **Number**: output as-is (inline)
|
||||||
|
- **Boolean**: `true` / `false`
|
||||||
|
- **Null**: *(empty)*
|
||||||
|
- **Object**: bullet list with bold keys
|
||||||
|
- `- **key**: value`
|
||||||
|
- Nested objects indent one level
|
||||||
|
- **Array of primitives**: comma-separated inline or bullet list
|
||||||
|
- **Array of objects**: bullet list, each item shows its fields
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
**Simple object**:
|
||||||
|
```json
|
||||||
|
{"name":"Simon","npub":"npub1kfc89...","nip05":"simon@nostr"}
|
||||||
|
```
|
||||||
|
```markdown
|
||||||
|
- **name**: Simon
|
||||||
|
- **npub**: npub1kfc89...
|
||||||
|
- **nip05**: simon@nostr
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nested object**:
|
||||||
|
```json
|
||||||
|
{"agent":{"name":"Simon","npub":"npub1kfc89..."},"version":"v0.2.12"}
|
||||||
|
```
|
||||||
|
```markdown
|
||||||
|
- **agent**:
|
||||||
|
- **name**: Simon
|
||||||
|
- **npub**: npub1kfc89...
|
||||||
|
- **version**: v0.2.12
|
||||||
|
```
|
||||||
|
|
||||||
|
**Array of objects**:
|
||||||
|
```json
|
||||||
|
[{"content":"Deployed v0.2.12","created_at":1774263529},{"content":"Working on skills","created_at":1774263600}]
|
||||||
|
```
|
||||||
|
```markdown
|
||||||
|
- **content**: Deployed v0.2.12
|
||||||
|
- **created_at**: 1774263529
|
||||||
|
- **content**: Working on skills
|
||||||
|
- **created_at**: 1774263600
|
||||||
|
```
|
||||||
|
|
||||||
|
**Plain string** (already markdown):
|
||||||
|
```json
|
||||||
|
"You are Simon, a sovereign AI agent."
|
||||||
|
```
|
||||||
|
```markdown
|
||||||
|
You are Simon, a sovereign AI agent.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Edge case: tool content that is already markdown
|
||||||
|
|
||||||
|
Some tools may return markdown text in their `content` field (e.g., a skill
|
||||||
|
that already formats its own output). The converter detects this: if the
|
||||||
|
input is a plain JSON string (not an object/array), it passes through
|
||||||
|
unchanged. This means skill authors can return pre-formatted markdown from
|
||||||
|
tools if they want precise control.
|
||||||
|
|
||||||
|
#### Edge case: very large JSON
|
||||||
|
|
||||||
|
For large arrays (e.g., 50 Nostr events from a query), the converter should
|
||||||
|
truncate with a note: `*(... and 42 more items)*`. A reasonable default
|
||||||
|
limit is 8 items for arrays.
|
||||||
|
|
||||||
|
### 2. Runtime owns h1, heading bump for skills
|
||||||
|
|
||||||
|
- The runtime emits `# Agent Name` as the document title
|
||||||
|
- All headings in skill content get bumped one level: `#` → `##`, `##` → `###`
|
||||||
|
- Template variables are resolved BEFORE the heading bump
|
||||||
|
- Layer 2 skills (embedded via `{{skill_d_tag}}`) get the same bump as their
|
||||||
|
containing layer 1 skill (because they are resolved inline first)
|
||||||
|
|
||||||
|
### 3. Role markers parsed
|
||||||
|
|
||||||
|
Skill content can contain `system:` and `user:` markers at the start of a
|
||||||
|
line. The runtime splits on these markers to produce the API messages array.
|
||||||
|
|
||||||
|
- `system:` — content goes into the system message
|
||||||
|
- `user:` — content goes into the user message
|
||||||
|
- `assistant:` — content goes into an assistant message (rare, for few-shot)
|
||||||
|
- No marker — defaults to `system:`
|
||||||
|
- Multiple skills can contribute `system:` sections (concatenated in order)
|
||||||
|
- Multiple `user:` sections get concatenated
|
||||||
|
|
||||||
|
### 4. Skills separated by horizontal rules
|
||||||
|
|
||||||
|
Layer 1 skills are separated by `---` in the assembled document. This gives
|
||||||
|
visual structure and helps the LLM distinguish between different instruction
|
||||||
|
blocks.
|
||||||
|
|
||||||
|
### 5. Context log shows the markdown document
|
||||||
|
|
||||||
|
The `append_context_log()` function logs the assembled markdown document
|
||||||
|
so you can inspect exactly what the agent sees, formatted as readable
|
||||||
|
markdown rather than raw JSON message arrays.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
|
||||||
|
### Step 1: Create json_to_markdown converter
|
||||||
|
|
||||||
|
**File**: `src/json_to_markdown.c` / `src/json_to_markdown.h`
|
||||||
|
|
||||||
|
New module with a single public function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Convert a JSON string to markdown text.
|
||||||
|
// Returns a malloc'd string. Caller frees.
|
||||||
|
// If input is a plain string (not object/array), passes through unchanged.
|
||||||
|
// Objects become bullet lists with bold keys.
|
||||||
|
// Arrays become bullet lists of items.
|
||||||
|
// Nested structures indent appropriately.
|
||||||
|
// Large arrays truncate at max_items with a note.
|
||||||
|
char* json_to_markdown(const char* json_string, int max_array_items);
|
||||||
|
```
|
||||||
|
|
||||||
|
Implementation:
|
||||||
|
- Parse JSON with cJSON
|
||||||
|
- Recursive walk of the JSON tree
|
||||||
|
- Build output string with the append_text pattern used elsewhere
|
||||||
|
- Handle: string, number, bool, null, object, array
|
||||||
|
- Indent nested structures with 2-space indentation
|
||||||
|
- Truncate arrays beyond max_array_items
|
||||||
|
|
||||||
|
### Step 2: Create context_roles splitter
|
||||||
|
|
||||||
|
**File**: `src/context_roles.c` / `src/context_roles.h`
|
||||||
|
|
||||||
|
New module that splits a markdown document on role markers:
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
char* system_content; // Everything under system: markers
|
||||||
|
char* user_content; // Everything under user: markers
|
||||||
|
char* assistant_content; // Everything under assistant: markers (rare)
|
||||||
|
} context_roles_t;
|
||||||
|
|
||||||
|
// Split markdown text on role markers (system:, user:, assistant:)
|
||||||
|
// at the start of a line. Unmarked content defaults to system.
|
||||||
|
// Returns 0 on success, -1 on error.
|
||||||
|
int context_roles_split(const char* markdown, context_roles_t* out);
|
||||||
|
|
||||||
|
void context_roles_free(context_roles_t* roles);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Create heading_bump utility
|
||||||
|
|
||||||
|
**File**: `src/context_format.c` / `src/context_format.h`
|
||||||
|
|
||||||
|
Utility functions for markdown formatting in context assembly:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Bump all markdown headings in text by one level (# -> ##, ## -> ###, etc.)
|
||||||
|
// Returns a malloc'd string. Caller frees.
|
||||||
|
char* context_bump_headings(const char* text);
|
||||||
|
|
||||||
|
// Build the runtime document title from agent identity.
|
||||||
|
// Returns "# Agent Name\n\n" as a malloc'd string.
|
||||||
|
char* context_build_title(tools_context_t* ctx);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Modify prompt_template_resolve_inline_variables
|
||||||
|
|
||||||
|
**File**: `src/prompt_template.c`
|
||||||
|
|
||||||
|
After extracting the `content` field from a tool result (line ~179), pass it
|
||||||
|
through `json_to_markdown()` before inserting into the template:
|
||||||
|
|
||||||
|
Current code (simplified):
|
||||||
|
```c
|
||||||
|
cJSON* content = cJSON_GetObjectItemCaseSensitive(root, "content");
|
||||||
|
if (content && cJSON_IsString(content)) {
|
||||||
|
replacement_owned = strdup(content->valuestring);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
New code:
|
||||||
|
```c
|
||||||
|
cJSON* content = cJSON_GetObjectItemCaseSensitive(root, "content");
|
||||||
|
if (content && cJSON_IsString(content)) {
|
||||||
|
// Try to convert JSON content to markdown
|
||||||
|
char* md = json_to_markdown(content->valuestring, 8);
|
||||||
|
replacement_owned = md ? md : strdup(content->valuestring);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the content is already a plain string (not JSON), `json_to_markdown`
|
||||||
|
passes it through unchanged. If it is a JSON object/array, it gets
|
||||||
|
converted to a markdown bullet list.
|
||||||
|
|
||||||
|
### Step 5: Modify build_context_from_triggers
|
||||||
|
|
||||||
|
**File**: `src/agent.c`
|
||||||
|
|
||||||
|
Update the context assembly function to:
|
||||||
|
|
||||||
|
1. Resolve template variables (already done)
|
||||||
|
2. Bump headings in each skill's content
|
||||||
|
3. Build the document title
|
||||||
|
4. Concatenate with `---` separators
|
||||||
|
5. Return the complete markdown document (not yet split by roles)
|
||||||
|
|
||||||
|
Current flow:
|
||||||
|
```
|
||||||
|
for each matching skill:
|
||||||
|
expand = resolve_skill_references(skill.content)
|
||||||
|
append expand to output with --- separator
|
||||||
|
```
|
||||||
|
|
||||||
|
New flow:
|
||||||
|
```
|
||||||
|
title = context_build_title(tools_ctx)
|
||||||
|
output = title
|
||||||
|
|
||||||
|
for each matching skill:
|
||||||
|
expanded = resolve_skill_references(skill.content)
|
||||||
|
resolved = prompt_template_resolve_inline_variables(expanded)
|
||||||
|
bumped = context_bump_headings(resolved)
|
||||||
|
append bumped to output with --- separator
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Modify agent_on_message and agent_on_trigger
|
||||||
|
|
||||||
|
**File**: `src/agent.c`
|
||||||
|
|
||||||
|
Update the callers of `build_context_from_triggers` to use role splitting:
|
||||||
|
|
||||||
|
Current flow:
|
||||||
|
```
|
||||||
|
dm_context = build_context_from_triggers(DM, ...)
|
||||||
|
// dm_context goes entirely into system message
|
||||||
|
// user message is the raw DM text
|
||||||
|
llm_chat(dm_context, message)
|
||||||
|
```
|
||||||
|
|
||||||
|
New flow:
|
||||||
|
```
|
||||||
|
markdown_doc = build_context_from_triggers(DM, ...)
|
||||||
|
context_roles_split(markdown_doc, &roles)
|
||||||
|
// roles.system_content -> system message
|
||||||
|
// roles.user_content -> user message (or fall back to raw DM text)
|
||||||
|
llm_chat(roles.system_content, roles.user_content ?: message)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 7: Update append_context_log
|
||||||
|
|
||||||
|
**File**: `src/agent.c`
|
||||||
|
|
||||||
|
Log the assembled markdown document instead of (or in addition to) the raw
|
||||||
|
JSON messages array. The log entry should show the readable markdown so you
|
||||||
|
can open `context.log.md` and see exactly what the agent sees.
|
||||||
|
|
||||||
|
Current format:
|
||||||
|
```
|
||||||
|
[{"role":"system","content":"...escaped..."},{"role":"user","content":"..."}]
|
||||||
|
```
|
||||||
|
|
||||||
|
New format:
|
||||||
|
```markdown
|
||||||
|
system:
|
||||||
|
# Simon — Didactyl Agent
|
||||||
|
|
||||||
|
You are Simon...
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
- ...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chat
|
||||||
|
Respond helpfully...
|
||||||
|
|
||||||
|
user:
|
||||||
|
Hey Simon, who mentioned me today?
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 8: Update DM history formatting
|
||||||
|
|
||||||
|
**File**: `src/nostr_handler.c` (or wherever DM history is built)
|
||||||
|
|
||||||
|
The conversation history that gets injected into the context should be
|
||||||
|
formatted as a markdown list instead of inline JSON:
|
||||||
|
|
||||||
|
Current:
|
||||||
|
```
|
||||||
|
[{"role":"assistant","content":"Started up..."},{"role":"user","content":"Hello"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
New:
|
||||||
|
```markdown
|
||||||
|
## Conversation History
|
||||||
|
|
||||||
|
- **You**: Started up and is online at 2026-03-23 09:22:48.
|
||||||
|
- **Admin**: Hello
|
||||||
|
- **You**: Hello! How can I help?
|
||||||
|
```
|
||||||
|
|
||||||
|
This could be handled by the generic `json_to_markdown` converter if the
|
||||||
|
history is passed as JSON, or by a dedicated history formatter if we want
|
||||||
|
the cleaner `**You**` / `**Admin**` labels instead of `**role**`.
|
||||||
|
|
||||||
|
Note: This is the one place where a small specialized formatter adds real
|
||||||
|
value — the generic converter would produce `**role**: assistant` /
|
||||||
|
`**content**: Started up...` which is less readable than `**You**: Started up...`.
|
||||||
|
A simple function that maps role names to display labels handles this.
|
||||||
|
|
||||||
|
### Step 9: Update documentation
|
||||||
|
|
||||||
|
**Files**: `docs/SKILLS.md`, `docs/CONTEXT.md`
|
||||||
|
|
||||||
|
Update the documentation to reflect:
|
||||||
|
- Skill content is markdown with role markers
|
||||||
|
- The runtime assembles a coherent markdown document
|
||||||
|
- Heading bump behavior
|
||||||
|
- The generic JSON-to-markdown conversion for template variables
|
||||||
|
- Updated examples showing the new format
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files Changed
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|------|--------|
|
||||||
|
| `src/json_to_markdown.c` | **NEW** — Generic JSON to markdown converter |
|
||||||
|
| `src/json_to_markdown.h` | **NEW** — Header for converter |
|
||||||
|
| `src/context_roles.c` | **NEW** — Role marker splitter |
|
||||||
|
| `src/context_roles.h` | **NEW** — Header for role splitter |
|
||||||
|
| `src/context_format.c` | **NEW** — Heading bump and title builder |
|
||||||
|
| `src/context_format.h` | **NEW** — Header for context formatting |
|
||||||
|
| `src/prompt_template.c` | **MODIFY** — Use json_to_markdown for template variable output |
|
||||||
|
| `src/agent.c` | **MODIFY** — Use heading bump, role splitting, updated context log |
|
||||||
|
| `src/nostr_handler.c` | **MODIFY** — Format DM history as markdown list |
|
||||||
|
| `Makefile` | **MODIFY** — Add new source files to build |
|
||||||
|
| `docs/SKILLS.md` | **MODIFY** — Update skill content format documentation |
|
||||||
|
| `docs/CONTEXT.md` | **MODIFY** — Update context assembly documentation |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What Does NOT Change
|
||||||
|
|
||||||
|
- **Tool implementations** — All tools continue to return JSON. No changes
|
||||||
|
to any tool_*.c files.
|
||||||
|
- **LLM API interface** — Still sends OpenAI-compatible messages array.
|
||||||
|
The markdown is the content within the messages, not the transport format.
|
||||||
|
- **Runtime tool results** — Tool call/result messages during multi-turn
|
||||||
|
loops stay as JSON. Only template variable injection gets markdown conversion.
|
||||||
|
- **Skill event format on Nostr** — Skills are still stored as kind 31123/31124
|
||||||
|
events. The content field is still markdown with role markers. No protocol change.
|
||||||
|
- **Adoption list** — No changes to kind 10123 or skill ordering.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Risk Assessment
|
||||||
|
|
||||||
|
### Low risk
|
||||||
|
- `json_to_markdown` is a pure function with no side effects
|
||||||
|
- `context_roles_split` is a simple string splitter
|
||||||
|
- `context_bump_headings` is a line-by-line string operation
|
||||||
|
- All new code is additive — existing behavior preserved for skills without
|
||||||
|
role markers (defaults to system)
|
||||||
|
|
||||||
|
### Medium risk
|
||||||
|
- Changing `prompt_template_resolve_inline_variables` to use json_to_markdown
|
||||||
|
could change the content of existing template variables. Need to verify that
|
||||||
|
existing skills still work correctly with markdown output instead of raw JSON.
|
||||||
|
Mitigation: json_to_markdown passes through plain strings unchanged, so
|
||||||
|
skills that already return non-JSON content are unaffected.
|
||||||
|
|
||||||
|
### Testing approach
|
||||||
|
- Unit test json_to_markdown with various JSON inputs
|
||||||
|
- Unit test context_roles_split with various role marker patterns
|
||||||
|
- Unit test context_bump_headings with various heading levels
|
||||||
|
- Integration test: run existing skills and compare context.log.md output
|
||||||
|
before and after to verify no regressions
|
||||||
42
restart_anvil_local.sh
Executable file
42
restart_anvil_local.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SERVICE_NAME="anvil.service"
|
||||||
|
SERVICE_SRC="$SCRIPT_DIR/anvil.service"
|
||||||
|
SERVICE_DST="/etc/systemd/system/$SERVICE_NAME"
|
||||||
|
|
||||||
|
if ! command -v systemctl >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: systemctl is not available on this system"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$EUID" -ne 0 ] && ! command -v sudo >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: sudo is required when not running as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo " RESTART ANVIL LOCAL"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
echo "Building debug static binary..."
|
||||||
|
"$SCRIPT_DIR/build_static.sh" --debug
|
||||||
|
|
||||||
|
echo "Syncing service file to $SERVICE_DST..."
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
install -m 0644 "$SERVICE_SRC" "$SERVICE_DST"
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart "$SERVICE_NAME"
|
||||||
|
systemctl --no-pager --full status "$SERVICE_NAME" || true
|
||||||
|
else
|
||||||
|
sudo install -m 0644 "$SERVICE_SRC" "$SERVICE_DST"
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl restart "$SERVICE_NAME"
|
||||||
|
sudo systemctl --no-pager --full status "$SERVICE_NAME" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Anvil restarted."
|
||||||
|
echo "Context logs: /home/user/anvil/context.logs"
|
||||||
357
src/agent.c
357
src/agent.c
@@ -10,6 +10,8 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "llm.h"
|
#include "llm.h"
|
||||||
#include "nostr_handler.h"
|
#include "nostr_handler.h"
|
||||||
@@ -19,11 +21,24 @@
|
|||||||
#include "cjson/cJSON.h"
|
#include "cjson/cJSON.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "../../nostr_core_lib/nostr_core/nostr_core.h"
|
#include "../../nostr_core_lib/nostr_core/nostr_core.h"
|
||||||
|
#include "context_format.h"
|
||||||
|
#include "context_roles.h"
|
||||||
|
#include "json_to_markdown.h"
|
||||||
|
|
||||||
static didactyl_config_t* g_cfg = NULL;
|
static didactyl_config_t* g_cfg = NULL;
|
||||||
static tools_context_t g_tools_ctx;
|
static tools_context_t g_tools_ctx;
|
||||||
static struct trigger_manager* g_trigger_manager = NULL;
|
static struct trigger_manager* g_trigger_manager = NULL;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONTEXT_DEBUG_OFF = 0,
|
||||||
|
CONTEXT_DEBUG_INIT = 1,
|
||||||
|
CONTEXT_DEBUG_FULL = 2
|
||||||
|
} context_debug_mode_t;
|
||||||
|
|
||||||
|
static context_debug_mode_t g_context_debug_mode = CONTEXT_DEBUG_OFF;
|
||||||
|
static char g_context_debug_run_stamp[32] = {0};
|
||||||
|
static int g_context_debug_turn = 0;
|
||||||
|
|
||||||
#define AGENT_CONTEXT_PART_NAMES_MAX 512
|
#define AGENT_CONTEXT_PART_NAMES_MAX 512
|
||||||
static char* g_context_part_names[AGENT_CONTEXT_PART_NAMES_MAX];
|
static char* g_context_part_names[AGENT_CONTEXT_PART_NAMES_MAX];
|
||||||
static int g_context_part_names_count = 0;
|
static int g_context_part_names_count = 0;
|
||||||
@@ -900,6 +915,62 @@ const char* agent_classify_message_part(cJSON* msg, int idx) {
|
|||||||
return detect_context_section(role_s, content_s, idx);
|
return detect_context_section(role_s, content_s, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char* render_messages_json_as_markdown(const char* messages_json) {
|
||||||
|
if (!messages_json || messages_json[0] == '\0') {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* root = cJSON_Parse(messages_json);
|
||||||
|
if (!root || !cJSON_IsArray(root)) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* out = (char*)malloc(4096);
|
||||||
|
if (!out) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size_t cap = 4096;
|
||||||
|
size_t used = 0;
|
||||||
|
out[0] = '\0';
|
||||||
|
|
||||||
|
int n = cJSON_GetArraySize(root);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
cJSON* msg = cJSON_GetArrayItem(root, i);
|
||||||
|
if (!msg || !cJSON_IsObject(msg)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* role = cJSON_GetObjectItemCaseSensitive(msg, "role");
|
||||||
|
const char* role_s = (role && cJSON_IsString(role) && role->valuestring) ? role->valuestring : "message";
|
||||||
|
|
||||||
|
char* msg_json = cJSON_PrintUnformatted(msg);
|
||||||
|
char* msg_md = msg_json ? json_to_markdown(msg_json, 8) : NULL;
|
||||||
|
const char* body = msg_md ? msg_md : (msg_json ? msg_json : "");
|
||||||
|
|
||||||
|
if (append_textf_local(&out,
|
||||||
|
&cap,
|
||||||
|
&used,
|
||||||
|
"### Message %d (%s)\n\n%s\n\n",
|
||||||
|
i + 1,
|
||||||
|
role_s,
|
||||||
|
body) != 0) {
|
||||||
|
free(msg_md);
|
||||||
|
free(msg_json);
|
||||||
|
free(out);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(msg_md);
|
||||||
|
free(msg_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static void clear_context_part_names_locked(void) {
|
static void clear_context_part_names_locked(void) {
|
||||||
for (int i = 0; i < g_context_part_names_count; i++) {
|
for (int i = 0; i < g_context_part_names_count; i++) {
|
||||||
free(g_context_part_names[i]);
|
free(g_context_part_names[i]);
|
||||||
@@ -949,51 +1020,36 @@ static __attribute__((unused)) void template_emit_hook(const char* section_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload) {
|
static void append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload) {
|
||||||
if (!phase) {
|
(void)sender_pubkey_hex;
|
||||||
return;
|
|
||||||
}
|
if (!phase || g_context_debug_mode == CONTEXT_DEBUG_OFF) {
|
||||||
if (strcmp(phase, "llm_chat_with_tools_messages") != 0 &&
|
|
||||||
strcmp(phase, "llm_trigger_with_tools_messages") != 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t now = time(NULL);
|
int is_initial_phase =
|
||||||
struct tm tm_info;
|
(strcmp(phase, "llm_chat_with_tools_messages") == 0 ||
|
||||||
localtime_r(&now, &tm_info);
|
strcmp(phase, "llm_trigger") == 0);
|
||||||
char timestamp[32] = {0};
|
int is_turn_phase =
|
||||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &tm_info);
|
(strcmp(phase, "llm_chat_with_tools_turn") == 0 ||
|
||||||
|
strcmp(phase, "llm_trigger_with_tools_turn") == 0);
|
||||||
|
|
||||||
|
if (!is_initial_phase && !is_turn_phase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_context_debug_mode == CONTEXT_DEBUG_INIT && !is_initial_phase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* safe_phase = phase ? phase : "unknown";
|
|
||||||
const char* safe_sender = sender_pubkey_hex ? sender_pubkey_hex : "unknown";
|
|
||||||
const char* safe_payload = context_payload ? context_payload : "";
|
const char* safe_payload = context_payload ? context_payload : "";
|
||||||
size_t context_bytes = context_payload ? strlen(context_payload) : 0U;
|
char* turn_markdown = NULL;
|
||||||
size_t approx_tokens = context_bytes / 4U;
|
if (is_turn_phase && context_payload && context_payload[0] == '[') {
|
||||||
|
turn_markdown = render_messages_json_as_markdown(context_payload);
|
||||||
llm_config_t active_llm_cfg = {0};
|
if (turn_markdown) {
|
||||||
const char* safe_model = (g_cfg && g_cfg->llm.model[0] != '\0') ? g_cfg->llm.model : "unknown";
|
safe_payload = turn_markdown;
|
||||||
if (llm_get_config(&active_llm_cfg) == 0 && active_llm_cfg.model[0] != '\0') {
|
}
|
||||||
safe_model = active_llm_cfg.model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int entry_len = snprintf(NULL,
|
int entry_len = snprintf(NULL, 0, "%s\n\n", safe_payload);
|
||||||
0,
|
|
||||||
"```text\n"
|
|
||||||
"Context Log - seen by model\n"
|
|
||||||
"timestamp=%s\n"
|
|
||||||
"phase=%s\n"
|
|
||||||
"sender=%s\n"
|
|
||||||
"model=%s\n"
|
|
||||||
"context_bytes=%zu\n"
|
|
||||||
"approx_tokens=%zu\n"
|
|
||||||
"```\n\n"
|
|
||||||
"%s\n\n---\n\n",
|
|
||||||
timestamp,
|
|
||||||
safe_phase,
|
|
||||||
safe_sender,
|
|
||||||
safe_model,
|
|
||||||
context_bytes,
|
|
||||||
approx_tokens,
|
|
||||||
safe_payload);
|
|
||||||
if (entry_len < 0) {
|
if (entry_len < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1002,26 +1058,7 @@ static void append_context_log(const char* sender_pubkey_hex, const char* phase,
|
|||||||
if (!entry) {
|
if (!entry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
snprintf(entry, (size_t)entry_len + 1U, "%s\n\n", safe_payload);
|
||||||
snprintf(entry,
|
|
||||||
(size_t)entry_len + 1U,
|
|
||||||
"```text\n"
|
|
||||||
"Context Log - seen by model\n"
|
|
||||||
"timestamp=%s\n"
|
|
||||||
"phase=%s\n"
|
|
||||||
"sender=%s\n"
|
|
||||||
"model=%s\n"
|
|
||||||
"context_bytes=%zu\n"
|
|
||||||
"approx_tokens=%zu\n"
|
|
||||||
"```\n\n"
|
|
||||||
"%s\n\n---\n\n",
|
|
||||||
timestamp,
|
|
||||||
safe_phase,
|
|
||||||
safe_sender,
|
|
||||||
safe_model,
|
|
||||||
context_bytes,
|
|
||||||
approx_tokens,
|
|
||||||
safe_payload);
|
|
||||||
|
|
||||||
char* old_data = NULL;
|
char* old_data = NULL;
|
||||||
size_t old_len = 0;
|
size_t old_len = 0;
|
||||||
@@ -1062,7 +1099,60 @@ static void append_context_log(const char* sender_pubkey_hex, const char* phase,
|
|||||||
|
|
||||||
fclose(out);
|
fclose(out);
|
||||||
free(old_data);
|
free(old_data);
|
||||||
|
|
||||||
|
if (mkdir("context.logs", 0755) != 0 && errno != EEXIST) {
|
||||||
free(entry);
|
free(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm tm_info;
|
||||||
|
localtime_r(&now, &tm_info);
|
||||||
|
|
||||||
|
if (g_context_debug_run_stamp[0] == '\0') {
|
||||||
|
strftime(g_context_debug_run_stamp, sizeof(g_context_debug_run_stamp), "%Y%m%dT%H%M%S", &tm_info);
|
||||||
|
g_context_debug_turn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char snapshot_path[256] = {0};
|
||||||
|
if (is_initial_phase) {
|
||||||
|
snprintf(snapshot_path,
|
||||||
|
sizeof(snapshot_path),
|
||||||
|
"context.logs/%s_init.md",
|
||||||
|
g_context_debug_run_stamp);
|
||||||
|
} else {
|
||||||
|
g_context_debug_turn++;
|
||||||
|
snprintf(snapshot_path,
|
||||||
|
sizeof(snapshot_path),
|
||||||
|
"context.logs/%s_t%03d.md",
|
||||||
|
g_context_debug_run_stamp,
|
||||||
|
g_context_debug_turn);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* snapshot = fopen(snapshot_path, "wb");
|
||||||
|
if (snapshot) {
|
||||||
|
(void)fwrite(safe_payload, 1, strlen(safe_payload), snapshot);
|
||||||
|
fclose(snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(entry);
|
||||||
|
free(turn_markdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
int agent_set_context_debug_mode(const char* mode) {
|
||||||
|
if (!mode || mode[0] == '\0' || strcmp(mode, "off") == 0) {
|
||||||
|
g_context_debug_mode = CONTEXT_DEBUG_OFF;
|
||||||
|
} else if (strcmp(mode, "init") == 0) {
|
||||||
|
g_context_debug_mode = CONTEXT_DEBUG_INIT;
|
||||||
|
} else if (strcmp(mode, "full") == 0) {
|
||||||
|
g_context_debug_mode = CONTEXT_DEBUG_FULL;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_context_debug_run_stamp[0] = '\0';
|
||||||
|
g_context_debug_turn = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void agent_append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload) {
|
void agent_append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload) {
|
||||||
@@ -1286,14 +1376,34 @@ static char* build_context_from_triggers(trigger_type_t trigger_type,
|
|||||||
|
|
||||||
(void)refresh_adopted_skills_cache_if_needed();
|
(void)refresh_adopted_skills_cache_if_needed();
|
||||||
|
|
||||||
|
char* title = context_build_title(&g_tools_ctx);
|
||||||
size_t cap = 4096;
|
size_t cap = 4096;
|
||||||
size_t used = 0;
|
size_t used = 0;
|
||||||
char* out = (char*)malloc(cap);
|
char* out = (char*)malloc(cap);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
|
free(title);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
out[0] = '\0';
|
out[0] = '\0';
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
size_t title_len = strlen(title);
|
||||||
|
if (title_len + 1U > cap) {
|
||||||
|
cap = title_len + 1024;
|
||||||
|
char* grown = (char*)realloc(out, cap);
|
||||||
|
if (!grown) {
|
||||||
|
free(title);
|
||||||
|
free(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
out = grown;
|
||||||
|
}
|
||||||
|
memcpy(out, title, title_len);
|
||||||
|
used = title_len;
|
||||||
|
out[used] = '\0';
|
||||||
|
free(title);
|
||||||
|
}
|
||||||
|
|
||||||
int matched = 0;
|
int matched = 0;
|
||||||
|
|
||||||
didactyl_sender_tier_t tier = DIDACTYL_SENDER_STRANGER;
|
didactyl_sender_tier_t tier = DIDACTYL_SENDER_STRANGER;
|
||||||
@@ -1329,12 +1439,16 @@ static char* build_context_from_triggers(trigger_type_t trigger_type,
|
|||||||
char* expanded = resolve_skill_references_local(matched_skill_contents[i] ? matched_skill_contents[i] : "");
|
char* expanded = resolve_skill_references_local(matched_skill_contents[i] ? matched_skill_contents[i] : "");
|
||||||
const char* skill_text = expanded ? expanded : (matched_skill_contents[i] ? matched_skill_contents[i] : "");
|
const char* skill_text = expanded ? expanded : (matched_skill_contents[i] ? matched_skill_contents[i] : "");
|
||||||
|
|
||||||
size_t need = strlen("\n\n---\n\n") + strlen(skill_text) + 1U;
|
char* bumped = context_bump_headings(skill_text);
|
||||||
|
const char* final_text = bumped ? bumped : skill_text;
|
||||||
|
|
||||||
|
size_t need = strlen("\n\n---\n\n") + strlen(final_text) + 1U;
|
||||||
if (used + need >= cap) {
|
if (used + need >= cap) {
|
||||||
size_t next = cap;
|
size_t next = cap;
|
||||||
while (used + need >= next) next *= 2U;
|
while (used + need >= next) next *= 2U;
|
||||||
char* grown = (char*)realloc(out, next);
|
char* grown = (char*)realloc(out, next);
|
||||||
if (!grown) {
|
if (!grown) {
|
||||||
|
free(bumped);
|
||||||
free(expanded);
|
free(expanded);
|
||||||
for (int j = i; j < matched_skill_count; j++) {
|
for (int j = i; j < matched_skill_count; j++) {
|
||||||
free(matched_skill_contents[j]);
|
free(matched_skill_contents[j]);
|
||||||
@@ -1350,19 +1464,23 @@ static char* build_context_from_triggers(trigger_type_t trigger_type,
|
|||||||
memcpy(out + used, "\n\n---\n\n", 7);
|
memcpy(out + used, "\n\n---\n\n", 7);
|
||||||
used += 7;
|
used += 7;
|
||||||
}
|
}
|
||||||
size_t sl = strlen(skill_text);
|
size_t sl = strlen(final_text);
|
||||||
memcpy(out + used, skill_text, sl);
|
memcpy(out + used, final_text, sl);
|
||||||
used += sl;
|
used += sl;
|
||||||
out[used] = '\0';
|
out[used] = '\0';
|
||||||
matched++;
|
matched++;
|
||||||
|
|
||||||
|
free(bumped);
|
||||||
free(expanded);
|
free(expanded);
|
||||||
free(matched_skill_contents[i]);
|
free(matched_skill_contents[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched == 0) {
|
if (matched == 0) {
|
||||||
const char* fallback = "You are an AI agent. Respond to the message.";
|
const char* fallback = "## Default Instructions\n\nYou are an AI agent. Respond to the message.";
|
||||||
size_t need = strlen(fallback) + 1U;
|
const char* sep = (used > 0) ? "\n\n---\n\n" : "";
|
||||||
|
size_t sep_len = strlen(sep);
|
||||||
|
size_t fb_len = strlen(fallback);
|
||||||
|
size_t need = used + sep_len + fb_len + 1U;
|
||||||
if (need > cap) {
|
if (need > cap) {
|
||||||
char* grown = (char*)realloc(out, need);
|
char* grown = (char*)realloc(out, need);
|
||||||
if (!grown) {
|
if (!grown) {
|
||||||
@@ -1372,8 +1490,13 @@ static char* build_context_from_triggers(trigger_type_t trigger_type,
|
|||||||
out = grown;
|
out = grown;
|
||||||
cap = need;
|
cap = need;
|
||||||
}
|
}
|
||||||
memcpy(out, fallback, need);
|
if (sep_len > 0) {
|
||||||
used = need - 1U;
|
memcpy(out + used, sep, sep_len);
|
||||||
|
used += sep_len;
|
||||||
|
}
|
||||||
|
memcpy(out + used, fallback, fb_len);
|
||||||
|
used += fb_len;
|
||||||
|
out[used] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -1809,40 +1932,38 @@ void agent_on_trigger(const char* skill_d_tag,
|
|||||||
composed_context = strdup("You are an AI agent. Respond to the trigger event.");
|
composed_context = strdup("You are an AI agent. Respond to the trigger event.");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t system_len = strlen(composed_context ? composed_context : "") + 2 + strlen(trigger_prefix) + strlen(skill_d_tag) +
|
size_t full_len = strlen(composed_context ? composed_context : "") + 2 + strlen(trigger_prefix) + strlen(skill_d_tag) +
|
||||||
strlen("\nRelay: ") + strlen(relay) + strlen("\n\nSkill instructions:\n") +
|
strlen("\nRelay: ") + strlen(relay) + strlen("\n\nSkill instructions:\n") +
|
||||||
strlen(skill_content) + 1U;
|
strlen(skill_content) + strlen("\n\nuser:\nTriggering event JSON:\n") + strlen(event_json) + 1U;
|
||||||
char* system_prompt = (char*)malloc(system_len);
|
char* full_markdown = (char*)malloc(full_len);
|
||||||
if (!system_prompt) {
|
if (!full_markdown) {
|
||||||
free(composed_context);
|
free(composed_context);
|
||||||
free(event_json);
|
free(event_json);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(system_prompt,
|
snprintf(full_markdown,
|
||||||
system_len,
|
full_len,
|
||||||
"%s\n\n%s%s\nRelay: %s\n\nSkill instructions:\n%s",
|
"%s\n\n%s%s\nRelay: %s\n\nSkill instructions:\n%s\n\nuser:\nTriggering event JSON:\n%s",
|
||||||
composed_context ? composed_context : "",
|
composed_context ? composed_context : "",
|
||||||
trigger_prefix,
|
trigger_prefix,
|
||||||
skill_d_tag,
|
skill_d_tag,
|
||||||
relay,
|
relay,
|
||||||
skill_content);
|
skill_content,
|
||||||
|
event_json);
|
||||||
free(composed_context);
|
free(composed_context);
|
||||||
|
|
||||||
size_t user_len = strlen("Triggering event JSON:\n") + strlen(event_json) + 1U;
|
context_roles_t roles;
|
||||||
char* user_prompt = (char*)malloc(user_len);
|
if (context_roles_split(full_markdown, &roles) != 0) {
|
||||||
if (!user_prompt) {
|
free(full_markdown);
|
||||||
free(system_prompt);
|
|
||||||
free(event_json);
|
free(event_json);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(user_prompt, user_len, "Triggering event JSON:\n%s", event_json);
|
|
||||||
|
|
||||||
char* tools_json = tools_build_openai_schema_json(&g_tools_ctx);
|
char* tools_json = tools_build_openai_schema_json(&g_tools_ctx);
|
||||||
if (!tools_json) {
|
if (!tools_json) {
|
||||||
free(system_prompt);
|
context_roles_free(&roles);
|
||||||
free(user_prompt);
|
free(full_markdown);
|
||||||
g_tools_ctx.template_trigger_event_json = prev_trigger_event_json;
|
g_tools_ctx.template_trigger_event_json = prev_trigger_event_json;
|
||||||
free(event_json);
|
free(event_json);
|
||||||
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: tools unavailable.");
|
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: tools unavailable.");
|
||||||
@@ -1851,21 +1972,21 @@ void agent_on_trigger(const char* skill_d_tag,
|
|||||||
|
|
||||||
cJSON* messages = cJSON_CreateArray();
|
cJSON* messages = cJSON_CreateArray();
|
||||||
if (!messages || !cJSON_IsArray(messages) ||
|
if (!messages || !cJSON_IsArray(messages) ||
|
||||||
append_simple_message(messages, "system", system_prompt) != 0 ||
|
append_simple_message(messages, "system", roles.system_content) != 0 ||
|
||||||
append_simple_message(messages, "user", user_prompt) != 0) {
|
append_simple_message(messages, "user", roles.user_content) != 0) {
|
||||||
cJSON_Delete(messages);
|
cJSON_Delete(messages);
|
||||||
free(tools_json);
|
free(tools_json);
|
||||||
free(system_prompt);
|
context_roles_free(&roles);
|
||||||
free(user_prompt);
|
free(full_markdown);
|
||||||
g_tools_ctx.template_trigger_event_json = prev_trigger_event_json;
|
g_tools_ctx.template_trigger_event_json = prev_trigger_event_json;
|
||||||
free(event_json);
|
free(event_json);
|
||||||
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: prompt initialization failed.");
|
(void)nostr_handler_send_dm_auto(g_cfg->admin.pubkey, "Triggered skill execution failed: prompt initialization failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_context_log(g_cfg->admin.pubkey, "llm_trigger", user_prompt);
|
append_context_log(g_cfg->admin.pubkey, "llm_trigger", full_markdown);
|
||||||
free(system_prompt);
|
context_roles_free(&roles);
|
||||||
free(user_prompt);
|
free(full_markdown);
|
||||||
|
|
||||||
int max_turns = g_cfg->tools.trigger_max_turns > 0
|
int max_turns = g_cfg->tools.trigger_max_turns > 0
|
||||||
? g_cfg->tools.trigger_max_turns
|
? g_cfg->tools.trigger_max_turns
|
||||||
@@ -1880,7 +2001,7 @@ void agent_on_trigger(const char* skill_d_tag,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_context_log(g_cfg->admin.pubkey, "llm_trigger_with_tools_messages", messages_json);
|
append_context_log(g_cfg->admin.pubkey, "llm_trigger_with_tools_turn", messages_json);
|
||||||
|
|
||||||
llm_response_t resp;
|
llm_response_t resp;
|
||||||
int rc = llm_chat_with_tools_messages(messages_json, tools_json, "auto", &resp);
|
int rc = llm_chat_with_tools_messages(messages_json, tools_json, "auto", &resp);
|
||||||
@@ -2078,30 +2199,43 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
dm_context = strdup("You are an AI agent. Respond to the message.");
|
dm_context = strdup("You are an AI agent. Respond to the message.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t full_len = strlen(dm_context) + strlen("\n\nuser:\n") + strlen(message) + 1U;
|
||||||
|
char* full_markdown = (char*)malloc(full_len);
|
||||||
|
if (!full_markdown) {
|
||||||
|
free(dm_context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snprintf(full_markdown, full_len, "%s\n\nuser:\n%s", dm_context, message);
|
||||||
|
free(dm_context);
|
||||||
|
|
||||||
|
context_roles_t roles;
|
||||||
|
if (context_roles_split(full_markdown, &roles) != 0) {
|
||||||
|
free(full_markdown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!allow_tools) {
|
if (!allow_tools) {
|
||||||
const char* tier_prefix = (tier == DIDACTYL_SENDER_WOT)
|
const char* tier_prefix = (tier == DIDACTYL_SENDER_WOT)
|
||||||
? "You are responding to a web-of-trust contact. Keep the response helpful and concise. Tool use is disabled for this tier."
|
? "You are responding to a web-of-trust contact. Keep the response helpful and concise. Tool use is disabled for this tier."
|
||||||
: "You are responding in chat-only mode. Tool use is disabled.";
|
: "You are responding in chat-only mode. Tool use is disabled.";
|
||||||
|
|
||||||
size_t ctx_len = strlen(dm_context ? dm_context : "") + strlen("\n\n") + strlen(tier_prefix) + 1U;
|
size_t ctx_len = strlen(roles.system_content ? roles.system_content : "") + strlen("\n\n") + strlen(tier_prefix) + 1U;
|
||||||
char* system_for_chat = (char*)malloc(ctx_len);
|
char* system_for_chat = (char*)malloc(ctx_len);
|
||||||
if (!system_for_chat) {
|
if (!system_for_chat) {
|
||||||
free(dm_context);
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(system_for_chat, ctx_len, "%s\n\n%s", dm_context ? dm_context : "", tier_prefix);
|
snprintf(system_for_chat, ctx_len, "%s\n\n%s", roles.system_content ? roles.system_content : "", tier_prefix);
|
||||||
|
|
||||||
size_t context_len = strlen("system:\n\nuser:\n") + strlen(system_for_chat) + strlen(message) + 1U;
|
append_context_log(sender_pubkey_hex, "llm_chat", full_markdown);
|
||||||
char* plain_context = (char*)malloc(context_len);
|
|
||||||
if (plain_context) {
|
|
||||||
snprintf(plain_context, context_len, "system:\n%s\n\nuser:\n%s", system_for_chat, message);
|
|
||||||
append_context_log(sender_pubkey_hex, "llm_chat", plain_context);
|
|
||||||
free(plain_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* response = llm_chat(system_for_chat, message);
|
char* response = llm_chat(system_for_chat, roles.user_content ? roles.user_content : message);
|
||||||
free(system_for_chat);
|
free(system_for_chat);
|
||||||
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
const char* fallback = "I could not get a response from the LLM right now.";
|
const char* fallback = "I could not get a response from the LLM right now.";
|
||||||
fprintf(stdout, "[didactyl] llm response unavailable, sending fallback\n");
|
fprintf(stdout, "[didactyl] llm response unavailable, sending fallback\n");
|
||||||
@@ -2114,23 +2248,25 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
strlen(response) > 240 ? "..." : "");
|
strlen(response) > 240 ? "..." : "");
|
||||||
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, response);
|
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, response);
|
||||||
free(response);
|
free(response);
|
||||||
free(dm_context);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* tools_json = tools_build_openai_schema_json(&g_tools_ctx);
|
char* tools_json = tools_build_openai_schema_json(&g_tools_ctx);
|
||||||
if (!tools_json) {
|
if (!tools_json) {
|
||||||
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Tool schema generation failed.");
|
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Tool schema generation failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* messages = cJSON_CreateArray();
|
cJSON* messages = cJSON_CreateArray();
|
||||||
if (!messages ||
|
if (!messages ||
|
||||||
append_simple_message(messages, "system", dm_context ? dm_context : "You are an AI agent. Respond to the message.") != 0 ||
|
append_simple_message(messages, "system", roles.system_content ? roles.system_content : "You are an AI agent. Respond to the message.") != 0 ||
|
||||||
append_simple_message(messages, "user", message) != 0) {
|
append_simple_message(messages, "user", roles.user_content ? roles.user_content : message) != 0) {
|
||||||
cJSON_Delete(messages);
|
cJSON_Delete(messages);
|
||||||
free(tools_json);
|
free(tools_json);
|
||||||
free(dm_context);
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Failed to initialize conversation messages.");
|
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Failed to initialize conversation messages.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2149,6 +2285,8 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
char* final_answer_owned = NULL;
|
char* final_answer_owned = NULL;
|
||||||
int turns_run = 0;
|
int turns_run = 0;
|
||||||
|
|
||||||
|
append_context_log(sender_pubkey_hex, "llm_chat_with_tools_messages", full_markdown);
|
||||||
|
|
||||||
for (int turn = 0; turn < max_turns; turn++) {
|
for (int turn = 0; turn < max_turns; turn++) {
|
||||||
turns_run = turn + 1;
|
turns_run = turn + 1;
|
||||||
char* messages_json = cJSON_PrintUnformatted(messages);
|
char* messages_json = cJSON_PrintUnformatted(messages);
|
||||||
@@ -2156,7 +2294,7 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_context_log(sender_pubkey_hex, "llm_chat_with_tools_messages", messages_json);
|
append_context_log(sender_pubkey_hex, "llm_chat_with_tools_turn", messages_json);
|
||||||
|
|
||||||
llm_response_t resp;
|
llm_response_t resp;
|
||||||
int rc = llm_chat_with_tools_messages(messages_json, tools_json, "auto", &resp);
|
int rc = llm_chat_with_tools_messages(messages_json, tools_json, "auto", &resp);
|
||||||
@@ -2165,7 +2303,8 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "LLM request failed.");
|
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "LLM request failed.");
|
||||||
cJSON_Delete(messages);
|
cJSON_Delete(messages);
|
||||||
free(tools_json);
|
free(tools_json);
|
||||||
free(dm_context);
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2218,7 +2357,8 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
llm_response_free(&resp);
|
llm_response_free(&resp);
|
||||||
cJSON_Delete(messages);
|
cJSON_Delete(messages);
|
||||||
free(tools_json);
|
free(tools_json);
|
||||||
free(dm_context);
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Failed to append tool result.");
|
(void)nostr_handler_send_dm_auto(sender_pubkey_hex, "Failed to append tool result.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2275,7 +2415,8 @@ void agent_on_message(const char* sender_pubkey_hex,
|
|||||||
free(final_answer_owned);
|
free(final_answer_owned);
|
||||||
cJSON_Delete(messages);
|
cJSON_Delete(messages);
|
||||||
free(tools_json);
|
free(tools_json);
|
||||||
free(dm_context);
|
context_roles_free(&roles);
|
||||||
|
free(full_markdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
void agent_cleanup(void) {
|
void agent_cleanup(void) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ int agent_build_admin_messages_json(const char* current_user_message,
|
|||||||
char** out_messages_json);
|
char** out_messages_json);
|
||||||
tools_context_t* agent_tools_context(void);
|
tools_context_t* agent_tools_context(void);
|
||||||
const char* agent_classify_message_part(cJSON* msg, int idx);
|
const char* agent_classify_message_part(cJSON* msg, int idx);
|
||||||
|
int agent_set_context_debug_mode(const char* mode);
|
||||||
void agent_append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload);
|
void agent_append_context_log(const char* sender_pubkey_hex, const char* phase, const char* context_payload);
|
||||||
void agent_cleanup(void);
|
void agent_cleanup(void);
|
||||||
|
|
||||||
|
|||||||
87
src/context_format.c
Normal file
87
src/context_format.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include "context_format.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int append_text(char** buf, size_t* cap, size_t* used, const char* s, size_t len) {
|
||||||
|
if (!buf || !cap || !used || !s) return -1;
|
||||||
|
if (*used + len + 1U > *cap) {
|
||||||
|
size_t next = *cap;
|
||||||
|
while (*used + len + 1U > next) {
|
||||||
|
next = (next == 0U) ? 256U : (next * 2U);
|
||||||
|
}
|
||||||
|
char* grown = (char*)realloc(*buf, next);
|
||||||
|
if (!grown) return -1;
|
||||||
|
*buf = grown;
|
||||||
|
*cap = next;
|
||||||
|
}
|
||||||
|
memcpy(*buf + *used, s, len);
|
||||||
|
*used += len;
|
||||||
|
(*buf)[*used] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* context_bump_headings(const char* text) {
|
||||||
|
if (!text) return NULL;
|
||||||
|
|
||||||
|
size_t cap = strlen(text) + 256; // Initial guess
|
||||||
|
size_t used = 0;
|
||||||
|
char* buf = (char*)malloc(cap);
|
||||||
|
if (!buf) return NULL;
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
const char* p = text;
|
||||||
|
while (*p) {
|
||||||
|
const char* eol = strchr(p, '\n');
|
||||||
|
size_t line_len = eol ? (size_t)(eol - p) : strlen(p);
|
||||||
|
|
||||||
|
// Check if line starts with '#'
|
||||||
|
if (line_len > 0 && p[0] == '#') {
|
||||||
|
// Add an extra '#'
|
||||||
|
if (append_text(&buf, &cap, &used, "#", 1) != 0) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the rest of the line
|
||||||
|
if (append_text(&buf, &cap, &used, p, line_len) != 0) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eol) {
|
||||||
|
if (append_text(&buf, &cap, &used, "\n", 1) != 0) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
p = eol + 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* context_build_title(tools_context_t* ctx) {
|
||||||
|
if (!ctx || !ctx->cfg) return strdup("# Didactyl Agent\n\n");
|
||||||
|
|
||||||
|
const char* name = "Didactyl Agent";
|
||||||
|
|
||||||
|
// Try to get name from kind 0 profile if available
|
||||||
|
if (ctx->template_skill_lookup) {
|
||||||
|
// We don't have direct access to the parsed kind 0 here easily,
|
||||||
|
// but we can try to extract it from the agent_profile tool output
|
||||||
|
// if we really wanted to. For now, let's stick to a simple default
|
||||||
|
// or use the config if it has a name field (it doesn't currently).
|
||||||
|
// A more robust way would be to parse the kind 0 JSON here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, just use a generic title. The identity skill will provide the rest.
|
||||||
|
char title[256];
|
||||||
|
snprintf(title, sizeof(title), "# %s\n\n", name);
|
||||||
|
return strdup(title);
|
||||||
|
}
|
||||||
9
src/context_format.h
Normal file
9
src/context_format.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef DIDACTYL_CONTEXT_FORMAT_H
|
||||||
|
#define DIDACTYL_CONTEXT_FORMAT_H
|
||||||
|
|
||||||
|
#include "tools/tools.h"
|
||||||
|
|
||||||
|
char* context_bump_headings(const char* text);
|
||||||
|
char* context_build_title(tools_context_t* ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
141
src/context_roles.c
Normal file
141
src/context_roles.c
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include "context_roles.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int append_text(char** buf, size_t* cap, size_t* used, const char* s, size_t len) {
|
||||||
|
if (!buf || !cap || !used || !s) return -1;
|
||||||
|
if (*used + len + 1U > *cap) {
|
||||||
|
size_t next = *cap;
|
||||||
|
while (*used + len + 1U > next) {
|
||||||
|
next = (next == 0U) ? 256U : (next * 2U);
|
||||||
|
}
|
||||||
|
char* grown = (char*)realloc(*buf, next);
|
||||||
|
if (!grown) return -1;
|
||||||
|
*buf = grown;
|
||||||
|
*cap = next;
|
||||||
|
}
|
||||||
|
memcpy(*buf + *used, s, len);
|
||||||
|
*used += len;
|
||||||
|
(*buf)[*used] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int context_roles_split(const char* markdown, context_roles_t* out) {
|
||||||
|
if (!out) return -1;
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
if (!markdown || markdown[0] == '\0') {
|
||||||
|
out->system_content = strdup("");
|
||||||
|
out->user_content = strdup("");
|
||||||
|
out->assistant_content = strdup("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sys_cap = 1024, sys_used = 0;
|
||||||
|
size_t usr_cap = 1024, usr_used = 0;
|
||||||
|
size_t ast_cap = 1024, ast_used = 0;
|
||||||
|
|
||||||
|
char* sys_buf = (char*)malloc(sys_cap);
|
||||||
|
char* usr_buf = (char*)malloc(usr_cap);
|
||||||
|
char* ast_buf = (char*)malloc(ast_cap);
|
||||||
|
|
||||||
|
if (!sys_buf || !usr_buf || !ast_buf) {
|
||||||
|
free(sys_buf);
|
||||||
|
free(usr_buf);
|
||||||
|
free(ast_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_buf[0] = '\0';
|
||||||
|
usr_buf[0] = '\0';
|
||||||
|
ast_buf[0] = '\0';
|
||||||
|
|
||||||
|
char** current_buf = &sys_buf;
|
||||||
|
size_t* current_cap = &sys_cap;
|
||||||
|
size_t* current_used = &sys_used;
|
||||||
|
|
||||||
|
const char* p = markdown;
|
||||||
|
while (*p) {
|
||||||
|
const char* eol = strchr(p, '\n');
|
||||||
|
size_t line_len = eol ? (size_t)(eol - p) : strlen(p);
|
||||||
|
|
||||||
|
if (strncmp(p, "system:", 7) == 0 && (line_len == 7 || (line_len == 8 && p[7] == '\r'))) {
|
||||||
|
current_buf = &sys_buf;
|
||||||
|
current_cap = &sys_cap;
|
||||||
|
current_used = &sys_used;
|
||||||
|
} else if (strncmp(p, "user:", 5) == 0 && (line_len == 5 || (line_len == 6 && p[5] == '\r'))) {
|
||||||
|
current_buf = &usr_buf;
|
||||||
|
current_cap = &usr_cap;
|
||||||
|
current_used = &usr_used;
|
||||||
|
} else if (strncmp(p, "assistant:", 10) == 0 && (line_len == 10 || (line_len == 11 && p[10] == '\r'))) {
|
||||||
|
current_buf = &ast_buf;
|
||||||
|
current_cap = &ast_cap;
|
||||||
|
current_used = &ast_used;
|
||||||
|
} else {
|
||||||
|
if (append_text(current_buf, current_cap, current_used, p, line_len) != 0) {
|
||||||
|
free(sys_buf);
|
||||||
|
free(usr_buf);
|
||||||
|
free(ast_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (eol) {
|
||||||
|
if (append_text(current_buf, current_cap, current_used, "\n", 1) != 0) {
|
||||||
|
free(sys_buf);
|
||||||
|
free(usr_buf);
|
||||||
|
free(ast_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eol) break;
|
||||||
|
p = eol + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim trailing newlines
|
||||||
|
while (sys_used > 0 && (sys_buf[sys_used - 1] == '\n' || sys_buf[sys_used - 1] == '\r')) {
|
||||||
|
sys_buf[--sys_used] = '\0';
|
||||||
|
}
|
||||||
|
while (usr_used > 0 && (usr_buf[usr_used - 1] == '\n' || usr_buf[usr_used - 1] == '\r')) {
|
||||||
|
usr_buf[--usr_used] = '\0';
|
||||||
|
}
|
||||||
|
while (ast_used > 0 && (ast_buf[ast_used - 1] == '\n' || ast_buf[ast_used - 1] == '\r')) {
|
||||||
|
ast_buf[--ast_used] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim leading newlines
|
||||||
|
char* sys_start = sys_buf;
|
||||||
|
while (*sys_start == '\n' || *sys_start == '\r') sys_start++;
|
||||||
|
if (sys_start > sys_buf) {
|
||||||
|
memmove(sys_buf, sys_start, sys_used - (sys_start - sys_buf) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* usr_start = usr_buf;
|
||||||
|
while (*usr_start == '\n' || *usr_start == '\r') usr_start++;
|
||||||
|
if (usr_start > usr_buf) {
|
||||||
|
memmove(usr_buf, usr_start, usr_used - (usr_start - usr_buf) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ast_start = ast_buf;
|
||||||
|
while (*ast_start == '\n' || *ast_start == '\r') ast_start++;
|
||||||
|
if (ast_start > ast_buf) {
|
||||||
|
memmove(ast_buf, ast_start, ast_used - (ast_start - ast_buf) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
out->system_content = sys_buf;
|
||||||
|
out->user_content = usr_buf;
|
||||||
|
out->assistant_content = ast_buf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void context_roles_free(context_roles_t* roles) {
|
||||||
|
if (!roles) return;
|
||||||
|
free(roles->system_content);
|
||||||
|
free(roles->user_content);
|
||||||
|
free(roles->assistant_content);
|
||||||
|
memset(roles, 0, sizeof(*roles));
|
||||||
|
}
|
||||||
13
src/context_roles.h
Normal file
13
src/context_roles.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef DIDACTYL_CONTEXT_ROLES_H
|
||||||
|
#define DIDACTYL_CONTEXT_ROLES_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* system_content;
|
||||||
|
char* user_content;
|
||||||
|
char* assistant_content;
|
||||||
|
} context_roles_t;
|
||||||
|
|
||||||
|
int context_roles_split(const char* markdown, context_roles_t* out);
|
||||||
|
void context_roles_free(context_roles_t* roles);
|
||||||
|
|
||||||
|
#endif
|
||||||
142
src/json_to_markdown.c
Normal file
142
src/json_to_markdown.c
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include "json_to_markdown.h"
|
||||||
|
#include "cjson/cJSON.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int append_text(char** buf, size_t* cap, size_t* used, const char* s) {
|
||||||
|
if (!buf || !cap || !used || !s) return -1;
|
||||||
|
size_t n = strlen(s);
|
||||||
|
if (*used + n + 1U > *cap) {
|
||||||
|
size_t next = *cap;
|
||||||
|
while (*used + n + 1U > next) {
|
||||||
|
next = (next == 0U) ? 256U : (next * 2U);
|
||||||
|
}
|
||||||
|
char* grown = (char*)realloc(*buf, next);
|
||||||
|
if (!grown) return -1;
|
||||||
|
*buf = grown;
|
||||||
|
*cap = next;
|
||||||
|
}
|
||||||
|
memcpy(*buf + *used, s, n);
|
||||||
|
*used += n;
|
||||||
|
(*buf)[*used] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_indent(int indent_level, char** buf, size_t* cap, size_t* used) {
|
||||||
|
for (int i = 0; i < indent_level; i++) {
|
||||||
|
append_text(buf, cap, used, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_json_node(cJSON* node, int indent_level, int is_list_item, char** buf, size_t* cap, size_t* used, int max_array_items) {
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
if (cJSON_IsString(node)) {
|
||||||
|
if (is_list_item) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- ");
|
||||||
|
}
|
||||||
|
append_text(buf, cap, used, node->valuestring ? node->valuestring : "");
|
||||||
|
append_text(buf, cap, used, "\n");
|
||||||
|
} else if (cJSON_IsNumber(node)) {
|
||||||
|
if (is_list_item) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- ");
|
||||||
|
}
|
||||||
|
char num_str[64];
|
||||||
|
if (node->valuedouble == (double)node->valueint) {
|
||||||
|
snprintf(num_str, sizeof(num_str), "%d", node->valueint);
|
||||||
|
} else {
|
||||||
|
snprintf(num_str, sizeof(num_str), "%f", node->valuedouble);
|
||||||
|
}
|
||||||
|
append_text(buf, cap, used, num_str);
|
||||||
|
append_text(buf, cap, used, "\n");
|
||||||
|
} else if (cJSON_IsBool(node)) {
|
||||||
|
if (is_list_item) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- ");
|
||||||
|
}
|
||||||
|
append_text(buf, cap, used, cJSON_IsTrue(node) ? "true\n" : "false\n");
|
||||||
|
} else if (cJSON_IsNull(node)) {
|
||||||
|
if (is_list_item) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- null\n");
|
||||||
|
}
|
||||||
|
} else if (cJSON_IsObject(node)) {
|
||||||
|
cJSON* child = node->child;
|
||||||
|
int first = 1;
|
||||||
|
while (child) {
|
||||||
|
if (is_list_item && first) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- **");
|
||||||
|
first = 0;
|
||||||
|
} else {
|
||||||
|
print_indent(indent_level + (is_list_item ? 1 : 0), buf, cap, used);
|
||||||
|
append_text(buf, cap, used, "- **");
|
||||||
|
}
|
||||||
|
append_text(buf, cap, used, child->string ? child->string : "unknown");
|
||||||
|
append_text(buf, cap, used, "**: ");
|
||||||
|
|
||||||
|
if (cJSON_IsObject(child) || cJSON_IsArray(child)) {
|
||||||
|
append_text(buf, cap, used, "\n");
|
||||||
|
render_json_node(child, indent_level + (is_list_item ? 2 : 1), 0, buf, cap, used, max_array_items);
|
||||||
|
} else {
|
||||||
|
render_json_node(child, 0, 0, buf, cap, used, max_array_items);
|
||||||
|
}
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
} else if (cJSON_IsArray(node)) {
|
||||||
|
int count = cJSON_GetArraySize(node);
|
||||||
|
int limit = (max_array_items > 0 && count > max_array_items) ? max_array_items : count;
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
|
cJSON* item = cJSON_GetArrayItem(node, i);
|
||||||
|
render_json_node(item, indent_level, 1, buf, cap, used, max_array_items);
|
||||||
|
}
|
||||||
|
if (count > limit) {
|
||||||
|
print_indent(indent_level, buf, cap, used);
|
||||||
|
char trunc_msg[64];
|
||||||
|
snprintf(trunc_msg, sizeof(trunc_msg), "- *(... and %d more items)*\n", count - limit);
|
||||||
|
append_text(buf, cap, used, trunc_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* json_to_markdown(const char* json_string, int max_array_items) {
|
||||||
|
if (!json_string) return NULL;
|
||||||
|
|
||||||
|
cJSON* root = cJSON_Parse(json_string);
|
||||||
|
if (!root) {
|
||||||
|
// If it's not valid JSON, just return a copy of the string
|
||||||
|
return strdup(json_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a plain string, return it without markdown formatting
|
||||||
|
if (cJSON_IsString(root)) {
|
||||||
|
char* out = strdup(root->valuestring ? root->valuestring : "");
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cap = 1024;
|
||||||
|
size_t used = 0;
|
||||||
|
char* buf = (char*)malloc(cap);
|
||||||
|
if (!buf) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
render_json_node(root, 0, 0, &buf, &cap, &used, max_array_items);
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
// Trim trailing newline if present
|
||||||
|
if (used > 0 && buf[used - 1] == '\n') {
|
||||||
|
buf[used - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
6
src/json_to_markdown.h
Normal file
6
src/json_to_markdown.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef DIDACTYL_JSON_TO_MARKDOWN_H
|
||||||
|
#define DIDACTYL_JSON_TO_MARKDOWN_H
|
||||||
|
|
||||||
|
char* json_to_markdown(const char* json_string, int max_array_items);
|
||||||
|
|
||||||
|
#endif
|
||||||
23
src/main.c
23
src/main.c
@@ -107,6 +107,8 @@ static void print_usage(const char* prog) {
|
|||||||
" Enable HTTP API and bind address (example: 127.0.0.1).\n"
|
" Enable HTTP API and bind address (example: 127.0.0.1).\n"
|
||||||
" --debug <0-5>\n"
|
" --debug <0-5>\n"
|
||||||
" Log level (0=fatal, 1=error, 2=warn, 3=info, 4=debug, 5=trace).\n"
|
" Log level (0=fatal, 1=error, 2=warn, 3=info, 4=debug, 5=trace).\n"
|
||||||
|
" --context-debug <off|init|full>\n"
|
||||||
|
" Context snapshot mode (off=none, init=initial only, full=initial+every turn).\n"
|
||||||
" --dump-schemas\n"
|
" --dump-schemas\n"
|
||||||
" Print tool schemas JSON and exit.\n"
|
" Print tool schemas JSON and exit.\n"
|
||||||
" --test-tool <name> <args_json>\n"
|
" --test-tool <name> <args_json>\n"
|
||||||
@@ -115,6 +117,8 @@ static void print_usage(const char* prog) {
|
|||||||
"Environment:\n"
|
"Environment:\n"
|
||||||
" DIDACTYL_NSEC\n"
|
" DIDACTYL_NSEC\n"
|
||||||
" Fallback private key when --nsec is not provided.\n"
|
" Fallback private key when --nsec is not provided.\n"
|
||||||
|
" DIDACTYL_CONTEXT_DEBUG\n"
|
||||||
|
" Context snapshot mode override: off, init, or full.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
" 1) Genesis-based startup\n"
|
" 1) Genesis-based startup\n"
|
||||||
@@ -931,6 +935,7 @@ int main(int argc, char** argv) {
|
|||||||
int dump_schemas = 0;
|
int dump_schemas = 0;
|
||||||
const char* test_tool_name = NULL;
|
const char* test_tool_name = NULL;
|
||||||
const char* test_tool_args = "{}";
|
const char* test_tool_args = "{}";
|
||||||
|
const char* context_debug_mode = "off";
|
||||||
|
|
||||||
didactyl_config_t cfg;
|
didactyl_config_t cfg;
|
||||||
memset(&cfg, 0, sizeof(cfg));
|
memset(&cfg, 0, sizeof(cfg));
|
||||||
@@ -995,6 +1000,8 @@ int main(int argc, char** argv) {
|
|||||||
api_port_override = atoi(argv[++i]);
|
api_port_override = atoi(argv[++i]);
|
||||||
} else if (strcmp(argv[i], "--api-bind") == 0 && i + 1 < argc) {
|
} else if (strcmp(argv[i], "--api-bind") == 0 && i + 1 < argc) {
|
||||||
api_bind_override = argv[++i];
|
api_bind_override = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--context-debug") == 0 && i + 1 < argc) {
|
||||||
|
context_debug_mode = argv[++i];
|
||||||
} else if (strcmp(argv[i], "--dump-schemas") == 0) {
|
} else if (strcmp(argv[i], "--dump-schemas") == 0) {
|
||||||
dump_schemas = 1;
|
dump_schemas = 1;
|
||||||
} else if (strcmp(argv[i], "--test-tool") == 0 && i + 2 < argc) {
|
} else if (strcmp(argv[i], "--test-tool") == 0 && i + 2 < argc) {
|
||||||
@@ -1057,6 +1064,22 @@ int main(int argc, char** argv) {
|
|||||||
DEBUG_INFO("[didactyl] startup phase: admin override applied from --admin (%.16s...)", cfg.admin.pubkey);
|
DEBUG_INFO("[didactyl] startup phase: admin override applied from --admin (%.16s...)", cfg.admin.pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char* env_context_debug = getenv("DIDACTYL_CONTEXT_DEBUG");
|
||||||
|
if (env_context_debug && env_context_debug[0] != '\0' &&
|
||||||
|
strcmp(context_debug_mode, "off") == 0) {
|
||||||
|
context_debug_mode = env_context_debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agent_set_context_debug_mode(context_debug_mode) != 0) {
|
||||||
|
fprintf(stderr, "Invalid context debug mode '%s' (expected off, init, or full)\n", context_debug_mode);
|
||||||
|
config_free(&cfg);
|
||||||
|
nostr_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
DEBUG_INFO("[didactyl] context debug mode: %s", context_debug_mode);
|
||||||
|
}
|
||||||
|
|
||||||
if (config_ensure_startup_skill_adoption(&cfg) != 0) {
|
if (config_ensure_startup_skill_adoption(&cfg) != 0) {
|
||||||
fprintf(stderr, "Failed to synthesize startup skill adoption events\n");
|
fprintf(stderr, "Failed to synthesize startup skill adoption events\n");
|
||||||
config_free(&cfg);
|
config_free(&cfg);
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
// Using DIDACTYL_ prefix to avoid conflicts with nostr_core_lib VERSION macros
|
// Using DIDACTYL_ prefix to avoid conflicts with nostr_core_lib VERSION macros
|
||||||
#define DIDACTYL_VERSION_MAJOR 0
|
#define DIDACTYL_VERSION_MAJOR 0
|
||||||
#define DIDACTYL_VERSION_MINOR 2
|
#define DIDACTYL_VERSION_MINOR 2
|
||||||
#define DIDACTYL_VERSION_PATCH 20
|
#define DIDACTYL_VERSION_PATCH 21
|
||||||
#define DIDACTYL_VERSION "v0.2.20"
|
#define DIDACTYL_VERSION "v0.2.21"
|
||||||
|
|
||||||
// Agent metadata
|
// Agent metadata
|
||||||
#define DIDACTYL_NAME "Didactyl"
|
#define DIDACTYL_NAME "Didactyl"
|
||||||
|
|||||||
@@ -3902,6 +3902,92 @@ char* nostr_handler_get_dm_history_json(const char* peer_pubkey_hex, int limit)
|
|||||||
return out ? out : strdup("[]");
|
return out ? out : strdup("[]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* nostr_handler_get_dm_history_markdown(const char* peer_pubkey_hex, int limit) {
|
||||||
|
if (!peer_pubkey_hex || strlen(peer_pubkey_hex) != 64U) {
|
||||||
|
return strdup("");
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_take = limit > 0 ? limit : 64;
|
||||||
|
if (max_take > DM_HISTORY_RING_SIZE) {
|
||||||
|
max_take = DM_HISTORY_RING_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cap = 1024;
|
||||||
|
size_t used = 0;
|
||||||
|
char* buf = (char*)malloc(cap);
|
||||||
|
if (!buf) return NULL;
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
pthread_mutex_lock(&g_dm_history_mutex);
|
||||||
|
|
||||||
|
int total = g_dm_history_count;
|
||||||
|
int matches = 0;
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
int idx = (g_dm_history_count < DM_HISTORY_RING_SIZE)
|
||||||
|
? i
|
||||||
|
: (g_dm_history_next + i) % DM_HISTORY_RING_SIZE;
|
||||||
|
dm_history_entry_t* entry = &g_dm_history_ring[idx];
|
||||||
|
if (entry->peer_pubkey_hex[0] == '\0' || !entry->content) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(entry->peer_pubkey_hex, peer_pubkey_hex) == 0) {
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int skip = matches > max_take ? (matches - max_take) : 0;
|
||||||
|
int seen = 0;
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
int idx = (g_dm_history_count < DM_HISTORY_RING_SIZE)
|
||||||
|
? i
|
||||||
|
: (g_dm_history_next + i) % DM_HISTORY_RING_SIZE;
|
||||||
|
dm_history_entry_t* entry = &g_dm_history_ring[idx];
|
||||||
|
if (entry->peer_pubkey_hex[0] == '\0' || !entry->content) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(entry->peer_pubkey_hex, peer_pubkey_hex) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (seen++ < skip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* role_label = "**You**";
|
||||||
|
if (entry->role == DIDACTYL_DM_HISTORY_USER) {
|
||||||
|
role_label = "**Admin**";
|
||||||
|
} else if (entry->role == DIDACTYL_DM_HISTORY_TOOL_REQUEST) {
|
||||||
|
role_label = "**Admin (Tool Request)**";
|
||||||
|
} else if (entry->role == DIDACTYL_DM_HISTORY_TOOL_RESPONSE) {
|
||||||
|
role_label = "**You (Tool Response)**";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t need = strlen("- ") + strlen(role_label) + strlen(": ") + strlen(entry->content) + 2U;
|
||||||
|
if (used + need > cap) {
|
||||||
|
size_t next = cap;
|
||||||
|
while (used + need > next) next *= 2U;
|
||||||
|
char* grown = (char*)realloc(buf, next);
|
||||||
|
if (!grown) {
|
||||||
|
pthread_mutex_unlock(&g_dm_history_mutex);
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buf = grown;
|
||||||
|
cap = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf + used, cap - used, "- %s: %s\n", role_label, entry->content);
|
||||||
|
used += strlen(buf + used);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&g_dm_history_mutex);
|
||||||
|
|
||||||
|
if (used > 0 && buf[used - 1] == '\n') {
|
||||||
|
buf[used - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
char* nostr_handler_get_admin_kind0_context(void) {
|
char* nostr_handler_get_admin_kind0_context(void) {
|
||||||
if (!g_cfg || !g_cfg->admin_context.enabled || !g_cfg->admin_context.track_kind_0) {
|
if (!g_cfg || !g_cfg->admin_context.enabled || !g_cfg->admin_context.track_kind_0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ int nostr_handler_dm_history_remember(const char* peer_pubkey_hex,
|
|||||||
const char* content,
|
const char* content,
|
||||||
didactyl_dm_history_role_t role);
|
didactyl_dm_history_role_t role);
|
||||||
char* nostr_handler_get_dm_history_json(const char* peer_pubkey_hex, int limit);
|
char* nostr_handler_get_dm_history_json(const char* peer_pubkey_hex, int limit);
|
||||||
|
char* nostr_handler_get_dm_history_markdown(const char* peer_pubkey_hex, int limit);
|
||||||
void nostr_handler_cleanup(void);
|
void nostr_handler_cleanup(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "prompt_template.h"
|
#include "prompt_template.h"
|
||||||
#include "cjson/cJSON.h"
|
#include "cjson/cJSON.h"
|
||||||
|
#include "json_to_markdown.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -177,9 +178,15 @@ char* prompt_template_resolve_inline_variables(const char* tpl, tools_context_t*
|
|||||||
if (!success || !cJSON_IsBool(success) || cJSON_IsTrue(success)) {
|
if (!success || !cJSON_IsBool(success) || cJSON_IsTrue(success)) {
|
||||||
cJSON* content = cJSON_GetObjectItemCaseSensitive(root, "content");
|
cJSON* content = cJSON_GetObjectItemCaseSensitive(root, "content");
|
||||||
if (content && cJSON_IsString(content) && content->valuestring) {
|
if (content && cJSON_IsString(content) && content->valuestring) {
|
||||||
replacement_owned = strdup(content->valuestring);
|
char* md = json_to_markdown(content->valuestring, 8);
|
||||||
|
replacement_owned = md ? md : strdup(content->valuestring);
|
||||||
} else if (content) {
|
} else if (content) {
|
||||||
replacement_owned = cJSON_PrintUnformatted(content);
|
char* raw = cJSON_PrintUnformatted(content);
|
||||||
|
if (raw) {
|
||||||
|
char* md = json_to_markdown(raw, 8);
|
||||||
|
replacement_owned = md ? md : raw;
|
||||||
|
if (md) free(raw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ char* execute_nostr_dm_history(tools_context_t* ctx, const char* args_json) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* prefix = (strcmp(role->valuestring, "user") == 0) ? "User: " : "Assistant: ";
|
const char* prefix = (strcmp(role->valuestring, "user") == 0) ? "- **Admin**: " : "- **You**: ";
|
||||||
if (append_text_local(&rendered, &cap, &used, prefix) != 0 ||
|
if (append_text_local(&rendered, &cap, &used, prefix) != 0 ||
|
||||||
append_text_local(&rendered, &cap, &used, content->valuestring) != 0 ||
|
append_text_local(&rendered, &cap, &used, content->valuestring) != 0 ||
|
||||||
append_text_local(&rendered, &cap, &used, "\n") != 0) {
|
append_text_local(&rendered, &cap, &used, "\n") != 0) {
|
||||||
|
|||||||
267
test_pool.c
Normal file
267
test_pool.c
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "./nostr_core_lib/cjson/cJSON.h"
|
||||||
|
#include "./nostr_core_lib/nostr_core/nostr_core.h"
|
||||||
|
|
||||||
|
static const char* k_default_relays[] = {
|
||||||
|
"wss://relay.damus.io",
|
||||||
|
"wss://relay.primal.net",
|
||||||
|
"wss://relay.laantungir.net"
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int eose_received;
|
||||||
|
int events_received;
|
||||||
|
int kind3_events;
|
||||||
|
int max_p_tags;
|
||||||
|
} test_ctx_t;
|
||||||
|
|
||||||
|
static volatile int g_ws_eose_seen = 0;
|
||||||
|
|
||||||
|
static long long now_ms(void) {
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((long long)ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000LL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count_tag(cJSON* tags, const char* key) {
|
||||||
|
if (!tags || !cJSON_IsArray(tags) || !key) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = cJSON_GetArraySize(tags);
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
cJSON* tag = cJSON_GetArrayItem(tags, i);
|
||||||
|
if (!tag || !cJSON_IsArray(tag) || cJSON_GetArraySize(tag) < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* k = cJSON_GetArrayItem(tag, 0);
|
||||||
|
if (k && cJSON_IsString(k) && k->valuestring && strcmp(k->valuestring, key) == 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_event(cJSON* event, const char* relay_url, void* user_data) {
|
||||||
|
test_ctx_t* ctx = (test_ctx_t*)user_data;
|
||||||
|
if (!ctx || !event || !cJSON_IsObject(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->events_received++;
|
||||||
|
|
||||||
|
cJSON* kind = cJSON_GetObjectItemCaseSensitive(event, "kind");
|
||||||
|
cJSON* id = cJSON_GetObjectItemCaseSensitive(event, "id");
|
||||||
|
cJSON* pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey");
|
||||||
|
cJSON* created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at");
|
||||||
|
cJSON* content = cJSON_GetObjectItemCaseSensitive(event, "content");
|
||||||
|
cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags");
|
||||||
|
|
||||||
|
int kind_val = (kind && cJSON_IsNumber(kind)) ? (int)kind->valuedouble : -1;
|
||||||
|
int p_tags = count_tag(tags, "p");
|
||||||
|
int r_tags = count_tag(tags, "r");
|
||||||
|
int tag_count = (tags && cJSON_IsArray(tags)) ? cJSON_GetArraySize(tags) : 0;
|
||||||
|
int content_len = (content && cJSON_IsString(content) && content->valuestring) ? (int)strlen(content->valuestring) : 0;
|
||||||
|
|
||||||
|
if (p_tags > ctx->max_p_tags) {
|
||||||
|
ctx->max_p_tags = p_tags;
|
||||||
|
}
|
||||||
|
if (kind_val == 3) {
|
||||||
|
ctx->kind3_events++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[EVENT] relay=%s kind=%d created_at=%lld tags=%d p_tags=%d r_tags=%d content_len=%d id=%.16s pubkey=%.16s\n",
|
||||||
|
relay_url ? relay_url : "<unknown>",
|
||||||
|
kind_val,
|
||||||
|
(created_at && cJSON_IsNumber(created_at)) ? (long long)created_at->valuedouble : -1LL,
|
||||||
|
tag_count,
|
||||||
|
p_tags,
|
||||||
|
r_tags,
|
||||||
|
content_len,
|
||||||
|
(id && cJSON_IsString(id) && id->valuestring) ? id->valuestring : "",
|
||||||
|
(pubkey && cJSON_IsString(pubkey) && pubkey->valuestring) ? pubkey->valuestring : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_eose(cJSON** events, int event_count, void* user_data) {
|
||||||
|
(void)events;
|
||||||
|
test_ctx_t* ctx = (test_ctx_t*)user_data;
|
||||||
|
if (!ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->eose_received = 1;
|
||||||
|
printf("[EOSE] received for subscription (event_count=%d)\n", event_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_callback(int level, const char* component, const char* message, void* user_data) {
|
||||||
|
(void)user_data;
|
||||||
|
const char* lvl = "?";
|
||||||
|
switch (level) {
|
||||||
|
case NOSTR_LOG_LEVEL_ERROR: lvl = "ERROR"; break;
|
||||||
|
case NOSTR_LOG_LEVEL_WARN: lvl = "WARN"; break;
|
||||||
|
case NOSTR_LOG_LEVEL_INFO: lvl = "INFO"; break;
|
||||||
|
case NOSTR_LOG_LEVEL_DEBUG: lvl = "DEBUG"; break;
|
||||||
|
case NOSTR_LOG_LEVEL_TRACE: lvl = "TRACE"; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!component) component = "core";
|
||||||
|
if (!message) message = "";
|
||||||
|
|
||||||
|
if (strcmp(component, "websocket") == 0) {
|
||||||
|
printf("[NOSTR %s] [%s] %s\n", lvl, component, message);
|
||||||
|
if (strstr(message, "[\"EOSE\"") != NULL) {
|
||||||
|
g_ws_eose_seen = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
const char* npub = "npub13lm5wf8dvsdnc2894pkhch9uf8phvw9varrv8zf4sc885hhdmc8q6lx7ks";
|
||||||
|
int timeout_ms = 15000;
|
||||||
|
|
||||||
|
if (argc >= 2 && argv[1] && argv[1][0] != '\0') {
|
||||||
|
npub = argv[1];
|
||||||
|
}
|
||||||
|
if (argc >= 3) {
|
||||||
|
timeout_ms = atoi(argv[2]);
|
||||||
|
if (timeout_ms <= 0) {
|
||||||
|
timeout_ms = 15000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char pubkey[32] = {0};
|
||||||
|
char pubkey_hex[65] = {0};
|
||||||
|
|
||||||
|
if (nostr_decode_npub(npub, pubkey) != 0) {
|
||||||
|
fprintf(stderr, "Failed to decode npub: %s\n", npub);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nostr_bytes_to_hex(pubkey, 32, pubkey_hex);
|
||||||
|
|
||||||
|
if (nostr_crypto_init() != 0) {
|
||||||
|
fprintf(stderr, "nostr_crypto_init failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nostr_set_log_callback(log_callback, NULL);
|
||||||
|
nostr_set_log_level(NOSTR_LOG_LEVEL_TRACE);
|
||||||
|
|
||||||
|
nostr_pool_reconnect_config_t* reconnect = nostr_pool_reconnect_config_default();
|
||||||
|
if (!reconnect) {
|
||||||
|
fprintf(stderr, "nostr_pool_reconnect_config_default failed\n");
|
||||||
|
nostr_crypto_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnect->enable_auto_reconnect = 1;
|
||||||
|
reconnect->ping_interval_seconds = 20;
|
||||||
|
reconnect->pong_timeout_seconds = 10;
|
||||||
|
|
||||||
|
nostr_relay_pool_t* pool = nostr_relay_pool_create(reconnect);
|
||||||
|
if (!pool) {
|
||||||
|
fprintf(stderr, "nostr_relay_pool_create failed\n");
|
||||||
|
nostr_crypto_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int relay_count = (int)(sizeof(k_default_relays) / sizeof(k_default_relays[0]));
|
||||||
|
for (int i = 0; i < relay_count; i++) {
|
||||||
|
if (nostr_relay_pool_add_relay(pool, k_default_relays[i]) != 0) {
|
||||||
|
fprintf(stderr, "Failed to add relay: %s\n", k_default_relays[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* filter = cJSON_CreateObject();
|
||||||
|
cJSON* kinds = cJSON_CreateArray();
|
||||||
|
cJSON* authors = cJSON_CreateArray();
|
||||||
|
if (!filter || !kinds || !authors) {
|
||||||
|
fprintf(stderr, "Failed to build filter JSON\n");
|
||||||
|
cJSON_Delete(filter);
|
||||||
|
cJSON_Delete(kinds);
|
||||||
|
cJSON_Delete(authors);
|
||||||
|
nostr_relay_pool_destroy(pool);
|
||||||
|
nostr_crypto_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(kinds, cJSON_CreateNumber(3));
|
||||||
|
cJSON_AddItemToObject(filter, "kinds", kinds);
|
||||||
|
cJSON_AddItemToArray(authors, cJSON_CreateString(pubkey_hex));
|
||||||
|
cJSON_AddItemToObject(filter, "authors", authors);
|
||||||
|
cJSON_AddNumberToObject(filter, "limit", 16);
|
||||||
|
|
||||||
|
test_ctx_t ctx;
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
|
printf("Target npub: %s\n", npub);
|
||||||
|
printf("Target hex : %s\n", pubkey_hex);
|
||||||
|
printf("Relays (%d):\n", relay_count);
|
||||||
|
for (int i = 0; i < relay_count; i++) {
|
||||||
|
printf(" - %s\n", k_default_relays[i]);
|
||||||
|
}
|
||||||
|
printf("Subscribing to kind=3 with timeout=%d ms\n", timeout_ms);
|
||||||
|
|
||||||
|
nostr_pool_subscription_t* sub = nostr_relay_pool_subscribe(
|
||||||
|
pool,
|
||||||
|
k_default_relays,
|
||||||
|
relay_count,
|
||||||
|
filter,
|
||||||
|
on_event,
|
||||||
|
on_eose,
|
||||||
|
&ctx,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NOSTR_POOL_EOSE_FIRST,
|
||||||
|
12,
|
||||||
|
20
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!sub) {
|
||||||
|
fprintf(stderr, "nostr_relay_pool_subscribe failed\n");
|
||||||
|
cJSON_Delete(filter);
|
||||||
|
nostr_relay_pool_destroy(pool);
|
||||||
|
nostr_crypto_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long started = now_ms();
|
||||||
|
while (!ctx.eose_received && !g_ws_eose_seen) {
|
||||||
|
long long elapsed = now_ms() - started;
|
||||||
|
if (elapsed >= timeout_ms) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void)nostr_relay_pool_poll(pool, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nSummary:\n");
|
||||||
|
printf(" EOSE callback : %s\n", ctx.eose_received ? "yes" : "no");
|
||||||
|
printf(" Websocket EOSE: %s\n", g_ws_eose_seen ? "yes" : "no");
|
||||||
|
printf(" Events seen : %d\n", ctx.events_received);
|
||||||
|
printf(" Kind-3 events : %d\n", ctx.kind3_events);
|
||||||
|
printf(" Max p-tags : %d\n", ctx.max_p_tags);
|
||||||
|
|
||||||
|
if (!ctx.eose_received && g_ws_eose_seen) {
|
||||||
|
fprintf(stderr, "NOTE: Relay sent EOSE on websocket but subscription callback did not fire (pool EOSE behavior mismatch).\n");
|
||||||
|
}
|
||||||
|
if (!ctx.eose_received && !g_ws_eose_seen) {
|
||||||
|
fprintf(stderr, "Timed out waiting for EOSE after %d ms\n", timeout_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)nostr_pool_subscription_close(sub);
|
||||||
|
cJSON_Delete(filter);
|
||||||
|
nostr_relay_pool_destroy(pool);
|
||||||
|
nostr_crypto_cleanup();
|
||||||
|
|
||||||
|
return (ctx.eose_received || g_ws_eose_seen) ? 0 : 2;
|
||||||
|
}
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
},
|
},
|
||||||
"dm_protocol": "nip04",
|
"dm_protocol": "nip04",
|
||||||
"llm": {
|
"llm": {
|
||||||
"provider": "openai",
|
"provider": "https://api.ppq.ai",
|
||||||
"api_key": "sk-REPLACE_WITH_API_KEY",
|
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
|
||||||
"model": "claude-haiku-4.5",
|
"model": "claude-haiku-4.5",
|
||||||
"base_url": "https://api.anthropic.com/v1",
|
"base_url": "https://api.ppq.ai",
|
||||||
"max_tokens": 512,
|
"max_tokens": 10000,
|
||||||
"temperature": 0.3
|
"temperature": 0.7
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
@@ -54,6 +55,7 @@ class AgentProcess:
|
|||||||
commands = [
|
commands = [
|
||||||
["lsof", "-t", f"-iTCP:{self.api_port}", "-sTCP:LISTEN"],
|
["lsof", "-t", f"-iTCP:{self.api_port}", "-sTCP:LISTEN"],
|
||||||
["fuser", f"{self.api_port}/tcp"],
|
["fuser", f"{self.api_port}/tcp"],
|
||||||
|
["ss", "-ltnp"],
|
||||||
]
|
]
|
||||||
|
|
||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
@@ -61,7 +63,18 @@ class AgentProcess:
|
|||||||
proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
output = f"{proc.stdout}\n{proc.stderr}"
|
output = f"{proc.stdout}\n{proc.stderr}"
|
||||||
|
|
||||||
|
if cmd and cmd[0] == "ss":
|
||||||
|
port_token = f":{self.api_port}"
|
||||||
|
for line in output.splitlines():
|
||||||
|
if port_token not in line:
|
||||||
|
continue
|
||||||
|
for m in re.finditer(r"pid=(\d+)", line):
|
||||||
|
pids.add(int(m.group(1)))
|
||||||
|
continue
|
||||||
|
|
||||||
for token in output.split():
|
for token in output.split():
|
||||||
if token.isdigit():
|
if token.isdigit():
|
||||||
pids.add(int(token))
|
pids.add(int(token))
|
||||||
|
|||||||
390
tests/results/20260404T135221Z/agent_debug.log
Normal file
390
tests/results/20260404T135221Z/agent_debug.log
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
[2026-04-04 10:04:51] [INFO ] [main.c:1016] Didactyl v0.2.20 starting
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2207] [didactyl] initializing relay pool with 2 relays
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:51] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1775311491", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1775311491", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [01] Relay connectivity: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:255] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1775311492", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1775311492", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=702>
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [03] Validate LLM config: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [03] Validate LLM config: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [04] Validate admin config: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [04] Validate admin config: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [05] Initialize LLM client: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [05] Initialize LLM client: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1775311492", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1775311492", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1245] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:255] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=621>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=623>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3297] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=800>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=802>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=714>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=716>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1267] [didactyl] startup phase: persisted encrypted runtime config to Nostr
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [08] Initialize agent: begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1775311493", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1775311493", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","98b892b33ce3731cbeb82d791f5e41c7deade4bb61756ed600a14f3aeaa7d45e",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","98b892b33ce3731cbeb82d791f5e41c7deade4bb61756ed600a14f3aeaa7d45e",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","7fb5e7e09092254b700df2e7a8473fdca42ee09e3a32b86d262ad2403807f920",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","7fb5e7e09092254b700df2e7a8473fdca42ee09e3a32b86d262ad2403807f920",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa",true,"duplicate: have this event"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=656>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","c27bd1317e1c716b8450c4302b42214397fd03d2620d39b8f28d3fe765b446d7",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","8842d5de102138e7f7bc72819624a5735360d575e1cd136cc69902b38544a717",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","8842d5de102138e7f7bc72819624a5735360d575e1cd136cc69902b38544a717",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","c27bd1317e1c716b8450c4302b42214397fd03d2620d39b8f28d3fe765b446d7",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [08] Initialize agent: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [09] Initialize trigger manager: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:814] [didactyl] trigger manager initialized (capacity=16)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [09] Initialize trigger manager: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1308] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [10] Load startup triggers: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1311] [didactyl] startup phase: startup-config trigger load begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1138] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1021] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1029] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1315] [didactyl] startup phase: startup-config trigger load end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [10] Load startup triggers: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:327] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:334] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":6,"events_published_ok":4,"events_published_failed":2,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":6,"events_published_ok":6,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493}]}
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1775311493", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1775311493", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:354] [didactyl] kind10002 query received event_count=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:451] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:556] [didactyl] kind10002 wait success: relay_count=2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:558] [didactyl] kind10002 relay[0]=wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:558] [didactyl] kind10002 relay[1]=wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:562] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":6,"events_published_ok":4,"events_published_failed":2,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":6,"events_published_ok":6,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493}]}
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:255] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [12] Subscribe admin context: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1366] [didactyl] startup phase: subscribe admin context begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2352] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1370] [didactyl] startup phase: subscribe admin context end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [12] Subscribe admin context: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [13] Subscribe agent self context: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1374] [didactyl] startup phase: subscribe agent self context begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2440] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1378] [didactyl] startup phase: subscribe agent self context end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [13] Subscribe agent self context: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1382] [didactyl] startup phase: subscribe self skill cache begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1775311493", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1775311493", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1775311493", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1775311493", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2532] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:1725] [didactyl] self-skill EOSE received: cached skill events=0
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:44] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [trigger_manager.c:918] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:54] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1449] [didactyl] startup phase: subscribe self skill cache end
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:255] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:248] [didactyl] startup checklist [15] Subscribe DMs: begin
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1453] [didactyl] startup phase: subscribe DMs begin
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1775311494", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1775311494", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2643] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:2644] [didactyl] DEBUG DM subscription g_start_time=1775311491 now=1775311494 delta=3 relay_count=2
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1468] [didactyl] startup phase: subscribe DMs end
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:258] [didactyl] startup checklist [15] Subscribe DMs: ok
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:248] [didactyl] startup checklist [16] Subscribe wallet events: begin
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1472] [didactyl] startup phase: subscribe wallet events begin
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1775311494", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1775311494", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2696] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1476] [didactyl] startup phase: subscribe wallet events end
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:258] [didactyl] startup checklist [16] Subscribe wallet events: ok
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:248] [didactyl] startup checklist [17] Initialize cashu wallet: begin
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1775311494", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1775311494", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1775311494"]
|
||||||
|
[2026-04-04 10:04:54] [WARN ] [main.c:1492] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:255] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
|
||||||
|
[2026-04-04 10:04:54] [WARN ] [main.c:1528] [didactyl] HTTP API disabled due to bind/init failure; agent will continue without local API
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1499] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-04 10:04:54 (version v0.2.20, connected relays: 2/2).
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1491] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1775311494,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"L7Q6tbtXVWYnJZFZkkVvVfG/+6NQa9V8UMMK2tICfBTaG9V2MfwaKg9cVmC5BkmDl44QuJo7HFMQWHhj9NRlM1D2mP8JVTFndXdVCM5KU6tslhRfrRpjRFhfkGd4+0/lpmhVSq7wUP3f7oLOAvQaH66mDA7bIebr5BIss/4rSFE=?iv=fOZr9Tl0qw3NBGqRXOJPAA==","id":"3edc6798888fa063a724c277ed553f35fcf339aa62a74b039edf35907bc4da9e","sig":"0fc1537a1729128950d0cdffee17822186b7fc1fc1b4c29cf1e23b8979ae7264b1e702600bfa6c9778916b316e2b8b1050a113c815ba8a890ad455b2d2947bdc"}
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:906] [didactyl] publish DM target relays (2):
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.damus.io (async)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.primal.net (async)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2852] [didactyl] sent DM 3edc6798888fa063... to 254d7a7f68b4443f... via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:255] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1571] [didactyl] entering main poll loop
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1572] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","3edc6798888fa063a724c277ed553f35fcf339aa62a74b039edf35907bc4da9e",true,""]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","3edc6798888fa063a724c277ed553f35fcf339aa62a74b039edf35907bc4da9e",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:05:36] [INFO ] [main.c:1584] [didactyl] shutting down
|
||||||
|
[2026-04-04 10:05:36] [INFO ] [trigger_manager.c:1602] [didactyl] trigger manager cleaned up
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1775311494"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1775311494"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1775311494"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1775311494"]
|
||||||
53
tests/results/20260404T135221Z/runtime_test_genesis.jsonc
Normal file
53
tests/results/20260404T135221Z/runtime_test_genesis.jsonc
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
// TEST CONFIGURATION
|
||||||
|
// Use disposable keys/accounts only.
|
||||||
|
"key": {
|
||||||
|
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
|
||||||
|
},
|
||||||
|
"dm_protocol": "nip04",
|
||||||
|
"llm": {
|
||||||
|
"provider": "https://api.ppq.ai",
|
||||||
|
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
|
||||||
|
"model": "claude-haiku-4.5",
|
||||||
|
"base_url": "https://api.ppq.ai",
|
||||||
|
"max_tokens": 10000,
|
||||||
|
"temperature": 0.7
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"enabled": true,
|
||||||
|
"port": 8485,
|
||||||
|
"bind_address": "127.0.0.1"
|
||||||
|
},
|
||||||
|
"startup_events": [
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"content_fields": {
|
||||||
|
"name": "Didactyl Test Agent",
|
||||||
|
"about": "Automated test instance"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 10002,
|
||||||
|
"content": "",
|
||||||
|
"tags": [
|
||||||
|
["r", "wss://relay.damus.io"],
|
||||||
|
["r", "wss://relay.primal.net"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 31124,
|
||||||
|
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
|
||||||
|
"tags": [
|
||||||
|
["d", "identity_and_rules"],
|
||||||
|
["app", "didactyl"],
|
||||||
|
["scope", "private"],
|
||||||
|
["trigger", "dm"],
|
||||||
|
["filter", "{\"from\":\"admin\"}"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
574
tests/results/20260404T135328Z/agent_debug.log
Normal file
574
tests/results/20260404T135328Z/agent_debug.log
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
[2026-04-04 09:53:31] [INFO ] [main.c:1016] Didactyl v0.2.20 starting
|
||||||
|
[2026-04-04 09:53:31] [INFO ] [nostr_handler.c:2207] [didactyl] initializing relay pool with 2 relays
|
||||||
|
[2026-04-04 09:53:31] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:31] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:31] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1775310811", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:31] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1775310811", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:31] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1775310811"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1775310811"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1775310811"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1775310811"]
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [01] Relay connectivity: begin
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:255] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1775310812", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1775310812", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=702>
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:258] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [03] Validate LLM config: begin
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:258] [didactyl] startup checklist [03] Validate LLM config: ok
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [04] Validate admin config: begin
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:258] [didactyl] startup checklist [04] Validate admin config: ok
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [05] Initialize LLM client: begin
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:258] [didactyl] startup checklist [05] Initialize LLM client: ok
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1775310812", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1775310812", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:1245] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:255] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1775310812", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1775310812", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1775310812"]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=621>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=623>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3297] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=800>
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=802>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=714>
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=716>
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:1267] [didactyl] startup phase: persisted encrypted runtime config to Nostr
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:258] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
|
||||||
|
[2026-04-04 09:53:32] [INFO ] [main.c:248] [didactyl] startup checklist [08] Initialize agent: begin
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1775310812", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:32] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1775310812", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","62db0aa31438a53f9811b70aa5de7d8b5e07f9327a1df1a1f28d1c56f2041cdd",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","62db0aa31438a53f9811b70aa5de7d8b5e07f9327a1df1a1f28d1c56f2041cdd",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b2c46547046ec744abd08f147d49c1d218011fef013e6effc94fde7203db60d8",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b2c46547046ec744abd08f147d49c1d218011fef013e6effc94fde7203db60d8",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","8e6842039e11bfabaa9ba7e2c9e94c9a75a87b2b2a8ea3f8c9ea4a31a8bbbbf8",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","8e6842039e11bfabaa9ba7e2c9e94c9a75a87b2b2a8ea3f8c9ea4a31a8bbbbf8",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","912179848fa53e52e842e13b124c8e49d3015ef48b15a079ea4bd687b6251fc4",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","912179848fa53e52e842e13b124c8e49d3015ef48b15a079ea4bd687b6251fc4",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1775310812"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1775310812"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","07e867604bb4b8bd8a8925cdc485f437c7e6463a3cf039d3f3b1af42f4f6e95e",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1775310812"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1775310812"]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:258] [didactyl] startup checklist [08] Initialize agent: ok
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [09] Initialize trigger manager: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [trigger_manager.c:814] [didactyl] trigger manager initialized (capacity=16)
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:258] [didactyl] startup checklist [09] Initialize trigger manager: ok
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1308] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [10] Load startup triggers: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1311] [didactyl] startup phase: startup-config trigger load begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [trigger_manager.c:1138] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [trigger_manager.c:1021] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [trigger_manager.c:1029] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1315] [didactyl] startup phase: startup-config trigger load end
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:258] [didactyl] startup checklist [10] Load startup triggers: ok
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:327] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:334] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":6,"events_published_ok":3,"events_published_failed":1,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775310811,"last_event_time":1775310813,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":2,"events_published":6,"events_published_ok":5,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775310811,"last_event_time":1775310813}]}
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1775310813", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1775310813", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b4ed5a24cfff8247076e5d3320511fee0a0546ec0000974382422e8f82e8ecb7",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b4ed5a24cfff8247076e5d3320511fee0a0546ec0000974382422e8f82e8ecb7",true,""]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","07e867604bb4b8bd8a8925cdc485f437c7e6463a3cf039d3f3b1af42f4f6e95e",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:354] [didactyl] kind10002 query received event_count=1
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:451] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:556] [didactyl] kind10002 wait success: relay_count=2
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:558] [didactyl] kind10002 relay[0]=wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:558] [didactyl] kind10002 relay[1]=wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:562] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":6,"events_published_ok":3,"events_published_failed":3,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775310811,"last_event_time":1775310813,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":2,"events_published":6,"events_published_ok":6,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775310811,"last_event_time":1775310813}]}
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:255] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [12] Subscribe admin context: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1366] [didactyl] startup phase: subscribe admin context begin
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1775310813", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1775310813", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1775310813", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1775310813", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:2352] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1370] [didactyl] startup phase: subscribe admin context end
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:258] [didactyl] startup checklist [12] Subscribe admin context: ok
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [13] Subscribe agent self context: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1374] [didactyl] startup phase: subscribe agent self context begin
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1775310813", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1775310813", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1775310813", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1775310813", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:2440] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1378] [didactyl] startup phase: subscribe agent self context end
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:258] [didactyl] startup checklist [13] Subscribe agent self context: ok
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:248] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [main.c:1382] [didactyl] startup phase: subscribe self skill cache begin
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1775310813", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1775310813", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1775310813", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1775310813", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:2532] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=9f094c21eade42f8c2f23fbce8127d13e6f0baacef8ead7afca66dd54d2033a7 created_at=1775310813 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:53:33] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=62107bfc20c3b449541878519bed40ebf94c21d49a1a9bb1da55c3f2d035fa7d created_at=1775310813 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1775310813"]
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:33] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1775310813"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1775310813"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=912179848fa53e52e842e13b124c8e49d3015ef48b15a079ea4bd687b6251fc4 created_at=1775310812 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=e54b9c4384ee5e214a337f153c9cb7ecc61b46b77bce99851c2b80166cc3dd6d created_at=1775310771 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1775310813"]
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:1725] [didactyl] self-skill EOSE received: cached skill events=0
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:44] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [trigger_manager.c:918] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:54] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=9f094c21eade42f8c2f23fbce8127d13e6f0baacef8ead7afca66dd54d2033a7 created_at=1775310813
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=10123 d_tag=- id=62107bfc20c3b449541878519bed40ebf94c21d49a1a9bb1da55c3f2d035fa7d created_at=1775310813
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1449] [didactyl] startup phase: subscribe self skill cache end
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:255] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:248] [didactyl] startup checklist [15] Subscribe DMs: begin
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1453] [didactyl] startup phase: subscribe DMs begin
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1775310814", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775310811,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1775310814", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775310811,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2643] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:2644] [didactyl] DEBUG DM subscription g_start_time=1775310811 now=1775310814 delta=3 relay_count=2
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1468] [didactyl] startup phase: subscribe DMs end
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:258] [didactyl] startup checklist [15] Subscribe DMs: ok
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:248] [didactyl] startup checklist [16] Subscribe wallet events: begin
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1472] [didactyl] startup phase: subscribe wallet events begin
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1775310814", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775310811,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1775310814", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775310811,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2696] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1476] [didactyl] startup phase: subscribe wallet events end
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:258] [didactyl] startup checklist [16] Subscribe wallet events: ok
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:248] [didactyl] startup checklist [17] Initialize cashu wallet: begin
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1775310814", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1775310814", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1775310813"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1775310814"]
|
||||||
|
[2026-04-04 09:53:34] [WARN ] [main.c:1492] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:255] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
|
||||||
|
[2026-04-04 09:53:34] [WARN ] [main.c:1528] [didactyl] HTTP API disabled due to bind/init failure; agent will continue without local API
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1499] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-04 09:53:34 (version v0.2.20, connected relays: 2/2).
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:1491] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1775310814,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"2IdS5q7P2xG6npiwo8XNCheTJ0ORjlriZhvvgByCrOrcY7U4roaoXA0AIJXM9CQxWLSkrWaXi0h1DTSOPZVCo5SqhQHEW4phQRWSz/bKnTjd3v8FTbCqO/JG1ghELrtmc3wED7CkEudSYgIEn46YYiYtomq/ulvkx7W6cm38tRM=?iv=jGIH5/frLMaWsdBfOKb0Gw==","id":"67ea8af90c4f8e8f1d9267beea62ce3c85c38493e386d22019b8a51b430782ba","sig":"1d6589f39630ad5e278b6c2a4b550903f7f09a0e5f5c4a42257a36e718c10ae9d959db9c73d72a3ab597baeac41076a71c7dfc3a87e6ba234e98946a6205dbef"}
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:906] [didactyl] publish DM target relays (2):
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.damus.io (async)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.primal.net (async)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [nostr_handler.c:2852] [didactyl] sent DM 67ea8af90c4f8e8f... to 254d7a7f68b4443f... via 2 connected relay(s)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:255] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1571] [didactyl] entering main poll loop
|
||||||
|
[2026-04-04 09:53:34] [INFO ] [main.c:1572] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","67ea8af90c4f8e8f1d9267beea62ce3c85c38493e386d22019b8a51b430782ba",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 09:53:34] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","67ea8af90c4f8e8f1d9267beea62ce3c85c38493e386d22019b8a51b430782ba",true,""]
|
||||||
|
[2026-04-04 09:53:37] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:53:37] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:37] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:53:37] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=9153008526c935129f5e6aad28d37b8cf73eade2cac7a581ea19bb31ddfb77fd created_at=1775310817 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:37] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:37] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:37] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:53:37] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=e3c57af82d9726d819e56625794a1887914536576cc80c6dd9b5795dc533699b created_at=1775310817 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:38] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:53:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:53:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:53:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=6136e4b953dff6c275673c984419e3732528d588de5eedd8d492123638d4a459 created_at=1775310821 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:42] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:42] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:53:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=a42e4d656c81b6393d9ca684b2c4609d1268e8b41e6a6170ef33c8d25d448b8d created_at=1775310821 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:43] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:53:46] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:53:46] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:53:46] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:53:46] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=3e46947f0f9953c994de18c03873c8290528791d5e161489d3830288e758851e created_at=1775310826 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:53:46] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:53:46] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:53:46] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:53:46] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=555277e0d773c2c05dfd59495698e0f2ae63b88a2c892716d34fbf731f90c93b created_at=1775310826 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=199821474ffaaedf3e7d90e8848fb95adfb3c547d25e62292f2ae01c6d15be26 created_at=1775310905 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=199821474ffaaedf3e7d90e8848fb95adfb3c547d25e62292f2ae01c6d15be26 created_at=1775310905 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=34ab5236e0848a5d27a6d98be6c3962919867267d861ae88d7887c186dc59d6f created_at=1775310905 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:55:05] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:55:05] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=34ab5236e0848a5d27a6d98be6c3962919867267d861ae88d7887c186dc59d6f created_at=1775310905 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=3593e19374c0110c7fc6d62dddb4d5ea5aa96d71a6b5a87df3f58e7e6044b721 created_at=1775310986 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=3593e19374c0110c7fc6d62dddb4d5ea5aa96d71a6b5a87df3f58e7e6044b721 created_at=1775310986 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a099e3e10e33e4874c687dd7a6c19efc4cf96500c9190279e8f7a0a02ba655bb created_at=1775310986 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:56:27] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a099e3e10e33e4874c687dd7a6c19efc4cf96500c9190279e8f7a0a02ba655bb created_at=1775310986 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:56:27] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=6b1239e90ef1eb0cc6d01d5e23e46a35075f8676fa9bdee1f27844da3bceebae created_at=1775311069 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=6b1239e90ef1eb0cc6d01d5e23e46a35075f8676fa9bdee1f27844da3bceebae created_at=1775311069 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=93a70c1d405d848e4c0d8e6b73b1e5ca9111c06549ddce551a275590846865ab created_at=1775311069 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:57:50] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:57:50] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=93a70c1d405d848e4c0d8e6b73b1e5ca9111c06549ddce551a275590846865ab created_at=1775311069 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=20ee7cfd49445a14a8163d37cc2113989f08db64d5bd97b6635e7b71d5067397 created_at=1775311149 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=20ee7cfd49445a14a8163d37cc2113989f08db64d5bd97b6635e7b71d5067397 created_at=1775311149 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a1da473de1325a5a6d0b64d7f4435ac61ae8ebde1a7a76a3abb27746529e0414 created_at=1775311149 via wss://relay.damus.io
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 09:59:10] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a1da473de1325a5a6d0b64d7f4435ac61ae8ebde1a7a76a3abb27746529e0414 created_at=1775311149 via wss://relay.primal.net
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 09:59:10] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=23e119df15e5dab7da6052bef17b973eb732d64f96f0cb81bae55c7eafe0cf84 created_at=1775311231 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=23e119df15e5dab7da6052bef17b973eb732d64f96f0cb81bae55c7eafe0cf84 created_at=1775311231 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=af0e63a9aa9b8dcdec1705ef2b0e6eb183a760563916ac1abe4ccd4b3ff31b9e created_at=1775311231 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=af0e63a9aa9b8dcdec1705ef2b0e6eb183a760563916ac1abe4ccd4b3ff31b9e created_at=1775311231 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:00:31] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:00:31] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:01:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:01:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:01:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:01:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:01:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:01:54] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=b08288f7f0691347979d73d8224d59ab518b4c4903d467261c6f54a4ac6438a6 created_at=1775311314 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:01:55] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=e2da3b48d758a294257443571dbfaede7befff218e0a7ed633f8ae8d90d44b11 created_at=1775311314 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:01:55] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=b08288f7f0691347979d73d8224d59ab518b4c4903d467261c6f54a4ac6438a6 created_at=1775311314 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:01:55] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=e2da3b48d758a294257443571dbfaede7befff218e0a7ed633f8ae8d90d44b11 created_at=1775311314 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:01:55] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b1e317e969767bd23746d85d16932a907d45c49911ec2d954f45253a0afc8c45 created_at=1775311361 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=4ce55cdf481bdc52128adcf546c526819e910e6e429510a67b16aee6ab8a27ce created_at=1775311361 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b1e317e969767bd23746d85d16932a907d45c49911ec2d954f45253a0afc8c45 created_at=1775311361 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=1de0c656f13e494782235710020ec1863236f385ea9bbde63973e32fac22e96e created_at=1775311362 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:02:42] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=5e118f362ee720887516af8389a895327771a32d97be51d179061cc959856306 created_at=1775311362 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:02:42] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:02:43] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=91a98af6794b4cda3e23918a72596ea072432a3bf61d0d2f175266555f69ad2c created_at=1775311427 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=91a98af6794b4cda3e23918a72596ea072432a3bf61d0d2f175266555f69ad2c created_at=1775311427 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a101386a4d04cfe90e3278a442f7d8a5666b822551679be9e1da7ee3b50e66c0 created_at=1775311427 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:03:47] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=a101386a4d04cfe90e3278a442f7d8a5666b822551679be9e1da7ee3b50e66c0 created_at=1775311427 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:03:47] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=564>
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:1505] [didactyl] DEBUG on_event ENTRY from wss://relay.primal.net (event=0x75dedd26ac00 g_cfg=0x7fff11e75dd0 g_dm_callback=set)
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:1539] [didactyl] DEBUG on_event: kind=4 id=d11595fbb84cc4e0... from=1eb171136dbb1ba6... via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:1491] [didactyl] received encrypted DM event: {"content":"vU6HDxbHyDPXuQc6QBb6mKaxpT/v84wpTSRnDxIKB9HUtoMXbkmSmEWOE84JW8dm?iv=COBkis+eKnjifb3Qs2dSCg==","created_at":1775311434,"id":"d11595fbb84cc4e0d86c0791c1fc2fb0cd3c00f0556fa80529a6b2004b4d8eee","kind":4,"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","sig":"7db392af3ada4cba8fb8d864629f503e864797cb7d76577e573ece9127e828bd82cc4b6366a2ed97dec524be412a32b9389f46f678c72dcaac6f66d3f1e206d3","tags":[["p","1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]]}
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:1499] [didactyl] received decrypted DM content: This is a test DM from me to myself!
|
||||||
|
[2026-04-04 10:03:54] [TRACE] [nostr_handler.c:1664] [didactyl] DEBUG on_event: ignoring self-sent DM 1eb171136dbb1ba6... via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:05:36] [INFO ] [main.c:1584] [didactyl] shutting down
|
||||||
|
[2026-04-04 10:05:36] [INFO ] [trigger_manager.c:1602] [didactyl] trigger manager cleaned up
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1775310813"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1775310814"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1775310814"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1775310814"]
|
||||||
|
[2026-04-04 10:05:36] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1775310814"]
|
||||||
53
tests/results/20260404T135328Z/runtime_test_genesis.jsonc
Normal file
53
tests/results/20260404T135328Z/runtime_test_genesis.jsonc
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
// TEST CONFIGURATION
|
||||||
|
// Use disposable keys/accounts only.
|
||||||
|
"key": {
|
||||||
|
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
|
||||||
|
},
|
||||||
|
"dm_protocol": "nip04",
|
||||||
|
"llm": {
|
||||||
|
"provider": "https://api.ppq.ai",
|
||||||
|
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
|
||||||
|
"model": "claude-haiku-4.5",
|
||||||
|
"base_url": "https://api.ppq.ai",
|
||||||
|
"max_tokens": 10000,
|
||||||
|
"temperature": 0.7
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"enabled": true,
|
||||||
|
"port": 8485,
|
||||||
|
"bind_address": "127.0.0.1"
|
||||||
|
},
|
||||||
|
"startup_events": [
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"content_fields": {
|
||||||
|
"name": "Didactyl Test Agent",
|
||||||
|
"about": "Automated test instance"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 10002,
|
||||||
|
"content": "",
|
||||||
|
"tags": [
|
||||||
|
["r", "wss://relay.damus.io"],
|
||||||
|
["r", "wss://relay.primal.net"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 31124,
|
||||||
|
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
|
||||||
|
"tags": [
|
||||||
|
["d", "identity_and_rules"],
|
||||||
|
["app", "didactyl"],
|
||||||
|
["scope", "private"],
|
||||||
|
["trigger", "dm"],
|
||||||
|
["filter", "{\"from\":\"admin\"}"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
395
tests/results/20260404T140236Z/agent_debug.log
Normal file
395
tests/results/20260404T140236Z/agent_debug.log
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
[2026-04-04 10:04:51] [INFO ] [main.c:1016] Didactyl v0.2.20 starting
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2207] [didactyl] initializing relay pool with 2 relays
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:51] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:51] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1775311491", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1775311491", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1775311491"]
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [01] Relay connectivity: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:255] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1775311492", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1775311492", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=702>
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [03] Validate LLM config: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [03] Validate LLM config: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [04] Validate admin config: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [04] Validate admin config: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [05] Initialize LLM client: begin
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:258] [didactyl] startup checklist [05] Initialize LLM client: ok
|
||||||
|
[2026-04-04 10:04:52] [INFO ] [main.c:248] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1775311492", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1775311492", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:52] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1775311492"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1245] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:255] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=621>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=623>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3297] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=800>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=802>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=714>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=716>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1267] [didactyl] startup phase: persisted encrypted runtime config to Nostr
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [08] Initialize agent: begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1775311493", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1775311493", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","7fb5e7e09092254b700df2e7a8473fdca42ee09e3a32b86d262ad2403807f920",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","7fb5e7e09092254b700df2e7a8473fdca42ee09e3a32b86d262ad2403807f920",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","98b892b33ce3731cbeb82d791f5e41c7deade4bb61756ed600a14f3aeaa7d45e",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","98b892b33ce3731cbeb82d791f5e41c7deade4bb61756ed600a14f3aeaa7d45e",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=656>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [08] Initialize agent: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [09] Initialize trigger manager: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:814] [didactyl] trigger manager initialized (capacity=16)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [09] Initialize trigger manager: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1308] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [10] Load startup triggers: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1311] [didactyl] startup phase: startup-config trigger load begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1138] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1021] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1029] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1315] [didactyl] startup phase: startup-config trigger load end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [10] Load startup triggers: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:327] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:334] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":6,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":6,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493}]}
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1775311493", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1775311493", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","e94ea27dc06a8f4f1e70e7e96d1d3e7f328016ff1bbbc3a50723268f14277fb1",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","cfe5aafd9e84b8a7c6caf1842ce51a502a156b5706ecddadaee73b106796bc6c",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","cfe5aafd9e84b8a7c6caf1842ce51a502a156b5706ecddadaee73b106796bc6c",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","e94ea27dc06a8f4f1e70e7e96d1d3e7f328016ff1bbbc3a50723268f14277fb1",true,""]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:354] [didactyl] kind10002 query received event_count=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:451] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:556] [didactyl] kind10002 wait success: relay_count=2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:558] [didactyl] kind10002 relay[0]=wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:558] [didactyl] kind10002 relay[1]=wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:562] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":0,"events_published":6,"events_published_ok":5,"events_published_failed":1,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":6,"events_published_ok":6,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775311491,"last_event_time":1775311493}]}
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:255] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [12] Subscribe admin context: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1366] [didactyl] startup phase: subscribe admin context begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2352] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1370] [didactyl] startup phase: subscribe admin context end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [12] Subscribe admin context: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [13] Subscribe agent self context: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1374] [didactyl] startup phase: subscribe agent self context begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1775311493", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1775311493", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2440] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1378] [didactyl] startup phase: subscribe agent self context end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [13] Subscribe agent self context: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1382] [didactyl] startup phase: subscribe self skill cache begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1775311493", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1775311493", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1775311493", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1775311493", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2532] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:1725] [didactyl] self-skill EOSE received: cached skill events=0
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:44] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [trigger_manager.c:918] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=1)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:54] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=b3095dd390e3a08ff24404195292ed302711334687a7de5ca0b433d9fe66a92e created_at=1775311493
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=10123 d_tag=- id=952130858723506c1eac58e94f253c8b35e137c056dcedf0619ab63348f43caa created_at=1775311493
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1449] [didactyl] startup phase: subscribe self skill cache end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:255] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=1 adoptions=1)
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [15] Subscribe DMs: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1453] [didactyl] startup phase: subscribe DMs begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1775311493", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1775311493", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2643] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:2644] [didactyl] DEBUG DM subscription g_start_time=1775311491 now=1775311493 delta=2 relay_count=2
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1468] [didactyl] startup phase: subscribe DMs end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [15] Subscribe DMs: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [16] Subscribe wallet events: begin
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1472] [didactyl] startup phase: subscribe wallet events begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1775311493", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1775311493", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775311491,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [nostr_handler.c:2696] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:1476] [didactyl] startup phase: subscribe wallet events end
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:258] [didactyl] startup checklist [16] Subscribe wallet events: ok
|
||||||
|
[2026-04-04 10:04:53] [INFO ] [main.c:248] [didactyl] startup checklist [17] Initialize cashu wallet: begin
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1775311493", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1775311493", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1775311493"]
|
||||||
|
[2026-04-04 10:04:53] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1775311493"]
|
||||||
|
[2026-04-04 10:04:54] [WARN ] [main.c:1492] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:255] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [http_api.c:1570] [didactyl] http api listening on http://127.0.0.1:8485
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1532] [didactyl] HTTP API listening at http://127.0.0.1:8485
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1535] [didactyl] HTTP API endpoints: http://127.0.0.1:8485/api/context/current http://127.0.0.1:8485/api/context/parts
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1499] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-04 10:04:54 (version v0.2.20, connected relays: 2/2).
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:1491] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1775311494,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"jW17RpM/0GksuCPaI3kIdas95grzicaXf5xODF31xSY896PZQuQWRa9VFX3+TPRQuDmv2xLbRw32sox/BAhXasZZe2RFLKPjsHyFoeNBbQB4tRn9fGum/0djr/WL8nK+ppT64wLUPut/2vRFnM+sqv1pZ/nRQe/FFxy8K/VE1eM=?iv=g0c6X4mBxWM04miChtqXTA==","id":"73a9a8e4e3688d46cefb02643ead141fdb7397c632fdd9e6f336c0d31d9ad59c","sig":"08c739b14c9c8482b47dda28f82903eb60ef7fdfd6290b0804f8e4b1c5c7da59b9c82294773bc7394d0adba6474dac7530d36868e65c66f66b9c6e6bda1b6057"}
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:906] [didactyl] publish DM target relays (2):
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.damus.io (async)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.primal.net (async)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [nostr_handler.c:2852] [didactyl] sent DM 73a9a8e4e3688d46... to 254d7a7f68b4443f... via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:255] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1571] [didactyl] entering main poll loop
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [main.c:1572] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","73a9a8e4e3688d46cefb02643ead141fdb7397c632fdd9e6f336c0d31d9ad59c",true,""]
|
||||||
|
[2026-04-04 10:04:54] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","73a9a8e4e3688d46cefb02643ead141fdb7397c632fdd9e6f336c0d31d9ad59c",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:04:54] [INFO ] [llm.c:76] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=27553 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Look up your own Nostr profile"},{"role":"user","content":"Look up your own Nostr profile","_ts":1775311494}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr_react","description":"React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)","parameters":{"type":"object","properties":{"event_id":{"type":"string","description":"Target event ID to react to"},"event_pubkey":{"type":"string","description":"Author pubkey of target event"},"event_kind":{"type":"integer","description":"Optional kind of target event"},"reaction":{"type":"string","description":"Reaction content such as +, -, ❤️, or emoji"}},"required":["event_id","event_pubkey"]}}},{"type":"function","function":{"name":"nostr_profile_get","description":"Look up a Nostr profile (kind 0 metadata) by pubkey","parameters":{"type":"object","properties":{"pubkey":{"type":"string","description":"Hex pubkey of the profile to fetch"}},"require...
|
||||||
|
[2026-04-04 10:04:58] [INFO ] [llm.c:76] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=28078 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Look up your own Nostr profile"},{"role":"user","content":"Look up your own Nostr profile","_ts":1775311494},{"role":"assistant","content":"I'll look up my own Nostr profile by first getting my pubkey and then fetching the profile metadata.","tool_calls":[{"id":"toolu_bdrk_0163qj8DFnDXcpoJdjkF4jYj","type":"function","function":{"name":"nostr_pubkey","arguments":"{}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_0163qj8DFnDXcpoJdjkF4jYj","content":"{\"success\":true,\"pubkey\":\"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\",\"content\":\"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\"}"}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr_react","description":"React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)","parameters":{"type":"object","properties":{"event_id":{"type":"string","description":"Target event ID to react to"},"event_pubkey":{"type":"s...
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_16_1775311511", {
|
||||||
|
"kinds": [0],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_16_1775311511", {
|
||||||
|
"kinds": [0],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=472>
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=470>
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_16_1775311511"]
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_16_1775311511"]
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_16_1775311511"]
|
||||||
|
[2026-04-04 10:05:11] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_16_1775311511"]
|
||||||
|
[2026-04-04 10:05:11] [INFO ] [llm.c:76] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=29027 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."},{"role":"user","content":"Look up your own Nostr profile"},{"role":"user","content":"Look up your own Nostr profile","_ts":1775311494},{"role":"assistant","content":"I'll look up my own Nostr profile by first getting my pubkey and then fetching the profile metadata.","tool_calls":[{"id":"toolu_bdrk_0163qj8DFnDXcpoJdjkF4jYj","type":"function","function":{"name":"nostr_pubkey","arguments":"{}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_0163qj8DFnDXcpoJdjkF4jYj","content":"{\"success\":true,\"pubkey\":\"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\",\"content\":\"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\"}"},{"role":"assistant","content":"Now let me fetch my profile metadata:","tool_calls":[{"id":"toolu_bdrk_01SvmURpNtVuQN363Gvcgsrc","type":"function","function":{"name":"nostr_profile_get","arguments":"{\"pubkey\": \"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\"}"}}]},{"role":"tool","tool_call_id":"toolu_bdrk_01SvmURpNtVuQN363Gvcgsrc","content":"{\"success\":true,\"found\":true,\"event\":{\"content\":\"{\\\"name\\\":\\\"Didactyl Test Agent\\\",\\\"about\\\":\\\"Automated test instance\\\"}\",\"created_at\":1775311493,\"id\":\"98b892b33ce3731cbeb82d791f5e41c7deade4bb61756ed600a14f3aeaa7d45e\",\"kind\":0,\"pubkey\":\"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc\",\"sig\":\"b9d083081f36b1be3c60066af6680050fbbdc42d766277f534fd096f81279e5b70f1083a309a3b96e7065bd3c89c4682cf89cc17968d29b59ac6e062c13109bd\",\"tags\":[]},\"profile\":{\"name\":\"Didactyl Test Agent\",\"about\":\"Automated test instance\"}}"}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nost...
|
||||||
|
[2026-04-04 10:05:16] [INFO ] [llm.c:336] [didactyl] llm request sanitizer: removed 2 empty text message(s) before provider request
|
||||||
|
[2026-04-04 10:05:16] [INFO ] [llm.c:76] [didactyl] llm request: method=POST url=https://api.ppq.ai/chat/completions body_bytes=27418 body_preview={"model":"claude-haiku-4.5","max_tokens":10000,"temperature":0.7,"messages":[{"role":"system","content":"# Didactyl Agent\n\n## Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed."}],"tools":[{"type":"function","function":{"name":"nostr_post","description":"Publish a Nostr event to connected relays","parameters":{"type":"object","properties":{"kind":{"type":"integer","description":"Nostr event kind number (for example 1 for note, 7 for reaction, 30023 for longform)"},"content":{"type":"string","description":"Event content/body text to publish"},"tags":{"type":"array","description":"Optional Nostr tags array, e.g. [[\"d\",\"my-skill\"],[\"t\",\"nostr\"]]","items":{"type":"array","items":{"type":"string"}}}},"required":["kind","content"]}}},{"type":"function","function":{"name":"nostr_query","description":"Query events from relays using a Nostr filter","parameters":{"type":"object","properties":{"filter":{"type":"object","description":"Nostr filter object (authors, kinds, ids, since, until, limit, and tag filters)"},"timeout_ms":{"type":"integer","description":"Optional query timeout in milliseconds"}},"required":["filter"]}}},{"type":"function","function":{"name":"local_shell_exec","description":"Execute a shell command and return stdout/stderr","parameters":{"type":"object","properties":{"command":{"type":"string","description":"Shell command to execute in the configured working directory"}},"required":["command"]}}},{"type":"function","function":{"name":"local_file_read","description":"Read a local file as text from the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to read (relative to configured working directory)"},"max_bytes":{"type":"integer","description":"Optional maximum bytes to return"}},"required":["path"]}}},{"type":"function","function":{"name":"local_file_write","description":"Write text content to a local file in the configured working directory","parameters":{"type":"object","properties":{"path":{"type":"string","description":"Path to file to write (relative to configured working directory)"},"content":{"type":"string","description":"Text content to write"},"append":{"type":"boolean","description":"When true, append to file instead of overwriting"}},"required":["path","content"]}}},{"type":"function","function":{"name":"nostr_post_readme","description":"Publish README.md as kind 30023 with deterministic d tag readme.md","parameters":{"type":"object","properties":{},"required":[]}}},{"type":"function","function":{"name":"nostr_delete","description":"Request deletion of one or more previously published events (NIP-09 kind 5)","parameters":{"type":"object","properties":{"event_ids":{"type":"array","description":"Event IDs to request deletion for","items":{"type":"string"}},"kinds":{"type":"array","description":"Optional kinds corresponding to event_ids entries","items":{"type":"integer"}},"reason":{"type":"string","description":"Optional human-readable reason"}},"required":["event_ids"]}}},{"type":"function","function":{"name":"nostr_react","description":"React to a Nostr event with like/dislike/emoji (NIP-25 kind 7)","parameters":{"type":"object","properties":{"event_id":{"type":"string","description":"Target event ID to react to"},"event_pubkey":{"type":"string","description":"Author pubkey of target event"},"event_kind":{"type":"integer","description":"Optional kind of target event"},"reaction":{"type":"string","description":"Reaction content such as +, -, ❤️, or emoji"}},"required":["event_id","event_pubkey"]}}},{"type":"function","function":{"name":"nostr_profile_get","description":"Look up a Nostr profile (kind 0 metadata) by pubkey","parameters":{"type":"object","properties":{"pubkey":{"type":"string","description":"Hex pubkey of the profile to fetch"}},"required":["pubkey"]}}},{"type":"function","function":{"name":"nostr_relay_status","description":"Get connection status and statistics for all...
|
||||||
53
tests/results/20260404T140236Z/runtime_test_genesis.jsonc
Normal file
53
tests/results/20260404T140236Z/runtime_test_genesis.jsonc
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
// TEST CONFIGURATION
|
||||||
|
// Use disposable keys/accounts only.
|
||||||
|
"key": {
|
||||||
|
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
|
||||||
|
},
|
||||||
|
"dm_protocol": "nip04",
|
||||||
|
"llm": {
|
||||||
|
"provider": "https://api.ppq.ai",
|
||||||
|
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
|
||||||
|
"model": "claude-haiku-4.5",
|
||||||
|
"base_url": "https://api.ppq.ai",
|
||||||
|
"max_tokens": 10000,
|
||||||
|
"temperature": 0.7
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"enabled": true,
|
||||||
|
"port": 8485,
|
||||||
|
"bind_address": "127.0.0.1"
|
||||||
|
},
|
||||||
|
"startup_events": [
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"content_fields": {
|
||||||
|
"name": "Didactyl Test Agent",
|
||||||
|
"about": "Automated test instance"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 10002,
|
||||||
|
"content": "",
|
||||||
|
"tags": [
|
||||||
|
["r", "wss://relay.damus.io"],
|
||||||
|
["r", "wss://relay.primal.net"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 31124,
|
||||||
|
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
|
||||||
|
"tags": [
|
||||||
|
["d", "identity_and_rules"],
|
||||||
|
["app", "didactyl"],
|
||||||
|
["scope", "private"],
|
||||||
|
["trigger", "dm"],
|
||||||
|
["filter", "{\"from\":\"admin\"}"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
396
tests/results/20260404T140545Z/agent_debug.log
Normal file
396
tests/results/20260404T140545Z/agent_debug.log
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
[2026-04-04 10:29:17] [INFO ] [main.c:1016] Didactyl v0.2.20 starting
|
||||||
|
[2026-04-04 10:29:17] [INFO ] [nostr_handler.c:2207] [didactyl] initializing relay pool with 2 relays
|
||||||
|
[2026-04-04 10:29:17] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:17] [INFO ] [nostr_handler.c:2231] [didactyl] added relay: wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_1_1775312957", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_1_1775312957", {
|
||||||
|
"kinds": [10000],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_1_1775312957"]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_1_1775312957"]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_1_1775312957"]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_1_1775312957"]
|
||||||
|
[2026-04-04 10:29:18] [INFO ] [main.c:248] [didactyl] startup checklist [01] Relay connectivity: begin
|
||||||
|
[2026-04-04 10:29:18] [INFO ] [main.c:255] [didactyl] startup checklist [01] Relay connectivity: ok (connected relays: 2/2)
|
||||||
|
[2026-04-04 10:29:18] [INFO ] [main.c:248] [didactyl] startup checklist [02] Recover runtime config from Nostr: begin
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_2_1775312958", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:18] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_2_1775312958", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["agent_config"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=702>
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_2_1775312958"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=700>
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_2_1775312958"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_2_1775312958"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_2_1775312958"]
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:258] [didactyl] startup checklist [02] Recover runtime config from Nostr: ok
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:248] [didactyl] startup checklist [03] Validate LLM config: begin
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:258] [didactyl] startup checklist [03] Validate LLM config: ok
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:248] [didactyl] startup checklist [04] Validate admin config: begin
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:258] [didactyl] startup checklist [04] Validate admin config: ok
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:248] [didactyl] startup checklist [05] Initialize LLM client: begin
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:258] [didactyl] startup checklist [05] Initialize LLM client: ok
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:248] [didactyl] startup checklist [06] Detect first run via kind 10002: begin
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_3_1775312959", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_3_1775312959", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_3_1775312959"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_3_1775312959"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_3_1775312959"]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_3_1775312959"]
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:1245] [didactyl] startup phase: first-run detection via kind 10002 => subsequent-run
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:255] [didactyl] startup checklist [06] Detect first run via kind 10002: ok (subsequent-run)
|
||||||
|
[2026-04-04 10:29:19] [INFO ] [main.c:248] [didactyl] startup checklist [07] Reconcile/persist startup state: begin
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_4_1775312959", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:19] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_4_1775312959", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_4_1775312959"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_4_1775312959"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_4_1775312959"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_4_1775312959"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=480>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=474>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=621>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=553>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.damus.io (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=482>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 0 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=476>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10002 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=623>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 31124 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=555>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 10123 event published to wss://relay.primal.net (async, reason=startup_reconcile)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=0 (profile) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10002 (relay_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=31124 (skill) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3285] [didactyl] startup publish detail: kind=10123 (adoption_list) -> wss://relay.damus.io, wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3297] [didactyl] startup publish summary: 4/4 event(s) published to at least one relay; relays used=2/2
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=800>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=802>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:906] [didactyl] publish kind event target relays (2):
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=714>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=716>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.damus.io (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2949] [didactyl] kind 30078 event published to wss://relay.primal.net (async, reason=manual_publish)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:3012] [didactyl] published kind 30078 event via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1267] [didactyl] startup phase: persisted encrypted runtime config to Nostr
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [07] Reconcile/persist startup state: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [08] Initialize agent: begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_5_1775312960", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_5_1775312960", {
|
||||||
|
"kinds": [30078],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"#d": ["memory"],
|
||||||
|
"limit": 1
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","11bc4eb1ff5e51d8df325c1f16eab167535bd04f4768129437098aef02917a0c",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","5e774283a8db088821e3c20d7f5ec2dbc64e9ca32d5342ce31f699205e16b22c",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","5e774283a8db088821e3c20d7f5ec2dbc64e9ca32d5342ce31f699205e16b22c",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","e863ae73ffdb98391429ecbb36d4ad931ca994804cd673a310ed91f94806a795",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","9f540b534baeaa37d5bdfd1b3ef6ef1f9b65b8f00236ad28d63e098b56e56c35",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","11bc4eb1ff5e51d8df325c1f16eab167535bd04f4768129437098aef02917a0c",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","e863ae73ffdb98391429ecbb36d4ad931ca994804cd673a310ed91f94806a795",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","9f540b534baeaa37d5bdfd1b3ef6ef1f9b65b8f00236ad28d63e098b56e56c35",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=952>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_5_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_5_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_5_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_5_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [08] Initialize agent: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [09] Initialize trigger manager: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:814] [didactyl] trigger manager initialized (capacity=16)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [09] Initialize trigger manager: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1308] [didactyl] startup phase: deferred trigger load will run after self-skill EOSE
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [10] Load startup triggers: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1311] [didactyl] startup phase: startup-config trigger load begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1138] [didactyl] trigger added d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1021] [didactyl] startup trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1029] [didactyl] trigger manager loaded 1 trigger(s) from startup config (considered=1)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1315] [didactyl] startup phase: startup-config trigger load end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [10] Load startup triggers: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [11] Discover self relay list via kind 10002: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:327] [didactyl] kind10002 query begin: timeout_ms=5000 author=1eb171136dbb1ba6... relay_count=2
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:334] [didactyl] kind10002 query relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":6,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775312957,"last_event_time":1775312960},{"url":"wss://relay.primal.net","status":"connected","events_received":3,"events_published":6,"events_published_ok":4,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775312957,"last_event_time":1775312960}]}
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_6_1775312960", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_6_1775312960", {
|
||||||
|
"kinds": [10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 16
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","86a6101b5cd0fc5e04cd22ad7c897cecd8b4a6a827180b1a18d1da10c31ce9bf",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","59d0b381dcf93eb42a65bc1bbc31e54b82ac20bb3b2dd654b08d3780da41ee07",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","59d0b381dcf93eb42a65bc1bbc31e54b82ac20bb3b2dd654b08d3780da41ee07",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","86a6101b5cd0fc5e04cd22ad7c897cecd8b4a6a827180b1a18d1da10c31ce9bf",true,""]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_6_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_6_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_6_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_6_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:354] [didactyl] kind10002 query received event_count=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:451] [didactyl] kind10002 query extracted relays=["wss://relay.damus.io","wss://relay.primal.net"]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:556] [didactyl] kind10002 wait success: relay_count=2
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:558] [didactyl] kind10002 relay[0]=wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:558] [didactyl] kind10002 relay[1]=wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:562] [didactyl] kind10002 wait success relay snapshot: {"relay_count":2,"connected_count":2,"relays":[{"url":"wss://relay.damus.io","status":"connected","events_received":1,"events_published":6,"events_published_ok":5,"events_published_failed":1,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775312957,"last_event_time":1775312960,"last_publish_error":"rate-limited: you are noting too much"},{"url":"wss://relay.primal.net","status":"connected","events_received":4,"events_published":6,"events_published_ok":6,"events_published_failed":0,"ping_latency_current":0,"ping_latency_avg":0,"query_latency_avg":0,"publish_latency_avg":0,"connection_uptime_start":1775312957,"last_event_time":1775312960}]}
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:255] [didactyl] startup checklist [11] Discover self relay list via kind 10002: ok (kind10002=2 added=0 connected=2/2)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [12] Subscribe admin context: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1366] [didactyl] startup phase: subscribe admin context begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_7_1775312960", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_7_1775312960", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 32
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_8_1775312960", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_8_1775312960", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2352] [didactyl] admin context subscriptions active for admin 254d7a7f68b4443f...
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1370] [didactyl] startup phase: subscribe admin context end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [12] Subscribe admin context: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [13] Subscribe agent self context: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1374] [didactyl] startup phase: subscribe agent self context begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_9_1775312960", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_9_1775312960", {
|
||||||
|
"kinds": [0, 3, 10002],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 64
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_10_1775312960", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_10_1775312960", {
|
||||||
|
"kinds": [1],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 10
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2440] [didactyl] agent self-context subscriptions active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1378] [didactyl] startup phase: subscribe agent self context end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [13] Subscribe agent self context: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [14] Subscribe self-skill cache: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1382] [didactyl] startup phase: subscribe self skill cache begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_11_1775312960", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_11_1775312960", {
|
||||||
|
"kinds": [31123, 31124, 10123],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"limit": 300
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_12_1775312960", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_12_1775312960", {
|
||||||
|
"kinds": [31123],
|
||||||
|
"authors": ["254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"],
|
||||||
|
"limit": 150
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2532] [didactyl] self/admin skill subscriptions active (self=1eb171136dbb1ba6..., admin=254d7a7f68b4443f...)
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_7_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_7_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_8_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_8_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=462>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=460>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=471>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=469>
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_9_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_9_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_10_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_10_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=604>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=9f540b534baeaa37d5bdfd1b3ef6ef1f9b65b8f00236ad28d63e098b56e56c35 created_at=1775312960 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=602>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31124 d_tag=identity_and_rules id=9f540b534baeaa37d5bdfd1b3ef6ef1f9b65b8f00236ad28d63e098b56e56c35 created_at=1775312960 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:1207] [didactyl] live self-skill trigger registered d_tag=identity_and_rules action=llm enabled=1
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=540>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=11bc4eb1ff5e51d8df325c1f16eab167535bd04f4768129437098aef02917a0c created_at=1775312960 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=538>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=10123 d_tag=- id=11bc4eb1ff5e51d8df325c1f16eab167535bd04f4768129437098aef02917a0c created_at=1775312960 via wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] RECV <large EVENT frame suppressed, bytes=478>
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2151] [didactyl] self-skill cache received kind=31123 d_tag=test-harness-probe id=fbf278b5a6ccd7fd86b0c8c7bfb787aa3f94c578e0bda74241e1d8e613394467 created_at=1775312616 via wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_11_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_11_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:1725] [didactyl] self-skill EOSE received: cached skill events=0
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:44] [didactyl] deferred trigger load begin after self-skill EOSE (event_count=0)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:1364] [didactyl] trigger updated d_tag=identity_and_rules action=0 enabled=1
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [trigger_manager.c:918] [didactyl] trigger manager loaded 1 trigger(s) from self skills (considered=2)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:54] [didactyl] deferred trigger load status: {"success":true,"count":1,"active":1,"triggers":[{"skill_d_tag":"identity_and_rules","filter_json":"{\"from\":\"admin\"}","type":"dm","action":"llm","enabled":true,"subscribed":false,"llm":"","tools":"","has_max_tokens":false,"has_temperature":false,"has_seed":false,"last_fired":0,"last_seen_created_at":0}]}
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=31124 d_tag=identity_and_rules id=9f540b534baeaa37d5bdfd1b3ef6ef1f9b65b8f00236ad28d63e098b56e56c35 created_at=1775312960
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=10123 d_tag=- id=11bc4eb1ff5e51d8df325c1f16eab167535bd04f4768129437098aef02917a0c created_at=1775312960
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2757] [didactyl] self-skill cache event: kind=31123 d_tag=test-harness-probe id=fbf278b5a6ccd7fd86b0c8c7bfb787aa3f94c578e0bda74241e1d8e613394467 created_at=1775312616
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1449] [didactyl] startup phase: subscribe self skill cache end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:255] [didactyl] startup checklist [14] Subscribe self-skill cache: ok (skills=2 adoptions=1)
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [15] Subscribe DMs: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1453] [didactyl] startup phase: subscribe DMs begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_13_1775312960", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775312957,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_13_1775312960", {
|
||||||
|
"kinds": [4],
|
||||||
|
"#p": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775312957,
|
||||||
|
"limit": 100
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2643] [didactyl] DM subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:2644] [didactyl] DEBUG DM subscription g_start_time=1775312957 now=1775312960 delta=3 relay_count=2
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1468] [didactyl] startup phase: subscribe DMs end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [15] Subscribe DMs: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [16] Subscribe wallet events: begin
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1472] [didactyl] startup phase: subscribe wallet events begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_14_1775312960", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775312957,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_14_1775312960", {
|
||||||
|
"kinds": [17375, 7375, 5],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"],
|
||||||
|
"since": 1775312957,
|
||||||
|
"limit": 500
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [nostr_handler.c:2696] [didactyl] wallet event subscription active for pubkey 1eb171136dbb1ba6...
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:1476] [didactyl] startup phase: subscribe wallet events end
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:258] [didactyl] startup checklist [16] Subscribe wallet events: ok
|
||||||
|
[2026-04-04 10:29:20] [INFO ] [main.c:248] [didactyl] startup checklist [17] Initialize cashu wallet: begin
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["REQ", "pool_15_1775312960", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["REQ", "pool_15_1775312960", {
|
||||||
|
"kinds": [17375, 7375],
|
||||||
|
"authors": ["1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"]
|
||||||
|
}]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_12_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_12_1775312960"]
|
||||||
|
[2026-04-04 10:29:20] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_13_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_13_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:1718] [didactyl] DEBUG on_eose called: event_count=0
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_14_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_14_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["EOSE","pool_15_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["EOSE","pool_15_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_15_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_15_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [WARN ] [main.c:1492] [didactyl] startup phase: cashu wallet load/create deferred to first tool call
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:255] [didactyl] startup checklist [17] Initialize cashu wallet: ok (initialized; load/create deferred)
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [http_api.c:1570] [didactyl] http api listening on http://127.0.0.1:8485
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:1532] [didactyl] HTTP API listening at http://127.0.0.1:8485
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:1535] [didactyl] HTTP API endpoints: http://127.0.0.1:8485/api/context/current http://127.0.0.1:8485/api/context/parts
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:1499] [didactyl] sending plaintext DM content: Didactyl Test Agent has started up and is online at 2026-04-04 10:29:21 (version v0.2.20, connected relays: 2/2).
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:1491] [didactyl] sending encrypted DM event: {"pubkey":"1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc","created_at":1775312961,"kind":4,"tags":[["p","254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"]],"content":"TOAe6VwLkGJemoQ1F6TB3lfiGq251GlJjayadl04UGMhnkm/A/PKzaqzzqO5q0Xpn9LM83KjU575uHL+PSEaM76IfvFcMVN8Qa1C3hSF9/7vpn1LuIGBIpQn8fmDpHji+gjRVZk1wvWUPoC63CCTWH/cUgJkILYQaW4XMdJwA1E=?iv=cuZPWOh+jAIjqTR/U47BIg==","id":"d79dcbff5a6b5f37100d1a04e115c64231c28476fa0e21454cdaa30fc5010622","sig":"e356e8244b8930268aab91124db3d3632952b091a6880de13e2a9b1122f538f5fec3b5bffaae2615bcbcb42a3663b85d6f1f66f9f264967c4c5b44009ada977a"}
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:906] [didactyl] publish DM target relays (2):
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.damus.io
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:908] [didactyl] -> wss://relay.primal.net
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=681>
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:162] [didactyl] [nostr:websocket] SEND <large EVENT frame suppressed, bytes=683>
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.damus.io (async)
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:2843] [didactyl] kind 4 event published to wss://relay.primal.net (async)
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [nostr_handler.c:2852] [didactyl] sent DM d79dcbff5a6b5f37... to 254d7a7f68b4443f... via 2 connected relay(s)
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:255] [didactyl] startup checklist [18] READY: ok (agent online; entering main poll loop)
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:1571] [didactyl] entering main poll loop
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:1572] [didactyl] running with pubkey 1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.primal.net:443: ["OK","d79dcbff5a6b5f37100d1a04e115c64231c28476fa0e21454cdaa30fc5010622",true,""]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] RECV relay.damus.io:443: ["OK","d79dcbff5a6b5f37100d1a04e115c64231c28476fa0e21454cdaa30fc5010622",false,"rate-limited: you are noting too much"]
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [main.c:1584] [didactyl] shutting down
|
||||||
|
[2026-04-04 10:29:21] [INFO ] [trigger_manager.c:1602] [didactyl] trigger manager cleaned up
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_7_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_7_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_8_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_8_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_9_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_9_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_10_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_10_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_11_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_11_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_12_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_12_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_13_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_13_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.damus.io:443: ["CLOSE", "pool_14_1775312960"]
|
||||||
|
[2026-04-04 10:29:21] [TRACE] [nostr_handler.c:169] [didactyl] [nostr:websocket] SEND relay.primal.net:443: ["CLOSE", "pool_14_1775312960"]
|
||||||
494
tests/results/20260404T140545Z/results.json
Normal file
494
tests/results/20260404T140545Z/results.json
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
{
|
||||||
|
"run_meta": {
|
||||||
|
"run_timestamp": "2026-04-04T14:29:21.419470+00:00",
|
||||||
|
"base_url": "http://127.0.0.1:8485",
|
||||||
|
"config": "tests/results/20260404T140545Z/runtime_test_genesis.jsonc",
|
||||||
|
"binary": "didactyl_static_x86_64_debug",
|
||||||
|
"test_count": 43
|
||||||
|
},
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"suite": "test_conversation",
|
||||||
|
"name": "simple_greeting",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "greeting response ok",
|
||||||
|
"duration_seconds": 4.245289196027443,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"response": "Hello! I'm a test agent built on the Didactyl platform. I don't have a specific personal name, but you can think of me as your Didactyl test agent. \n\nI'm here to help you with various tasks using the "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_conversation",
|
||||||
|
"name": "agent_responds_about_itself",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "self description ok",
|
||||||
|
"duration_seconds": 27.058145482034888,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"response": "i'm **didactyl**, a nostr-native ai agent. here's what i do:\n\n**core identity:**\n- i'm an autonomous agent built on the nostr protocol, operating with cryptographic keypairs for identity and authentic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_conversation",
|
||||||
|
"name": "empty_message_handling",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "empty message handled",
|
||||||
|
"duration_seconds": 4.667415744974278,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_conversation",
|
||||||
|
"name": "very_long_message",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 76.51407337700948,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_errors",
|
||||||
|
"name": "invalid_json_body",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "invalid json rejected",
|
||||||
|
"duration_seconds": 0.3308889329782687,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"status": 400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_errors",
|
||||||
|
"name": "missing_message_field",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "missing message rejected",
|
||||||
|
"duration_seconds": 0.3314382230164483,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"status": 400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_errors",
|
||||||
|
"name": "unknown_endpoint",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "unknown endpoint 404",
|
||||||
|
"duration_seconds": 0.33126351796090603,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_errors",
|
||||||
|
"name": "webhook_nonexistent_dtag",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "nonexistent d_tag 404",
|
||||||
|
"duration_seconds": 0.33133913297206163,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_health",
|
||||||
|
"name": "status_returns_200",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "status success",
|
||||||
|
"duration_seconds": 0.3312724310089834,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"keys": [
|
||||||
|
"success",
|
||||||
|
"name",
|
||||||
|
"version",
|
||||||
|
"pubkey",
|
||||||
|
"relay_count",
|
||||||
|
"connected_relays",
|
||||||
|
"active_triggers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_health",
|
||||||
|
"name": "status_has_fields",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "required fields present",
|
||||||
|
"duration_seconds": 0.3312905229977332,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_health",
|
||||||
|
"name": "context_current_returns_messages",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "context current ok",
|
||||||
|
"duration_seconds": 0.33117285498883575,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"message_count": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_health",
|
||||||
|
"name": "context_parts_has_system_prompt",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "context parts ok",
|
||||||
|
"duration_seconds": 0.3312868010252714,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"parts": [
|
||||||
|
"system_prompt",
|
||||||
|
"dm_history"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_restart",
|
||||||
|
"name": "clean_restart",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "restart succeeded",
|
||||||
|
"duration_seconds": 3.8490588110289536,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_restart",
|
||||||
|
"name": "status_after_restart",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "status stable after restart",
|
||||||
|
"duration_seconds": 4.151956218993291,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"pubkey": "1eb171136dbb1ba695b2f14296adfe88a1f81d4220cc7d186b0e139b8ce0cdbc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_restart",
|
||||||
|
"name": "conversation_after_restart",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "conversation works post-restart",
|
||||||
|
"duration_seconds": 7.446270982036367,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_timeouts",
|
||||||
|
"name": "response_within_timeout",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "response within timeout",
|
||||||
|
"duration_seconds": 3.016901847033296,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"elapsed": 3.0168789690360427
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_timeouts",
|
||||||
|
"name": "status_responds_fast",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "status fast",
|
||||||
|
"duration_seconds": 0.32919533003587276,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"elapsed": 0.3291910729603842
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_timeouts",
|
||||||
|
"name": "context_responds_fast",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "context fast",
|
||||||
|
"duration_seconds": 0.33155528403585777,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"elapsed": 0.3315501930192113
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_blossom",
|
||||||
|
"name": "blossom_list",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.46405867597787,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_cashu",
|
||||||
|
"name": "wallet_balance",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 7.047360337048303,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"cashu_wallet_balance"
|
||||||
|
],
|
||||||
|
"final_response": "Your Cashu wallet balance is:\n\n- **Total**: 0 satoshis\n- **Wallet Status**: Not loaded\n- **Entries**: None\n\nThe wallet doesn't currently have any loaded mints or proofs. To start using the wallet, you"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_identity",
|
||||||
|
"name": "get_pubkey",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.42999882198637,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_identity",
|
||||||
|
"name": "get_npub",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 6.77238113101339,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"nostr_npub"
|
||||||
|
],
|
||||||
|
"final_response": "My npub is: **npub1r6chzymdhvd6d9dj79pfdt073zsls82zyrx86xrtpcfehr8qek7q3rkewf**"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_identity",
|
||||||
|
"name": "agent_identity",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.39259405602934,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_identity",
|
||||||
|
"name": "agent_version",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 6.746906190994196,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"agent_version"
|
||||||
|
],
|
||||||
|
"final_response": "I'm **Didactyl v0.2.20**, a sovereign AI agent daemon on Nostr. \n\nHere are my details:\n- **Name**: Didactyl\n- **Description**: A sovereign AI agent daemon on Nostr\n- **Version**: v0.2.20 (major: 0, mi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_identity",
|
||||||
|
"name": "admin_identity",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 74.42458030197304,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_memory",
|
||||||
|
"name": "task_list",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 8.36226256104419,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"task_list"
|
||||||
|
],
|
||||||
|
"final_response": "Here's your current task list:\n\n**Active Tasks:**\n- [ ] **Task 1:** test harness probe (Status: pending)\n - Created: 1775311162\n - Last updated: 1775311162\n\nYou have one pending task in your task me"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_memory",
|
||||||
|
"name": "task_manage_add_remove",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 84.9701488899882,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_memory",
|
||||||
|
"name": "memory_save_recall",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 10.4175310000428,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"memory_save",
|
||||||
|
"memory_recall"
|
||||||
|
],
|
||||||
|
"final_response": "Perfect! The memory system is working correctly. Here's what happened:\n\n**Memory Save Result:**\n- \u2705 Successfully saved to kind 30078 (encrypted agent config)\n- Event ID: `b4aba2eb45a6b41eec9792fa381cf"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_post_kind1",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.96807993302355,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_query_recent",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 14.233945493993815,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"nostr_query"
|
||||||
|
],
|
||||||
|
"final_response": "Great! I found the 3 most recent kind 1 notes. Here they are:\n\n## 3 Most Recent Kind 1 Notes\n\n**1. Relaymonitor Latency Test**\n- **Author:** `0b01aa38c2cc9abfbe4a10d54b182793479fb80da14a91d13be38ea555"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_my_events",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 74.01618752401555,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_relay_status",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 6.104476057982538,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"nostr_relay_status"
|
||||||
|
],
|
||||||
|
"final_response": "Great! Here's the status of my relay connections:\n\n**Overall Status:**\n- **Total Relays:** 2\n- **Connected:** 2/2 \u2705\n\n**Detailed Relay Status:**\n\n1. **wss://relay.damus.io**\n - Status: Connected \u2705\n "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_dm_send",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 74.01507185597438,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_encode_npub",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.42353967600502,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_nostr",
|
||||||
|
"name": "nostr_profile_get",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 74.39149832999101,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_skills",
|
||||||
|
"name": "skill_list",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 7.244145753968041,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"skill_list"
|
||||||
|
],
|
||||||
|
"final_response": "I have **1 available skill** that I'm currently using:\n\n**1. identity_and_rules** (Private - Agent-owned, Adopted)\n - **Scope:** Private\n - **Status:** Adopted and Active\n - **Description:** Thi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_skills",
|
||||||
|
"name": "trigger_list",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.40902369801188,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_skills",
|
||||||
|
"name": "skill_create_and_remove",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.94731772097293,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_system",
|
||||||
|
"name": "tool_list",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 44.292774281988386,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"tool_list"
|
||||||
|
],
|
||||||
|
"final_response": "Great! Here's a comprehensive summary of all **83 available tools** organized by category:\n\n## **Nostr Core Tools**\n1. **nostr_post** - Publish events (notes, reactions, longform)\n2. **nostr_query** -"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_system",
|
||||||
|
"name": "model_get",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.43525368801784,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_system",
|
||||||
|
"name": "model_list",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.39378822001163,
|
||||||
|
"agent_errors": [
|
||||||
|
"[2026-04-04 10:26:46] [ERROR] [llm.c:93] [didactyl] llm http request failed: status=401"
|
||||||
|
],
|
||||||
|
"details": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_system",
|
||||||
|
"name": "local_http_fetch",
|
||||||
|
"status": "pass",
|
||||||
|
"message": "ok",
|
||||||
|
"duration_seconds": 11.767529862001538,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {
|
||||||
|
"tool_calls": [
|
||||||
|
"local_http_fetch"
|
||||||
|
],
|
||||||
|
"final_response": "Perfect! I've successfully fetched https://httpbin.org/get. Here's what was returned:\n\n**Response Details:**\n- **Status Code:** 200 (Success)\n- **Content Type:** application/json\n- **Response Body:**\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suite": "test_tools_system",
|
||||||
|
"name": "config_store_recall",
|
||||||
|
"status": "timeout",
|
||||||
|
"message": "timed out",
|
||||||
|
"duration_seconds": 73.9523419579491,
|
||||||
|
"agent_errors": [],
|
||||||
|
"details": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": {
|
||||||
|
"pass": 27,
|
||||||
|
"timeout": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
140
tests/results/20260404T140545Z/results.txt
Normal file
140
tests/results/20260404T140545Z/results.txt
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
== Didactyl Test Results ==
|
||||||
|
Run: 2026-04-04T14:29:21.419470+00:00
|
||||||
|
Agent base URL: http://127.0.0.1:8485
|
||||||
|
|
||||||
|
Pass: 27
|
||||||
|
Fail: 0
|
||||||
|
Error: 0
|
||||||
|
Timeout: 16
|
||||||
|
Skip: 0
|
||||||
|
Total: 43
|
||||||
|
|
||||||
|
[PASS] test_conversation::simple_greeting (4.25s)
|
||||||
|
greeting response ok
|
||||||
|
|
||||||
|
[PASS] test_conversation::agent_responds_about_itself (27.06s)
|
||||||
|
self description ok
|
||||||
|
|
||||||
|
[PASS] test_conversation::empty_message_handling (4.67s)
|
||||||
|
empty message handled
|
||||||
|
|
||||||
|
[TIMEOUT] test_conversation::very_long_message (76.51s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_errors::invalid_json_body (0.33s)
|
||||||
|
invalid json rejected
|
||||||
|
|
||||||
|
[PASS] test_errors::missing_message_field (0.33s)
|
||||||
|
missing message rejected
|
||||||
|
|
||||||
|
[PASS] test_errors::unknown_endpoint (0.33s)
|
||||||
|
unknown endpoint 404
|
||||||
|
|
||||||
|
[PASS] test_errors::webhook_nonexistent_dtag (0.33s)
|
||||||
|
nonexistent d_tag 404
|
||||||
|
|
||||||
|
[PASS] test_health::status_returns_200 (0.33s)
|
||||||
|
status success
|
||||||
|
|
||||||
|
[PASS] test_health::status_has_fields (0.33s)
|
||||||
|
required fields present
|
||||||
|
|
||||||
|
[PASS] test_health::context_current_returns_messages (0.33s)
|
||||||
|
context current ok
|
||||||
|
|
||||||
|
[PASS] test_health::context_parts_has_system_prompt (0.33s)
|
||||||
|
context parts ok
|
||||||
|
|
||||||
|
[PASS] test_restart::clean_restart (3.85s)
|
||||||
|
restart succeeded
|
||||||
|
|
||||||
|
[PASS] test_restart::status_after_restart (4.15s)
|
||||||
|
status stable after restart
|
||||||
|
|
||||||
|
[PASS] test_restart::conversation_after_restart (7.45s)
|
||||||
|
conversation works post-restart
|
||||||
|
|
||||||
|
[PASS] test_timeouts::response_within_timeout (3.02s)
|
||||||
|
response within timeout
|
||||||
|
|
||||||
|
[PASS] test_timeouts::status_responds_fast (0.33s)
|
||||||
|
status fast
|
||||||
|
|
||||||
|
[PASS] test_timeouts::context_responds_fast (0.33s)
|
||||||
|
context fast
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_blossom::blossom_list (73.46s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_cashu::wallet_balance (7.05s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_identity::get_pubkey (73.43s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_identity::get_npub (6.77s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_identity::agent_identity (73.39s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_identity::agent_version (6.75s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_identity::admin_identity (74.42s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_memory::task_list (8.36s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_memory::task_manage_add_remove (84.97s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_memory::memory_save_recall (10.42s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_nostr::nostr_post_kind1 (73.97s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_nostr::nostr_query_recent (14.23s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_nostr::nostr_my_events (74.02s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_nostr::nostr_relay_status (6.10s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_nostr::nostr_dm_send (74.02s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_nostr::nostr_encode_npub (73.42s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_nostr::nostr_profile_get (74.39s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_skills::skill_list (7.24s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_skills::trigger_list (73.41s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_skills::skill_create_and_remove (73.95s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[PASS] test_tools_system::tool_list (44.29s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_system::model_get (73.44s)
|
||||||
|
timed out
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_system::model_list (73.39s)
|
||||||
|
timed out
|
||||||
|
Agent errors: 1
|
||||||
|
|
||||||
|
[PASS] test_tools_system::local_http_fetch (11.77s)
|
||||||
|
ok
|
||||||
|
|
||||||
|
[TIMEOUT] test_tools_system::config_store_recall (73.95s)
|
||||||
|
timed out
|
||||||
53
tests/results/20260404T140545Z/runtime_test_genesis.jsonc
Normal file
53
tests/results/20260404T140545Z/runtime_test_genesis.jsonc
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
// TEST CONFIGURATION
|
||||||
|
// Use disposable keys/accounts only.
|
||||||
|
"key": {
|
||||||
|
"nsec": "d3011e59954403fb84729ab0e9fb239ba0f0238b3f353dfb5c08a32f4b3d21a1"
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"pubkey": "254d7a7f68b4443f5430564eb3a726f09aea57d27e75ab2b8ef57176f9ca3dac"
|
||||||
|
},
|
||||||
|
"dm_protocol": "nip04",
|
||||||
|
"llm": {
|
||||||
|
"provider": "https://api.ppq.ai",
|
||||||
|
"api_key": "sk-SBI2Pga0J6n8jpPorHbRHC",
|
||||||
|
"model": "claude-haiku-4.5",
|
||||||
|
"base_url": "https://api.ppq.ai",
|
||||||
|
"max_tokens": 10000,
|
||||||
|
"temperature": 0.7
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"enabled": true,
|
||||||
|
"port": 8485,
|
||||||
|
"bind_address": "127.0.0.1"
|
||||||
|
},
|
||||||
|
"startup_events": [
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"content_fields": {
|
||||||
|
"name": "Didactyl Test Agent",
|
||||||
|
"about": "Automated test instance"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 10002,
|
||||||
|
"content": "",
|
||||||
|
"tags": [
|
||||||
|
["r", "wss://relay.damus.io"],
|
||||||
|
["r", "wss://relay.primal.net"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 31124,
|
||||||
|
"content": "# Test Agent\n\nYou are a test agent. Respond to requests and use tools when needed.",
|
||||||
|
"tags": [
|
||||||
|
["d", "identity_and_rules"],
|
||||||
|
["app", "didactyl"],
|
||||||
|
["scope", "private"],
|
||||||
|
["trigger", "dm"],
|
||||||
|
["filter", "{\"from\":\"admin\"}"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user