140 lines
4.7 KiB
Python
140 lines
4.7 KiB
Python
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)
|