move the embeddings api endpoint to underneath llm

This commit is contained in:
perf3ct 2025-04-01 18:44:10 +00:00
parent b13a6ec905
commit 7ae55de8b1
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
3 changed files with 124 additions and 90 deletions

View File

@ -150,7 +150,7 @@ export default class AiSettingsWidget extends OptionsWidget {
$recreateEmbeddings.on('click', async () => { $recreateEmbeddings.on('click', async () => {
if (confirm(t("ai_llm.recreate_embeddings_confirm") || "Are you sure you want to recreate all embeddings? This may take a long time.")) { if (confirm(t("ai_llm.recreate_embeddings_confirm") || "Are you sure you want to recreate all embeddings? This may take a long time.")) {
try { try {
await server.post('embeddings/reprocess'); await server.post('llm/embeddings/reprocess');
toastService.showMessage(t("ai_llm.recreate_embeddings_started")); toastService.showMessage(t("ai_llm.recreate_embeddings_started"));
// Start progress polling // Start progress polling
@ -166,7 +166,7 @@ export default class AiSettingsWidget extends OptionsWidget {
const $rebuildIndex = this.$widget.find('.rebuild-embeddings-index'); const $rebuildIndex = this.$widget.find('.rebuild-embeddings-index');
$rebuildIndex.on('click', async () => { $rebuildIndex.on('click', async () => {
try { try {
await server.post('embeddings/rebuild-index'); await server.post('llm/embeddings/rebuild-index');
toastService.showMessage(t("ai_llm.rebuild_index_started")); toastService.showMessage(t("ai_llm.rebuild_index_started"));
// Start progress polling // Start progress polling
@ -300,7 +300,7 @@ export default class AiSettingsWidget extends OptionsWidget {
if (!this.$widget) return; if (!this.$widget) return;
try { try {
const response = await server.get<EmbeddingStats>('embeddings/stats'); const response = await server.get<EmbeddingStats>('llm/embeddings/stats');
if (response && response.success) { if (response && response.success) {
const stats = response.stats; const stats = response.stats;
@ -357,7 +357,7 @@ export default class AiSettingsWidget extends OptionsWidget {
if (!this.$widget) return; if (!this.$widget) return;
try { try {
const response = await server.get<FailedEmbeddingNotes>('embeddings/failed'); const response = await server.get<FailedEmbeddingNotes>('llm/embeddings/failed');
if (response && response.success) { if (response && response.success) {
const failedNotes = response.failedNotes || []; const failedNotes = response.failedNotes || [];
@ -412,7 +412,7 @@ export default class AiSettingsWidget extends OptionsWidget {
$failedNotesList.find('.retry-embedding').on('click', async function() { $failedNotesList.find('.retry-embedding').on('click', async function() {
const noteId = $(this).closest('tr').data('note-id'); const noteId = $(this).closest('tr').data('note-id');
try { try {
await server.post('embeddings/retry', { noteId }); await server.post('llm/embeddings/retry', { noteId });
toastService.showMessage(t("ai_llm.retry_queued")); toastService.showMessage(t("ai_llm.retry_queued"));
// Remove this row or update status // Remove this row or update status
$(this).closest('tr').remove(); $(this).closest('tr').remove();

View File

@ -9,7 +9,7 @@ import sql from "../../services/sql.js";
/** /**
* @swagger * @swagger
* /api/embeddings/similar/{noteId}: * /api/llm/embeddings/similar/{noteId}:
* get: * get:
* summary: Find similar notes based on a given note ID * summary: Find similar notes based on a given note ID
* operationId: embeddings-similar-by-note * operationId: embeddings-similar-by-note
@ -139,7 +139,7 @@ async function findSimilarNotes(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/search: * /api/llm/embeddings/search:
* post: * post:
* summary: Search for notes similar to provided text * summary: Search for notes similar to provided text
* operationId: embeddings-search-by-text * operationId: embeddings-search-by-text
@ -250,7 +250,7 @@ async function searchByText(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/providers: * /api/llm/embeddings/providers:
* get: * get:
* summary: Get available embedding providers * summary: Get available embedding providers
* operationId: embeddings-get-providers * operationId: embeddings-get-providers
@ -294,7 +294,7 @@ async function getProviders(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/providers/{providerId}: * /api/llm/embeddings/providers/{providerId}:
* patch: * patch:
* summary: Update embedding provider configuration * summary: Update embedding provider configuration
* operationId: embeddings-update-provider * operationId: embeddings-update-provider
@ -304,7 +304,7 @@ async function getProviders(req: Request, res: Response) {
* required: true * required: true
* schema: * schema:
* type: string * type: string
* description: ID of the embedding provider to update * description: Provider ID to update
* requestBody: * requestBody:
* required: true * required: true
* content: * content:
@ -312,18 +312,18 @@ async function getProviders(req: Request, res: Response) {
* schema: * schema:
* type: object * type: object
* properties: * properties:
* isEnabled: * enabled:
* type: boolean * type: boolean
* description: Whether the provider is enabled * description: Whether provider is enabled
* priority: * priority:
* type: integer * type: integer
* description: Priority level for the provider * description: Priority order (lower is higher priority)
* config: * config:
* type: object * type: object
* description: Provider-specific configuration * description: Provider-specific configuration
* responses: * responses:
* '200': * '200':
* description: Provider successfully updated * description: Provider updated successfully
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -331,8 +331,8 @@ async function getProviders(req: Request, res: Response) {
* properties: * properties:
* success: * success:
* type: boolean * type: boolean
* '404': * '400':
* description: Provider not found * description: Invalid provider ID or configuration
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -359,13 +359,29 @@ async function updateProvider(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/reprocess: * /api/llm/embeddings/reprocess:
* post: * post:
* summary: Reprocess all notes for embedding generation * summary: Reprocess embeddings for all notes
* operationId: embeddings-reprocess-all * operationId: embeddings-reprocess-all
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* providerId:
* type: string
* description: Provider ID to use for reprocessing
* modelId:
* type: string
* description: Model ID to use for reprocessing
* forceReprocess:
* type: boolean
* description: Whether to reprocess notes that already have embeddings
* responses: * responses:
* '200': * '200':
* description: Reprocessing started successfully * description: Reprocessing started
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -373,8 +389,12 @@ async function updateProvider(req: Request, res: Response) {
* properties: * properties:
* success: * success:
* type: boolean * type: boolean
* jobId:
* type: string
* message: * message:
* type: string * type: string
* '400':
* description: Invalid provider ID or configuration
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -405,10 +425,17 @@ async function reprocessAllNotes(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/queue-status: * /api/llm/embeddings/queue-status:
* get: * get:
* summary: Get status of the embedding generation queue * summary: Get status of the embedding processing queue
* operationId: embeddings-queue-status * operationId: embeddings-queue-status
* parameters:
* - name: jobId
* in: query
* required: false
* schema:
* type: string
* description: Optional job ID to get status for a specific processing job
* responses: * responses:
* '200': * '200':
* description: Queue status information * description: Queue status information
@ -420,17 +447,14 @@ async function reprocessAllNotes(req: Request, res: Response) {
* success: * success:
* type: boolean * type: boolean
* status: * status:
* type: string
* enum: [idle, processing, paused]
* progress:
* type: number
* format: float
* description: Progress percentage (0-100)
* details:
* type: object * type: object
* properties:
* queueCount:
* type: integer
* description: Number of items in the queue
* failedCount:
* type: integer
* description: Number of failed embedding attempts
* totalEmbeddingsCount:
* type: integer
* description: Total number of generated embeddings
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -461,7 +485,7 @@ async function getQueueStatus(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/stats: * /api/llm/embeddings/stats:
* get: * get:
* summary: Get embedding statistics * summary: Get embedding statistics
* operationId: embeddings-stats * operationId: embeddings-stats
@ -502,13 +526,13 @@ async function getEmbeddingStats(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/failed: * /api/llm/embeddings/failed:
* get: * get:
* summary: Get list of notes that failed embedding generation * summary: Get list of notes that failed embedding generation
* operationId: embeddings-failed-notes * operationId: embeddings-failed-notes
* responses: * responses:
* '200': * '200':
* description: List of failed embedding notes * description: List of failed notes
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -527,9 +551,7 @@ async function getEmbeddingStats(req: Request, res: Response) {
* type: string * type: string
* error: * error:
* type: string * type: string
* attempts: * failedAt:
* type: integer
* lastAttempt:
* type: string * type: string
* format: date-time * format: date-time
* security: * security:
@ -549,9 +571,9 @@ async function getFailedNotes(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/retry/{noteId}: * /api/llm/embeddings/retry/{noteId}:
* post: * post:
* summary: Retry embedding generation for a failed note * summary: Retry generating embeddings for a failed note
* operationId: embeddings-retry-note * operationId: embeddings-retry-note
* parameters: * parameters:
* - name: noteId * - name: noteId
@ -559,10 +581,22 @@ async function getFailedNotes(req: Request, res: Response) {
* required: true * required: true
* schema: * schema:
* type: string * type: string
* description: ID of the note to retry embedding * description: Note ID to retry
* - name: providerId
* in: query
* required: false
* schema:
* type: string
* description: Provider ID to use (defaults to configured default)
* - name: modelId
* in: query
* required: false
* schema:
* type: string
* description: Model ID to use (defaults to provider default)
* responses: * responses:
* '200': * '200':
* description: Retry operation result * description: Retry result
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -572,8 +606,10 @@ async function getFailedNotes(req: Request, res: Response) {
* type: boolean * type: boolean
* message: * message:
* type: string * type: string
* '400':
* description: Invalid request
* '404': * '404':
* description: Note not found or not in failed state * description: Note not found
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -605,13 +641,26 @@ async function retryFailedNote(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/retry-all-failed: * /api/llm/embeddings/retry-all-failed:
* post: * post:
* summary: Retry embedding generation for all failed notes * summary: Retry generating embeddings for all failed notes
* operationId: embeddings-retry-all-failed * operationId: embeddings-retry-all-failed
* requestBody:
* required: false
* content:
* application/json:
* schema:
* type: object
* properties:
* providerId:
* type: string
* description: Provider ID to use (defaults to configured default)
* modelId:
* type: string
* description: Model ID to use (defaults to provider default)
* responses: * responses:
* '200': * '200':
* description: Retry operation started * description: Retry started
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -621,9 +670,8 @@ async function retryFailedNote(req: Request, res: Response) {
* type: boolean * type: boolean
* message: * message:
* type: string * type: string
* count: * jobId:
* type: integer * type: string
* description: Number of notes queued for retry
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -639,26 +687,13 @@ async function retryAllFailedNotes(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/rebuild-index: * /api/llm/embeddings/rebuild-index:
* post: * post:
* summary: Rebuild the embedding vector index * summary: Rebuild the vector store index
* operationId: embeddings-rebuild-index * operationId: embeddings-rebuild-index
* requestBody:
* required: false
* content:
* application/json:
* schema:
* type: object
* properties:
* provider:
* type: string
* description: Specific provider to rebuild index for
* force:
* type: boolean
* description: Force rebuild even if not necessary
* responses: * responses:
* '200': * '200':
* description: Index rebuild operation started * description: Rebuild started
* content: * content:
* application/json: * application/json:
* schema: * schema:
@ -670,7 +705,6 @@ async function retryAllFailedNotes(req: Request, res: Response) {
* type: string * type: string
* jobId: * jobId:
* type: string * type: string
* description: ID of the rebuild job for status tracking
* security: * security:
* - session: [] * - session: []
* tags: ["llm"] * tags: ["llm"]
@ -695,7 +729,7 @@ async function rebuildIndex(req: Request, res: Response) {
/** /**
* @swagger * @swagger
* /api/embeddings/index-rebuild-status: * /api/llm/embeddings/index-rebuild-status:
* get: * get:
* summary: Get status of the vector index rebuild operation * summary: Get status of the vector index rebuild operation
* operationId: embeddings-rebuild-status * operationId: embeddings-rebuild-status

View File

@ -391,20 +391,6 @@ function register(app: express.Application) {
etapiSpecRoute.register(router); etapiSpecRoute.register(router);
etapiBackupRoute.register(router); etapiBackupRoute.register(router);
// Embeddings API endpoints
apiRoute(GET, "/api/embeddings/similar/:noteId", embeddingsRoute.findSimilarNotes);
apiRoute(PST, "/api/embeddings/search", embeddingsRoute.searchByText);
apiRoute(GET, "/api/embeddings/providers", embeddingsRoute.getProviders);
apiRoute(PATCH, "/api/embeddings/providers/:providerId", embeddingsRoute.updateProvider);
apiRoute(PST, "/api/embeddings/reprocess", embeddingsRoute.reprocessAllNotes);
apiRoute(GET, "/api/embeddings/queue-status", embeddingsRoute.getQueueStatus);
apiRoute(GET, "/api/embeddings/stats", embeddingsRoute.getEmbeddingStats);
apiRoute(GET, "/api/embeddings/failed", embeddingsRoute.getFailedNotes);
apiRoute(PST, "/api/embeddings/retry/:noteId", embeddingsRoute.retryFailedNote);
apiRoute(PST, "/api/embeddings/retry-all-failed", embeddingsRoute.retryAllFailedNotes);
apiRoute(PST, "/api/embeddings/rebuild-index", embeddingsRoute.rebuildIndex);
apiRoute(GET, "/api/embeddings/index-rebuild-status", embeddingsRoute.getIndexRebuildStatus);
// LLM chat session management endpoints // LLM chat session management endpoints
apiRoute(PST, "/api/llm/sessions", llmRoute.createSession); apiRoute(PST, "/api/llm/sessions", llmRoute.createSession);
apiRoute(GET, "/api/llm/sessions", llmRoute.listSessions); apiRoute(GET, "/api/llm/sessions", llmRoute.listSessions);
@ -424,6 +410,20 @@ function register(app: express.Application) {
apiRoute(GET, "/api/llm/indexes/context", llmRoute.generateQueryContext); // Get context apiRoute(GET, "/api/llm/indexes/context", llmRoute.generateQueryContext); // Get context
apiRoute(PST, "/api/llm/indexes/notes/:noteId", llmRoute.indexNote); // Create index for specific note apiRoute(PST, "/api/llm/indexes/notes/:noteId", llmRoute.indexNote); // Create index for specific note
// LLM embeddings endpoints
apiRoute(GET, "/api/llm/embeddings/similar/:noteId", embeddingsRoute.findSimilarNotes);
apiRoute(PST, "/api/llm/embeddings/search", embeddingsRoute.searchByText);
apiRoute(GET, "/api/llm/embeddings/providers", embeddingsRoute.getProviders);
apiRoute(PATCH, "/api/llm/embeddings/providers/:providerId", embeddingsRoute.updateProvider);
apiRoute(PST, "/api/llm/embeddings/reprocess", embeddingsRoute.reprocessAllNotes);
apiRoute(GET, "/api/llm/embeddings/queue-status", embeddingsRoute.getQueueStatus);
apiRoute(GET, "/api/llm/embeddings/stats", embeddingsRoute.getEmbeddingStats);
apiRoute(GET, "/api/llm/embeddings/failed", embeddingsRoute.getFailedNotes);
apiRoute(PST, "/api/llm/embeddings/retry/:noteId", embeddingsRoute.retryFailedNote);
apiRoute(PST, "/api/llm/embeddings/retry-all-failed", embeddingsRoute.retryAllFailedNotes);
apiRoute(PST, "/api/llm/embeddings/rebuild-index", embeddingsRoute.rebuildIndex);
apiRoute(GET, "/api/llm/embeddings/index-rebuild-status", embeddingsRoute.getIndexRebuildStatus);
// LLM provider endpoints - moved under /api/llm/providers hierarchy // LLM provider endpoints - moved under /api/llm/providers hierarchy
apiRoute(GET, "/api/llm/providers/ollama/models", ollamaRoute.listModels); apiRoute(GET, "/api/llm/providers/ollama/models", ollamaRoute.listModels);
apiRoute(GET, "/api/llm/providers/openai/models", openaiRoute.listModels); apiRoute(GET, "/api/llm/providers/openai/models", openaiRoute.listModels);