diff --git a/.daemon/logs/daemon.out.log b/.daemon/logs/daemon.out.log index 931ad0267..345b2ffed 100644 --- a/.daemon/logs/daemon.out.log +++ b/.daemon/logs/daemon.out.log @@ -6643,3 +6643,26 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details. 13:55:11 INFO  [watcher] File changed {"path":"/home/nicholai/.agents/memory/memories.db-wal"} 13:55:12 INFO  [memory] Memory saved {"id":"6ef334e1-7f6e-4f0e-a64a-6b34f603f7fb","type":"issue","pinned":false,"embedded":true} 13:55:12 INFO  [watcher] File changed {"path":"/home/nicholai/.agents/memory/memories.db-wal"} +13:55:17 INFO  [git] Auto-committed {"message":"2026-02-19T13-55-17_auto_memory/memories.db-wal, memory/memories.db-wal","filesChanged":2} +13:55:37 WARN  [git] Push failed: To https://github.com/Signet-AI/signetai.git + ! [rejected] HEAD -> main (non-fast-forward) +error: failed to push some refs to 'https://github.com/Signet-AI/signetai.git' +hint: Updates were rejected because the tip of your current branch is behind +hint: its remote counterpart. If you want to integrate the remote changes, +hint: use 'git pull' before pushing again. +hint: See the 'Note about fast-forwards' in 'git push --help' for details. + +13:55:37 WARN  [git] Periodic sync failed: Push failed: To https://github.com/Signet-AI/signetai.git + ! [rejected] HEAD -> main (non-fast-forward) +error: failed to push some refs to 'https://github.com/Signet-AI/signetai.git' +hint: Updates were rejected because the tip of your current branch is behind +hint: its remote counterpart. If you want to integrate the remote changes, +hint: use 'git pull' before pushing again. +hint: See the 'Note about fast-forwards' in 'git push --help' for details. + +13:57:48 WARN  [hooks] Failed to parse LLM output as JSON +19:35:08 INFO  [hooks] Session start hook {"harness":"claude-code","project":"/home/nicholai"} +19:35:08 INFO  [hooks] Session start completed {"memoryCount":6,"durationMs":39} +19:35:08 INFO  [watcher] File changed {"path":"/home/nicholai/.agents/memory/memories.db-shm"} +19:35:08 INFO  [watcher] File changed {"path":"/home/nicholai/.agents/memory/memories.db-wal"} +19:35:08 INFO  [watcher] File changed {"path":"/home/nicholai/.agents/memory/memories.db"} diff --git a/.daemon/logs/signet-2026-02-19.log b/.daemon/logs/signet-2026-02-19.log index 95a06a45f..a035ac0f1 100644 --- a/.daemon/logs/signet-2026-02-19.log +++ b/.daemon/logs/signet-2026-02-19.log @@ -2493,3 +2493,12 @@ {"timestamp":"2026-02-19T13:55:11.328Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-wal"}} {"timestamp":"2026-02-19T13:55:12.124Z","level":"info","category":"memory","message":"Memory saved","data":{"id":"6ef334e1-7f6e-4f0e-a64a-6b34f603f7fb","type":"issue","pinned":false,"embedded":true}} {"timestamp":"2026-02-19T13:55:12.125Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-wal"}} +{"timestamp":"2026-02-19T13:55:17.146Z","level":"info","category":"git","message":"Auto-committed","data":{"message":"2026-02-19T13-55-17_auto_memory/memories.db-wal, memory/memories.db-wal","filesChanged":2}} +{"timestamp":"2026-02-19T13:55:37.260Z","level":"warn","category":"git","message":"Push failed: To https://github.com/Signet-AI/signetai.git\n ! [rejected] HEAD -> main (non-fast-forward)\nerror: failed to push some refs to 'https://github.com/Signet-AI/signetai.git'\nhint: Updates were rejected because the tip of your current branch is behind\nhint: its remote counterpart. If you want to integrate the remote changes,\nhint: use 'git pull' before pushing again.\nhint: See the 'Note about fast-forwards' in 'git push --help' for details.\n"} +{"timestamp":"2026-02-19T13:55:37.260Z","level":"warn","category":"git","message":"Periodic sync failed: Push failed: To https://github.com/Signet-AI/signetai.git\n ! [rejected] HEAD -> main (non-fast-forward)\nerror: failed to push some refs to 'https://github.com/Signet-AI/signetai.git'\nhint: Updates were rejected because the tip of your current branch is behind\nhint: its remote counterpart. If you want to integrate the remote changes,\nhint: use 'git pull' before pushing again.\nhint: See the 'Note about fast-forwards' in 'git push --help' for details.\n"} +{"timestamp":"2026-02-19T13:57:48.522Z","level":"warn","category":"hooks","message":"Failed to parse LLM output as JSON"} +{"timestamp":"2026-02-19T19:35:08.746Z","level":"info","category":"hooks","message":"Session start hook","data":{"harness":"claude-code","project":"/home/nicholai"}} +{"timestamp":"2026-02-19T19:35:08.785Z","level":"info","category":"hooks","message":"Session start completed","data":{"memoryCount":6,"durationMs":39}} +{"timestamp":"2026-02-19T19:35:08.788Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}} +{"timestamp":"2026-02-19T19:35:08.788Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-wal"}} +{"timestamp":"2026-02-19T19:35:08.810Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db"}} diff --git a/hooks/agent-memory/handler.js b/hooks/agent-memory/handler.js index ebdcf57c3..3bddd1bf6 100644 --- a/hooks/agent-memory/handler.js +++ b/hooks/agent-memory/handler.js @@ -1,20 +1,14 @@ -import { spawn } from "node:child_process"; -import os from "node:os"; +const DAEMON_URL = process.env.SIGNET_DAEMON_URL || "http://localhost:3850"; -const MEMORY_SCRIPT = "/home/nicholai/.agents/memory/scripts/memory.py"; - -async function runMemoryScript(args) { - return new Promise((resolve, reject) => { - const proc = spawn("python3", [MEMORY_SCRIPT, ...args], { timeout: 5000 }); - let stdout = "", stderr = ""; - proc.stdout.on("data", (d) => { stdout += d.toString(); }); - proc.stderr.on("data", (d) => { stderr += d.toString(); }); - proc.on("close", (code) => { - if (code === 0) resolve(stdout.trim()); - else reject(new Error(stderr || `exit code ${code}`)); - }); - proc.on("error", reject); +async function fetchDaemon(path, body) { + const res = await fetch(`${DAEMON_URL}${path}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(body), + signal: AbortSignal.timeout(5000), }); + if (!res.ok) throw new Error(`daemon ${res.status}`); + return res.json(); } const handler = async (event) => { @@ -23,24 +17,34 @@ const handler = async (event) => { switch (event.action) { case "remember": - if (!args.trim()) { event.messages.push("🧠 Usage: /remember "); return; } + if (!args.trim()) { event.messages.push("Usage: /remember "); return; } try { - const result = await runMemoryScript(["save", "--mode", "explicit", "--who", "openclaw", "--content", args.trim()]); - event.messages.push(`🧠 ${result}`); - } catch (e) { event.messages.push(`🧠 Error: ${e.message}`); } + await fetchDaemon("/api/hooks/remember", { + harness: "openclaw", who: "openclaw", content: args.trim(), + }); + event.messages.push(`saved: ${args.trim().slice(0, 50)}...`); + } catch (e) { event.messages.push(`Error: ${e.message}`); } break; case "recall": - if (!args.trim()) { event.messages.push("🧠 Usage: /recall "); return; } + if (!args.trim()) { event.messages.push("Usage: /recall "); return; } try { - const result = await runMemoryScript(["query", args.trim(), "--limit", "10"]); - event.messages.push(result ? `🧠 Results:\n\n${result}` : "🧠 No memories found."); - } catch (e) { event.messages.push(`🧠 Error: ${e.message}`); } + const data = await fetchDaemon("/api/hooks/recall", { + harness: "openclaw", query: args.trim(), + }); + if (data.results?.length) { + event.messages.push(data.results.map(r => `- ${r.content}`).join("\n")); + } else { + event.messages.push("No memories found."); + } + } catch (e) { event.messages.push(`Error: ${e.message}`); } break; case "context": try { - const result = await runMemoryScript(["load", "--mode", "session-start"]); - event.messages.push(result ? `🧠 **Context**\n\n${result}` : "🧠 No context."); - } catch (e) { event.messages.push(`🧠 Error: ${e.message}`); } + const data = await fetchDaemon("/api/hooks/session-start", { + harness: "openclaw", + }); + event.messages.push(data.inject || "no context"); + } catch (e) { event.messages.push(`Error: ${e.message}`); } break; } }; diff --git a/memory/memories.db b/memory/memories.db index 70c9ee0cb..7ddf51572 100644 Binary files a/memory/memories.db and b/memory/memories.db differ diff --git a/memory/memories.db-shm b/memory/memories.db-shm deleted file mode 100644 index cf437a51e..000000000 Binary files a/memory/memories.db-shm and /dev/null differ diff --git a/memory/memories.db-wal b/memory/memories.db-wal deleted file mode 100644 index 741134800..000000000 Binary files a/memory/memories.db-wal and /dev/null differ diff --git a/skills/memory-debug/SKILL.md b/skills/memory-debug/SKILL.md new file mode 100644 index 000000000..c612ea318 --- /dev/null +++ b/skills/memory-debug/SKILL.md @@ -0,0 +1,115 @@ +--- +name: memory-debug +description: Diagnose and fix Signet memory issues (daemon health, embeddings, search quality, and data integrity). +user_invocable: true +arg_hint: "[symptom or query]" +builtin: true +--- + +# /memory-debug + +Debug the Signet memory system when recall quality is poor, memories are missing, or remember/recall commands fail. + +Use this skill when the user asks things like: +- "memory is broken" +- "recall isn't finding anything" +- "remember didn't save" +- "why are results low quality?" + +## syntax + +```bash +/memory-debug +/memory-debug recall is empty +/memory-debug embeddings failing +``` + +## workflow + +Run these checks in order and stop when you find the root cause. + +### 1) verify daemon + config + +```bash +signet status +curl -s http://localhost:3850/health +``` + +If daemon is down, run: + +```bash +signet start +signet restart +``` + +Then verify key files exist: +- `~/.agents/agent.yaml` +- `~/.agents/memory/memories.db` + +### 2) verify write path (`remember`) + +```bash +signet remember "memory-debug smoke test" -t debug,smoke -w claude-code +``` + +Expected: success response with `embedded: true` or a clear fallback message. + +If save fails, capture exact CLI error and recommend the fix (daemon restart, permissions, missing config, etc.). + +### 3) verify read path (`recall`) + +```bash +signet recall "memory-debug smoke test" -l 5 --json +``` + +If no results: +- retry with simpler keyword query +- check `search.min_score` and `search.alpha` in `~/.agents/agent.yaml` +- confirm the memory was actually written in step 2 + +### 4) check embedding health + +If memories save but semantic recall is weak: + +```bash +signet recall "memory-debug smoke test" --json +``` + +Inspect whether scores are keyword-heavy and whether embedding appears unavailable. + +Then verify embedding provider configuration in `~/.agents/agent.yaml`: +- `embedding.provider` +- `embedding.model` +- `embedding.dimensions` + +Common fixes: +- provider offline (Ollama/OpenAI unreachable) +- wrong model name +- dimensions mismatch after model change + +### 5) advanced diagnostics + +Check daemon logs for hook and memory errors: + +```bash +signet logs -c hooks +signet logs -c memory +``` + +Use direct API checks for deeper issues: + +```bash +curl -s "http://localhost:3850/api/memory/search?q=debug&limit=5" +curl -s http://localhost:3850/api/status +``` + +## response format + +When reporting back, include: +1. what failed +2. exact command + error +3. likely root cause +4. concrete fix steps +5. verification command to confirm fix + +Prefer minimal, reproducible checks over broad speculation. diff --git a/skills/recall/SKILL.md b/skills/recall/SKILL.md index bdf725116..3e83ad639 100644 --- a/skills/recall/SKILL.md +++ b/skills/recall/SKILL.md @@ -49,15 +49,16 @@ Example with filters: signet recall "signet" --type preference --tags architecture -l 5 ``` -### fallback (daemon not running) +### daemon required -If the daemon is unavailable, fall back to the Python script: +The daemon must be running for recall to work. Check status: ```bash -python ~/.agents/memory/scripts/memory.py query "" +signet status +curl -s http://localhost:3850/health ``` -Check daemon status: `signet status` or `curl -s http://localhost:3850/health` +If the daemon is down, start it with `signet start`. ## response format diff --git a/skills/remember/SKILL.md b/skills/remember/SKILL.md index 1299b8487..f8ec577ad 100644 --- a/skills/remember/SKILL.md +++ b/skills/remember/SKILL.md @@ -53,17 +53,16 @@ The daemon automatically: - generates embedding via configured provider (Ollama/OpenAI) - stores in SQLite + embeddings table -### fallback (daemon not running) +### daemon required -If the daemon is unavailable, fall back to the Python script: +The daemon must be running for remember to work. Check status: ```bash -python ~/.agents/memory/scripts/memory.py save \ - --mode explicit --who --project "$(pwd)" \ - --content "" +signet status +curl -s http://localhost:3850/health ``` -Check daemon status: `signet status` or `curl -s http://localhost:3850/health` +If the daemon is down, start it with `signet start`. ## type inference diff --git a/skills/signet/SKILL.md b/skills/signet/SKILL.md new file mode 100644 index 000000000..6acb5a4ff --- /dev/null +++ b/skills/signet/SKILL.md @@ -0,0 +1,84 @@ +# Signet Skill + +Use Signet for portable agent identity, memory, and secrets management. + +## Secrets + +Retrieve secrets (API keys, tokens) stored in Signet's encrypted vault: + +```bash +# Get a secret value +signet secret get OPENAI_API_KEY + +# List available secrets (names only, never values) +signet secret list +``` + +Secrets are encrypted at rest and only accessible to the agent. + +## Memory + +Save and recall information across sessions: + +```bash +# Save a memory (auto-categorizes and embeds) +signet remember "User prefers dark mode and vim keybindings" + +# Search memories +signet recall "user preferences" + +# Save with explicit importance +signet remember --importance critical "Never delete the production database" +``` + +Memory is persisted in `~/.agents/memory/memories.db` and synced across harnesses. + +## Daemon API + +The Signet daemon runs at `http://localhost:3850`. You can query it directly: + +```bash +# Check daemon status +curl http://localhost:3850/api/status + +# Search memories via API +curl "http://localhost:3850/api/memory/search?q=preferences" + +# Get a secret via API (requires local access) +curl http://localhost:3850/api/secrets/OPENAI_API_KEY +``` + +## Agent Identity Files + +Your identity is defined in `~/.agents/`: + +- `AGENTS.md` - Instructions and capabilities +- `SOUL.md` - Personality and tone +- `IDENTITY.md` - Name and traits +- `USER.md` - User profile and preferences +- `MEMORY.md` - Working memory summary (auto-generated) +- `agent.yaml` - Configuration + +## Skills + +Skills are stored in `~/.agents/skills/` and symlinked to harness directories. + +Install skills: +```bash +npx skills install +``` + +## Commands Reference + +```bash +signet # Interactive menu +signet status # Show status +signet dashboard # Open web UI +signet secret put NAME # Store a secret +signet secret get NAME # Retrieve a secret +signet secret list # List secret names +signet remember "..." # Save a memory +signet recall "..." # Search memories +signet sync # Sync built-in templates/skills +signet restart # Restart daemon +```