docs: add library-desk integration requirements

- Document required endpoints for wiki write operations
- Include implementation guide for smart-create endpoint
- Decision flow for when to use each write tool

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-11 21:31:05 +01:00
co-authored by Claude Opus 4.5
parent 22d44b3071
commit ebac19ba6e
+424
View File
@@ -0,0 +1,424 @@
# 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.