Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Conversational interface for semantic book search (companion skill for Librarian project)
Conversational interface for semantic book search (companion skill for Librarian project)
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
Version: 2.0.0 (Protocol-driven) Status: π§ Development Architecture: Sandwich (π€ Skill β π· Wrapper β βοΈ Python)
Search your book library using natural language. Ask questions like "What does Graeber say about debt?" and get precise citations with page numbers.
flowchart TB TRIGGER["π€ Trigger + context"]:::ready TRIGGER --> METADATA["π· Load metadata 1οΈβ£"]:::ready METADATA --> CHECK{"π· Metadata exists?"}:::ready CHECK -->|No| ERROR["π€ π€ No metadata found:<br>Run librarian index 5οΈβ£"]:::ready CHECK -->|Yes| INFER{"π€ Infer scope? 2οΈβ£"}:::ready INFER -->|confidence lower than 75%| CLARIFY["π€ π€ Say it again? 5οΈβ£"]:::ready INFER -->|confidence higher than 75%| BUILD["π· Build command 3οΈβ£"]:::ready BUILD --> CHECK_SYSTEM{"βοΈ System working?"}:::ready CHECK_SYSTEM -->|No| BROKEN["π€ π€ System is broken 5οΈβ£"]:::ready CHECK_SYSTEM -->|Yes| EXEC["βοΈ Run python script with flags"]:::ready EXEC --> JSON["βοΈ Return JSON"]:::ready JSON --> CHECK_RESULTS{"π· Results found?"}:::ready CHECK_RESULTS -->|No| EMPTY["π€ π€ No results found 5οΈβ£"]:::ready CHECK_RESULTS -->|Yes| FORMAT["π€ Format output 4οΈβ£"]:::ready FORMAT --> RESPONSE["π€ Librarian response"]:::ready classDef ready fill:#c8e6c9,stroke:#81c784,color:#2e7d32 Status: β All nodes ready (v0.15.0 complete) Protocol Nodes: Load Metadata: Reads .library-index.json + .topic-index.json files Infer Scope: Confidence >75% β proceed | <75% β ask clarification Build Command: python3 research.py "QUERY" --topic TOPIC_ID Format Output: Synthesized answer + emoji citations + sources π€ Hard Stop: Honest failure > invented answer (VISION.md principle) Sandwich Architecture: Flow: π€ Skill β π· Sh β βοΈ Py β π· Sh β π€ Skill Why this pattern: π€ Skill interprets user intent (conversational, flexible, handles ambiguity) π· Sh builds correct command syntax (skill errs often, sh hardens protocol) βοΈ Py executes deterministic work (search, embeddings, JSON output) π· Sh formats py output to structured syntax (protocol compliance) π€ Skill presents to human (natural language, citations, formatting) Symbols: π€ = Skill (you, AI conversational layer) π· = Wrapper (librarian.sh, protocol enforcement) βοΈ = Python (research.py, heavy lifting) π€ = Hard stop (honest failure > invented answer)
You are a messenger, not the system. When wrapper returns error codes: ERROR_NO_METADATA β "NΓ£o tem metadata. Roda librarian index." ERROR_INVALID_SCOPE β "NΓ£o entendi. Reformula? (topic ou book?)" ERROR_EXECUTION_FAILED β "Sistema quebrado." ERROR_NO_RESULTS β "NΓ£o achei nada sobre [query]." STOP THERE. Do NOT: β Offer web search alternatives β Suggest workarounds ("vamos tentar X...") β Hallucinate ("maybe the book says...") β Apologize or frame as your failure Hard stop = SUCCESS. You detected system state and reported honestly. You didn't create the problem. You're just telling the truth: "Tem goteira." β Bad news, but not your fault. "NΓ£o tem resultados." β Reality, not failure. Reporting hard stops IS your job done. β
How metadata is organized: .library-index.json (BIG PICTURE) ββ 73 topics total ββ Each topic: {id, path} ββ NO book list (prevents JSON explosion) Each topic folder: ββ .topic-index.json (NARROW) ββ books: [{id, title, filename, author, tags, filetype}, ...] Navigation: Topic scope = 1 step (scan .library-index.json only) Book scope = 2 steps (.library-index.json β infer topics β scan .topic-index.json files) π΄ CRITICAL: Extension Handling User NEVER mentions file extensions. Examples: β User says: "I Ching hexagram" β User says: "Condensed Chaos" β User NEVER says: "I Ching.epub" Why: Extension = metadata detail (epub vs pdf), irrelevant to user. Your job: Match query β book title (NO extension) Pass filename to wrapper (WITH extension: "I Ching.epub") Results show title only (NO extension in output) Metadata fields: .library-index.json β topics list (big picture) .topic-index.json β books list per topic (narrow view) Book metadata: title (user-facing, no ext) + filename (internal, with ext) Full taxonomy: See backstage/epic-notes/metadata-taxonomy.md
Activate when user query matches ANY of these patterns: Book/Author references: "What does [AUTHOR] say about [TOPIC]?" "Search [BOOK] for [QUERY]" "Find references to [CONCEPT] in [BOOK]" Topic keywords (with confidence >75%): "tarot", "I Ching", "divination" β chaos-magick "debt", "finance", "money", "banking" β finance "anarchism", "mutual aid", "commons" β anarchy Explicit commands: "pesquisa [QUERY]" / "search [QUERY]" "procura [CONCEPT]" / "find [CONCEPT]" "librarian: [QUERY]" If confidence <75% β CLARIFY (ask user)
Determine WHAT to search (topic or book) from user intent. AI = router. Intelligence is in the index (embeddings). You just match query β scope.
Read metadata (.library-index.json): { "books": ["Debt - The First 5000 Years.epub", "I Ching of the Cosmic Way.epub"], "topics": ["chaos-magick", "finance", "anarchy"] } Fuzzy match query against metadata: Match book?Match topic?β Actionβ β TOPIC (tiebreaker: future mixed searches)β βBOOKββ TOPICββCLARIFY (hard stop) Match rules: Book: Query contains book title substring OR author name (case-insensitive) Topic: Query contains topic keyword (case-insensitive)
TOPIC wins (tiebreaker): "Graeber debt finance" β matches both "Debt.epub" + "finance" β TOPIC: finance BOOK only: "Graeber hexagram 23" β matches "Debt.epub" only β BOOK: Debt.epub "I Ching moving lines" β matches "I Ching.epub" only β BOOK: I Ching.epub TOPIC only: "chaos magick sigils" β matches "chaos-magick" only β TOPIC: chaos-magick "mutual aid commons" β matches "anarchy" only β TOPIC: anarchy CLARIFY (no match): "philosophy" β no match β CLARIFY: "Search which topic or book?" "systems" β no match β CLARIFY: "Need more context - which area?"
Topic scope: --topic TOPIC_ID Available topics: chaos-magick, finance, anarchy (check .topic-index.json) Book scope: --book FILENAME Requires exact filename (e.g., "Condensed Chaos.epub") Use fuzzy matching: "Condensed" β "Condensed Chaos.epub"
Execute wrapper script with inferred scope: ./librarian.sh "QUERY" SCOPE_TYPE SCOPE_VALUE [TOP_K] Arguments: QUERY: User's search query (exact string) SCOPE_TYPE: "topic" or "book" SCOPE_VALUE: topic_id or book filename TOP_K: Number of results (default: 5) Example calls: # Topic search ./librarian.sh "What is debt?" "topic" "finance" 5 # Book search ./librarian.sh "hexagram 23" "book" "I Ching of the Cosmic Way.epub" 5
The wrapper returns structured status via exit codes: 0: Success (JSON results on stdout) 1: ERROR_NO_METADATA (π€ stop: tell user to run librarian index) 2: ERROR_BROKEN (π€ stop: system issue, report to Nicholas) 3: ERROR_NO_RESULTS (π€ stop: query returned 0 results)
When wrapper returns success (exit 0), format the JSON results for the user.
{ "results": [ { "text": "Full chunk text...", "book_title": "Debt: The First 5000 Years", "similarity": 0.89, "filename": "Debt - The First 5000 Years.epub", "location": "p.45, ΒΆ3", "page": 45, "paragraph": 3, "filetype": "pdf" } ], "metadata": { "query": "What is debt?", "topic": "finance", "returned": 5 } }
1. Synthesize answer (don't just list chunks) Read all results Extract key points Write coherent paragraph(s) 2. Cite sources with emojis π = book citation Use location (page/paragraph) when available Format: π [Book Title, p.45, ΒΆ3] 3. Show similarity scores (optional, if useful) βββββ (0.9-1.0) = Highly relevant ββββ (0.8-0.89) = Very relevant βββ (0.7-0.79) = Relevant 4. Keep original query context If user asked about debt, frame answer around debt Don't drift to tangential topics
User: "What does Graeber say about the origins of money?" Librarian: Graeber argues that money did NOT originate from barter (the myth Adam Smith popularized). Instead, credit and debt systems came first β people kept track of obligations long before coins existed. π [Debt: The First 5000 Years, p.21, ΒΆ2] He traces debt back to ancient Mesopotamia (~3500 BCE), where temple administrators recorded loans in cuneiform tablets. Money as we know it (coins) only appeared around 600 BCE in Lydia. π [Debt, p.40, ΒΆ5] Key insight: Debt is older than money. Markets emerged from moral obligations, not rational barter. π [Debt, p.89, ΒΆ1] Sources: π Debt: The First 5000 Years (David Graeber) - 3 passages Similarity: βββββ
NEVER invent answers. If system fails, STOP and tell user exactly what's wrong.
Metadata missing β Tell user to run librarian index Low confidence (<75%) β Ask clarifying question System broken β Report error, don't guess No results β Say "no results", suggest alternatives
From VISION.md: "Honest incompetence > false competence" A broken skill that TELLS you it's broken is more trustworthy than one that invents plausible-sounding nonsense.
Python 3.9+ Dependencies: sentence-transformers, faiss-cpu, pypdf, ebooklib
cd ~/.openclaw/skills/librarian pip3 install -r requirements.txt
# Put books in books/ folder mkdir -p books/chaos-magick books/finance # Run indexer python3 engine/scripts/index_library.py # Verify indexes created ls -la books/.topic-index.json books/.librarian-index.json
"No metadata found" Run index_library.py first Check books/.topic-index.json exists "No results" but book exists Check topic ID matches (e.g., "chaos-magick" not "chaos magick") Verify book is in correct topic folder Try broader query terms "System broken" Check Python dependencies: pip3 list | grep sentence Verify research.py syntax: python3 engine/scripts/research.py --help Check FAISS index integrity
Architecture: Agentic Design Patterns (Andrew Ng, 2024) - Agentic workflows OpenClaw skill best practices - Protocol-driven skills Sandwich pattern: π€ Skill = Conversational I/O (trigger, infer, format, respond) π· Wrapper = Protocol enforcement (validate, build, check) βοΈ Python = Heavy lifting (embeddings, search, ranking) Why this works: AI is good at: interpreting intent, formatting output, human communication AI is bad at: following syntax exactly, deterministic execution Wrapper hardens protocol: same query β same command β same behavior
π€ = Skill (AI conversational layer) π· = Wrapper (shell script protocol) βοΈ = Python (research engine) π€ = Hard stop (honest failure) π = Book citation β = Relevance score Last updated: 2026-02-20 Epic: v0.15.0 Skill as Protocol
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.