Spaces:
Running
Running
| from fastapi import APIRouter, HTTPException | |
| from loguru import logger | |
| from api.command_service import CommandService | |
| from api.models import EmbedRequest, EmbedResponse | |
| from open_notebook.domain.models import model_manager | |
| from open_notebook.domain.notebook import Note, Source | |
| router = APIRouter() | |
| async def embed_content(embed_request: EmbedRequest): | |
| """Embed content for vector search.""" | |
| try: | |
| # Check if embedding model is available | |
| if not await model_manager.get_embedding_model(): | |
| raise HTTPException( | |
| status_code=400, | |
| detail="No embedding model configured. Please configure one in the Models section.", | |
| ) | |
| item_id = embed_request.item_id | |
| item_type = embed_request.item_type.lower() | |
| # Validate item type | |
| if item_type not in ["source", "note"]: | |
| raise HTTPException( | |
| status_code=400, detail="Item type must be either 'source' or 'note'" | |
| ) | |
| # Branch based on processing mode | |
| if embed_request.async_processing: | |
| # ASYNC PATH: Submit command for background processing | |
| logger.info(f"Using async processing for {item_type} {item_id}") | |
| try: | |
| # Import commands to ensure they're registered | |
| import commands.embedding_commands # noqa: F401 | |
| # Submit command | |
| command_id = await CommandService.submit_command_job( | |
| "open_notebook", # app name | |
| "embed_single_item", # command name | |
| {"item_id": item_id, "item_type": item_type}, | |
| ) | |
| logger.info(f"Submitted async embedding command: {command_id}") | |
| return EmbedResponse( | |
| success=True, | |
| message="Embedding queued for background processing", | |
| item_id=item_id, | |
| item_type=item_type, | |
| command_id=command_id, | |
| ) | |
| except Exception as e: | |
| logger.error(f"Failed to submit async embedding command: {e}") | |
| raise HTTPException( | |
| status_code=500, detail=f"Failed to queue embedding: {str(e)}" | |
| ) | |
| else: | |
| # SYNC PATH: Submit job (returns immediately with command_id) | |
| # NOTE: "sync" here means "submit and return command_id" - actual processing | |
| # still happens asynchronously in the worker pool | |
| logger.info(f"Using sync processing for {item_type} {item_id}") | |
| command_id = None | |
| # Get the item and embed it | |
| if item_type == "source": | |
| source_item = await Source.get(item_id) | |
| if not source_item: | |
| raise HTTPException(status_code=404, detail="Source not found") | |
| # Submit vectorization job (returns command_id for tracking) | |
| command_id = await source_item.vectorize() | |
| message = "Source vectorization job submitted" | |
| elif item_type == "note": | |
| note_item = await Note.get(item_id) | |
| if not note_item: | |
| raise HTTPException(status_code=404, detail="Note not found") | |
| await note_item.save() # Auto-embeds via ObjectModel.save() | |
| message = "Note embedded successfully" | |
| return EmbedResponse( | |
| success=True, message=message, item_id=item_id, item_type=item_type, command_id=command_id | |
| ) | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error( | |
| f"Error embedding {embed_request.item_type} {embed_request.item_id}: {str(e)}" | |
| ) | |
| raise HTTPException( | |
| status_code=500, detail=f"Error embedding content: {str(e)}" | |
| ) | |