feat: add smart page creation endpoint with HybridRAG research

Add POST /wiki/pages/smart-create endpoint that combines research with
content generation for the librarian agent:

- Run HybridRAG search on topic (wiki + graph + web)
- Use LLM (WikiPageWriter) to synthesize findings into wiki content
- Create page with proper attribution and sources
- Schedule background tasks for vector/graph indexing
- Apply bidirectional entity linking (forward + backward links)

New files:
- src/services/entity_linking_utils.py - shared entity linking helper

Modified:
- src/models/wiki.py - WikiSmartCreateRequest/Response models
- src/services/wiki_service.py - smart_create_page() method
- src/routers/wiki.py - /pages/smart-create endpoint

🤖 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 20:23:46 +01:00
co-authored by Claude Opus 4.5
parent 95852190ba
commit e05e7aeae3
4 changed files with 492 additions and 3 deletions
+127 -2
View File
@@ -13,7 +13,8 @@ import logging
from src.models.wiki import (
WikiPage, WikiPageList, WikiPageCreate, WikiPageUpdate, WikiPageMove,
WikiOperationResponse, WikiSearchResponse,
DossierList, WikiSearchResult
DossierList, WikiSearchResult,
WikiSmartCreateRequest, WikiSmartCreateResponse
)
from src.services.wiki_service import WikiService
from src.services.graph_service import GraphService
@@ -22,8 +23,15 @@ from src.clients.wikijs_client import WikiJSClient
from src.clients.neo4j_client import Neo4jClient
from src.clients.qdrant_client import QdrantClientWrapper
from src.clients.ollama_client import OllamaClient
from src.core.dependencies import WikiJSDep, Neo4jDep, QdrantDep, OllamaDep, verify_api_key
from src.core.dependencies import (
WikiJSDep, Neo4jDep, QdrantDep, OllamaDep, SearXNGDep,
verify_api_key, get_settings, get_hybrid_rag_service, get_ingestion_service
)
from src.core.multi_tenancy import DEFAULT_USER
from src.services.hybrid_rag_service import HybridRAGService
from src.services.wiki_page_writer import WikiPageWriter
from src.services.entity_linking_utils import apply_bidirectional_entity_linking
from src.config import Settings
logger = logging.getLogger(__name__)
@@ -163,6 +171,123 @@ async def create_page(
raise HTTPException(status_code=500, detail="Internal server error")
@router.post("/pages/smart-create", response_model=WikiSmartCreateResponse, status_code=201)
async def smart_create_page(
request: WikiSmartCreateRequest,
background_tasks: BackgroundTasks,
wiki_client: WikiJSDep,
neo4j_client: Neo4jDep,
qdrant_client: QdrantDep,
ollama_client: OllamaDep,
searxng_client: SearXNGDep,
settings: Settings = Depends(get_settings),
api_key: str = Depends(verify_api_key)
):
"""
Create wiki page with intelligent research.
Combines HybridRAG search with LLM content generation to create
rich, well-researched wiki pages in a single API call.
**Process:**
1. Runs HybridRAG search on the topic (wiki + graph + web)
2. Uses LLM to synthesize findings into structured wiki content
3. Creates the page with proper attribution/sources
4. Indexes into vectors + knowledge graph (background)
5. Applies bidirectional entity linking (background)
**Example Request:**
```json
{
"topic": "Docker orchestration patterns",
"path": "/technology/containers/docker-orchestration",
"tags": ["technology", "devops", "containers"],
"user": "jpmschweitzer",
"include_web_research": true,
"include_wiki_search": true
}
```
**Returns:**
- Created page with ID, path, content
- Research summary (wiki/web/graph result counts)
- Entity linking statistics (forward/backward links)
"""
try:
user = request.user or DEFAULT_USER
# Build services
wiki_service = WikiService(wiki_client)
vector_service = VectorService(qdrant_client, wiki_client, ollama_client)
graph_service = GraphService(neo4j_client, wiki_client)
hybrid_rag_service = HybridRAGService(
vector_service=vector_service,
graph_service=graph_service,
searxng_client=searxng_client,
ollama_client=ollama_client,
settings=settings
)
wiki_page_writer = WikiPageWriter(ollama_client=ollama_client)
# Step 1-5: Research + Generate + Create page
page, research_data = await wiki_service.smart_create_page(
topic=request.topic,
user=user,
path=request.path,
tags=request.tags,
hybrid_rag_service=hybrid_rag_service,
wiki_page_writer=wiki_page_writer,
include_web=request.include_web_research,
include_wiki=request.include_wiki_search
)
# Schedule graph and vector updates in background
background_tasks.add_task(
graph_service.update_from_page,
page_id=page.id,
user=user
)
background_tasks.add_task(
vector_service.update_from_page,
page_id=page.id,
user=user
)
# Schedule bidirectional entity linking in background
async def run_entity_linking():
ingestion_service = get_ingestion_service()
return await apply_bidirectional_entity_linking(
page_id=page.id,
page_title=page.title,
user=user,
neo4j_client=neo4j_client,
wiki_service=wiki_service,
ingestion_service=ingestion_service
)
background_tasks.add_task(run_entity_linking)
logger.info(
f"Smart page created: id={page.id}, path={page.path}, "
f"sources={research_data['sources_used']}"
)
return WikiSmartCreateResponse(
page=page,
research_summary=research_data["research_summary"],
sources_used=research_data["sources_used"],
search_id=research_data["search_id"],
entity_linking={"forward_links": 0, "backward_links": 0, "pages_updated": 0}
# Note: entity_linking stats are 0 here as it runs in background
)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Failed to smart create page: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Internal server error")
@router.put("/pages/{page_id}", response_model=WikiPage)
async def update_page(
page_id: int,