# Library-Desk API Requirements for Tatlock Integration ## Overview The Librarian agent in Tatlock needs additional endpoints in library-desk to support wiki page editing and content management. Currently, the API provides read operations but The Librarian needs write capabilities for: - Creating new wiki pages - Updating existing wiki pages (content, title, tags, description) ## Required Endpoints ### 1. Create Wiki Page (Already Exists) **Endpoint:** `POST /wiki/pages` This endpoint already exists and works correctly. ### 2. Update Wiki Page (Needs Enhancement) **Endpoint:** `PUT /wiki/pages/{page_id}` **Current Status:** May exist but needs verification that it supports partial updates. **Required Behavior:** - Accept partial updates (only provided fields should be updated) - Support updating: `content`, `title`, `tags`, `description` - Auto-update vector embeddings after content changes - Auto-update knowledge graph after content changes **Request Body:** ```json { "content": "# New Content\n\nOptional - only if changing content", "title": "Optional - only if renaming", "tags": ["optional", "list", "of", "new", "tags"], "description": "Optional new description" } ``` **Query Parameters:** - `user`: User identifier for multi-tenancy (required) **Response:** ```json { "id": 42, "path": "/projects/example", "title": "Updated Title", "description": "Updated description", "content": "# New Content...", "tags": ["updated", "tags"], "updated_at": "2024-01-15T10:30:00Z" } ``` **Notes:** - Should trigger background tasks to re-index vectors and refresh graph entities - Should validate that user has access to the page (namespace check) - Should preserve fields that are not provided in the request ## Use Cases for The Librarian ### Adding New Knowledge When a user says "Add this to the wiki" or "Create a page about X": - Librarian uses `POST /wiki/pages` to create the page - Tags are assigned based on context (dossiers) ### Correcting Information When a user says "Update the page about X" or "Fix this fact": 1. Librarian searches for the page with `GET /wiki/search` 2. Fetches full content with `GET /wiki/pages/{id}` 3. Updates with corrected content via `PUT /wiki/pages/{id}` ### Organizing Knowledge When a user says "Add this page to the projects dossier": - Librarian updates just the tags field via `PUT /wiki/pages/{id}` ## Integration Notes - The Librarian will call these endpoints via HTTP from Tatlock - Authentication uses Bearer token (LIBRARY_DESK_API_KEY) - All operations are scoped to the user's namespace - Background processing (vectors, graph) should not block the response ## Testing Checklist - [ ] `PUT /wiki/pages/{page_id}` accepts partial updates - [ ] Updating content triggers vector re-indexing - [ ] Updating content triggers graph entity extraction - [ ] Tags can be updated independently of content - [ ] Description can be updated independently - [ ] Title can be updated (with path remaining the same) - [ ] User namespace validation works correctly ===== IMPLEMENTATION INSTRUCTIONS ========= # Librarian Wiki Integration Guide This document provides implementation instructions for integrating the library-desk wiki endpoints into the Librarian agent (Tatlock). ## Available Endpoints ### 1. Create Wiki Page **Endpoint:** `POST /wiki/pages` Use this for simple page creation when the Librarian already has the content. ```python async def create_wiki_page( title: str, path: str, content: str, tags: list[str], description: str = "", user: str = "default" ) -> dict: """Create a new wiki page.""" response = await http_client.post( f"{LIBRARY_DESK_URL}/wiki/pages", headers={"Authorization": f"Bearer {LIBRARY_DESK_API_KEY}"}, json={ "title": title, "path": path, "content": content, "tags": tags, "description": description, "user": user } ) return response.json() ``` **When to use:** - User provides specific content to add - Librarian has already composed the content - Simple note-taking or quick additions --- ### 2. Smart Create Wiki Page (Recommended for Research) **Endpoint:** `POST /wiki/pages/smart-create` Use this when the Librarian should research a topic before creating the page. This endpoint: 1. Searches existing wiki, knowledge graph, and web for context 2. Uses LLM to synthesize findings into structured content 3. Creates the page with proper attribution 4. Automatically links entities bidirectionally ```python async def smart_create_wiki_page( topic: str, tags: list[str], user: str = "default", path: str | None = None, include_web_research: bool = True, include_wiki_search: bool = True ) -> dict: """Create a wiki page with HybridRAG research.""" response = await http_client.post( f"{LIBRARY_DESK_URL}/wiki/pages/smart-create", headers={"Authorization": f"Bearer {LIBRARY_DESK_API_KEY}"}, json={ "topic": topic, "path": path, # Optional - auto-generated from topic if not provided "tags": tags, "user": user, "include_web_research": include_web_research, "include_wiki_search": include_wiki_search } ) return response.json() ``` **Response includes:** ```json { "page": { "id": 123, "path": "/users/jpmschweitzer/technology/docker-orchestration", "title": "Docker orchestration", "content": "# Docker Orchestration\n\n...", "tags": ["technology", "devops"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" }, "research_summary": { "wiki_results": 3, "web_results": 8, "graph_entities": 5, "keywords_extracted": 12, "timing_ms": 4500 }, "sources_used": 11, "search_id": "uuid-for-reference", "entity_linking": { "forward_links": 5, "backward_links": 3, "pages_updated": 2 } } ``` **When to use:** - User says "Create a page about X" - User says "Add information about X to the wiki" - Librarian needs to research before writing - Topic benefits from context from existing knowledge --- ### 3. Update Wiki Page **Endpoint:** `PUT /wiki/pages/{page_id}` Use this for modifying existing pages. Supports partial updates. ```python async def update_wiki_page( page_id: int, user: str = "default", content: str | None = None, title: str | None = None, tags: list[str] | None = None, description: str | None = None ) -> dict: """Update an existing wiki page (partial updates supported).""" # Only include fields that are being updated update_data = {} if content is not None: update_data["content"] = content if title is not None: update_data["title"] = title if tags is not None: update_data["tags"] = tags if description is not None: update_data["description"] = description response = await http_client.put( f"{LIBRARY_DESK_URL}/wiki/pages/{page_id}?user={user}", headers={"Authorization": f"Bearer {LIBRARY_DESK_API_KEY}"}, json=update_data ) return response.json() ``` **When to use:** - User says "Update the page about X" - User says "Fix this information" - User says "Add this page to the projects dossier" (update tags only) - Correcting or enhancing existing content --- ### 4. Search Wiki Pages **Endpoint:** `GET /wiki/search` Use this to find existing pages before updating. ```python async def search_wiki( query: str, user: str = "default" ) -> dict: """Search wiki pages.""" response = await http_client.get( f"{LIBRARY_DESK_URL}/wiki/search", headers={"Authorization": f"Bearer {LIBRARY_DESK_API_KEY}"}, params={"q": query, "user": user} ) return response.json() ``` --- ### 5. Get Wiki Page **Endpoint:** `GET /wiki/pages/{page_id}` Use this to fetch full page content before editing. ```python async def get_wiki_page( page_id: int, user: str = "default" ) -> dict: """Get a wiki page by ID.""" response = await http_client.get( f"{LIBRARY_DESK_URL}/wiki/pages/{page_id}", headers={"Authorization": f"Bearer {LIBRARY_DESK_API_KEY}"}, params={"user": user} ) return response.json() ``` --- ## Decision Flow for Librarian ``` User Request │ ▼ ┌─────────────────────────────────────────────┐ │ Does user want to CREATE or UPDATE a page? │ └─────────────────────────────────────────────┘ │ │ ▼ ▼ CREATE UPDATE │ │ ▼ ▼ ┌─────────────────┐ ┌──────────────────────┐ │ Does Librarian │ │ Search for the page │ │ need to research│ │ GET /wiki/search │ │ the topic? │ └──────────────────────┘ └─────────────────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────────┐ YES NO │ Get full page content│ │ │ │ GET /wiki/pages/{id} │ ▼ ▼ └──────────────────────┘ ┌─────────┐ ┌─────────┐ │ │ smart- │ │ POST │ ▼ │ create │ │ /wiki/ │ ┌──────────────────────┐ │ │ │ pages │ │ Update the page │ └─────────┘ └─────────┘ │ PUT /wiki/pages/{id} │ └──────────────────────┘ ``` --- ## Common Use Cases ### 1. "Create a page about Docker Compose" ```python # Use smart-create for research-backed content result = await smart_create_wiki_page( topic="Docker Compose", tags=["technology", "devops", "containers"], user="jpmschweitzer" ) # Returns page with synthesized content from wiki + web research ``` ### 2. "Add this note to the wiki: Remember to renew SSL cert on Jan 15" ```python # Use simple create for user-provided content result = await create_wiki_page( title="SSL Certificate Renewal Reminder", path="/reminders/ssl-renewal", content="# SSL Certificate Renewal\n\nRemember to renew SSL cert on Jan 15", tags=["reminders", "infrastructure"], user="jpmschweitzer" ) ``` ### 3. "Update the page about my home server to add the new IP" ```python # 1. Search for the page search_results = await search_wiki("home server", user="jpmschweitzer") page_id = search_results["results"][0]["id"] # 2. Get current content page = await get_wiki_page(page_id, user="jpmschweitzer") # 3. Modify content (Librarian edits the markdown) new_content = page["content"] + "\n\n## Updated IP\n\nNew IP: 192.168.1.100" # 4. Update the page result = await update_wiki_page( page_id=page_id, content=new_content, user="jpmschweitzer" ) ``` ### 4. "Add this page to the projects dossier" ```python # Update only tags (partial update) result = await update_wiki_page( page_id=page_id, tags=["projects", "existing-tag"], # Add "projects" tag user="jpmschweitzer" ) ``` --- ## Background Processing All write operations trigger background tasks that: 1. **Vector Indexing:** Chunks content and generates embeddings in Qdrant 2. **Graph Extraction:** Extracts entities and creates Neo4j relationships 3. **Entity Linking:** (smart-create only) Links entities bidirectionally These run asynchronously and don't block the API response. --- ## Authentication All endpoints require Bearer token authentication: ``` Authorization: Bearer {LIBRARY_DESK_API_KEY} ``` --- ## Multi-Tenancy All operations are scoped to the user's namespace: - Pages are stored under `/users/{user}/...` - Vector collections are per-user: `library_desk_{user}` - Graph nodes are labeled per-user: `User_{User}_Document` Always pass the `user` parameter to ensure proper isolation.