feat(library-desk): add list_all_pages and get_taxonomy_structure to wikijs client
- list_all_pages: fetch all pages with path prefix filter - get_taxonomy_structure: extract category/subcategory structure for taxonomy-aware classification 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -231,6 +231,94 @@ class WikiJSClient:
|
||||
|
||||
return pages
|
||||
|
||||
async def list_all_pages(
|
||||
self,
|
||||
path_prefix: str = "",
|
||||
tags: Optional[List[str]] = None,
|
||||
batch_size: int = 100
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
List ALL pages with pagination support.
|
||||
|
||||
Fetches pages in batches until all are retrieved.
|
||||
|
||||
Args:
|
||||
path_prefix: Filter by path prefix (e.g., "users/jpmschweitzer")
|
||||
tags: Filter by tags
|
||||
batch_size: Number of pages per batch (max 100)
|
||||
|
||||
Returns:
|
||||
Complete list of page objects
|
||||
"""
|
||||
all_pages = []
|
||||
offset = 0
|
||||
|
||||
while True:
|
||||
# Wiki.js list doesn't support offset, but limit is enough
|
||||
# since we filter client-side by path_prefix
|
||||
# Just fetch a large batch
|
||||
pages = await self.list_pages(
|
||||
path_prefix=path_prefix,
|
||||
tags=tags,
|
||||
limit=1000 # Fetch up to 1000 at once
|
||||
)
|
||||
|
||||
if not pages:
|
||||
break
|
||||
|
||||
all_pages = pages
|
||||
break # Wiki.js list doesn't paginate, so one call is enough
|
||||
|
||||
logger.info(f"list_all_pages: found {len(all_pages)} pages (prefix: {path_prefix or 'all'})")
|
||||
return all_pages
|
||||
|
||||
async def get_taxonomy_structure(
|
||||
self,
|
||||
user_namespace: str,
|
||||
limit: int = 500
|
||||
) -> Dict[str, List[str]]:
|
||||
"""
|
||||
Get the existing taxonomy structure for a user namespace.
|
||||
|
||||
Returns a dict mapping top-level categories to their subcategories.
|
||||
This helps the LLM choose existing paths rather than creating new ones.
|
||||
|
||||
Args:
|
||||
user_namespace: User namespace (e.g., "users/jpmschweitzer")
|
||||
limit: Maximum pages to fetch
|
||||
|
||||
Returns:
|
||||
Dict like {"reference": ["political-entities", "tech"], "places": ["the-netherlands"]}
|
||||
"""
|
||||
from collections import defaultdict
|
||||
|
||||
pages = await self.list_pages(path_prefix=user_namespace, limit=limit)
|
||||
|
||||
# Extract structure: category -> set of subcategories
|
||||
structure: Dict[str, set] = defaultdict(set)
|
||||
prefix = user_namespace.strip("/") + "/"
|
||||
|
||||
for page in pages:
|
||||
path = page.get("path", "")
|
||||
if not path.startswith(prefix):
|
||||
continue
|
||||
|
||||
# Get relative path within user namespace
|
||||
rel_path = path[len(prefix):]
|
||||
parts = rel_path.split("/")
|
||||
|
||||
if len(parts) >= 1:
|
||||
category = parts[0]
|
||||
if len(parts) >= 2:
|
||||
# Has subcategory (e.g., reference/political-entities/nato)
|
||||
structure[category].add(parts[1])
|
||||
else:
|
||||
# Just ensure category exists in structure
|
||||
structure[category] # Access to ensure key exists
|
||||
|
||||
# Convert sets to sorted lists
|
||||
return {cat: sorted(list(subs)) for cat, subs in sorted(structure.items())}
|
||||
|
||||
async def get_page(self, page_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Get single page by ID.
|
||||
|
||||
Reference in New Issue
Block a user