from typing import Any, Dict, Optional from langchain_core.tools import tool from wiki_engine.service import ( delete_by_file, delete_by_kb, diff_kb, evidence_search, get_stats, reconcile_kb, resolve_kb_reference, search_wiki, sync_file, sync_kb, ) async def wiki_pointer_search( query: str, kb_id: Optional[str] = None, limit: int = 5, ) -> Dict[str, Any]: """Search local Wiki pointer pages and return related 11000 slice ids.""" if not query or not query.strip(): return {"success": False, "error": "query is empty", "items": []} return await search_wiki(query=query.strip(), kb_id=kb_id, limit=limit, include_slices=True) async def wiki_evidence_search( query: str, kb_id: Optional[str] = None, limit: int = 5, ) -> Dict[str, Any]: """Return Wiki results in the unified evidence-like format.""" if not query or not query.strip(): return {"success": False, "error": "query is empty", "items": []} return await evidence_search(query=query.strip(), kb_id=kb_id, limit=limit) async def wiki_admin_stats() -> Dict[str, Any]: return {"success": True, "stats": await get_stats()} async def wiki_admin_sync_file(file_id: str, kb_id: Optional[str] = None, use_llm: bool = False) -> Dict[str, Any]: return await sync_file(file_id=file_id, kb_id=kb_id, use_llm=use_llm) async def wiki_admin_sync_kb( kb_id: Optional[str] = None, kb_name: Optional[str] = None, limit: int = 20, use_llm: bool = False, ) -> Dict[str, Any]: target = await _resolve_kb_target(kb_id=kb_id, kb_name=kb_name) if not target.get("success"): return target result = await sync_kb(kb_id=target["kb_id"], limit=limit, use_llm=use_llm) result.update({"kb_name": target.get("kb_name", ""), "kb_path": target.get("kb_path", "")}) return result async def wiki_admin_diff_kb( kb_id: Optional[str] = None, kb_name: Optional[str] = None, include_children: bool = False, limit: int = 200, ) -> Dict[str, Any]: target = await _resolve_kb_target(kb_id=kb_id, kb_name=kb_name) if not target.get("success"): return target result = await diff_kb(kb_id=target["kb_id"], include_children=include_children, limit=limit) result.update({"kb_name": target.get("kb_name", ""), "kb_path": target.get("kb_path", "")}) return result async def wiki_admin_reconcile_kb( kb_id: Optional[str] = None, kb_name: Optional[str] = None, include_children: bool = False, limit: int = 200, sync_missing: bool = True, rebuild_stale: bool = True, delete_orphan: bool = False, use_llm: bool = False, dry_run: bool = True, ) -> Dict[str, Any]: target = await _resolve_kb_target(kb_id=kb_id, kb_name=kb_name) if not target.get("success"): return target result = await reconcile_kb( kb_id=target["kb_id"], include_children=include_children, limit=limit, sync_missing=sync_missing, rebuild_stale=rebuild_stale, delete_orphan=delete_orphan, use_llm=use_llm, dry_run=dry_run, ) result.update({"kb_name": target.get("kb_name", ""), "kb_path": target.get("kb_path", "")}) return result async def wiki_admin_delete_file(file_id: str) -> Dict[str, Any]: return await delete_by_file(file_id) async def wiki_admin_delete_kb(kb_id: Optional[str] = None, kb_name: Optional[str] = None) -> Dict[str, Any]: target = await _resolve_kb_target(kb_id=kb_id, kb_name=kb_name) if not target.get("success"): return target result = await delete_by_kb(target["kb_id"]) result.update({"kb_name": target.get("kb_name", ""), "kb_path": target.get("kb_path", "")}) return result async def _resolve_kb_target(kb_id: Optional[str] = None, kb_name: Optional[str] = None) -> Dict[str, Any]: if kb_id and str(kb_id).strip(): return {"success": True, "kb_id": str(kb_id).strip(), "kb_name": "", "kb_path": ""} if kb_name and str(kb_name).strip(): return await resolve_kb_reference(str(kb_name).strip()) return {"success": False, "error": "kb_name is required", "matches": []} @tool async def wiki_pointer_search_tool(query: str, limit: int = 5) -> str: """Search Wiki pointer pages and format them for workflow prompts.""" result = await wiki_pointer_search(query=query, limit=limit) if not result.get("success"): return "" parts = [] for item in result.get("items", []): title = item.get("title", "") summary = item.get("summary", "") slice_ids = ", ".join(item.get("related_slice_ids", [])[:8]) if title or summary: parts.append(f"[Wiki] {title}\n{summary}\nrelated_slice_ids: {slice_ids}") return "\n\n".join(parts)