diff --git a/DSL/Liquibase/changelog/20260907120000_add-llm-index-status-to-services.xml b/DSL/Liquibase/changelog/20260907120000_add-llm-index-status-to-services.xml new file mode 100644 index 000000000..e94aa6bbe --- /dev/null +++ b/DSL/Liquibase/changelog/20260907120000_add-llm-index-status-to-services.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/DSL/Liquibase/changelog/migrations/20260907120000_add-llm-index-status-to-services.sql b/DSL/Liquibase/changelog/migrations/20260907120000_add-llm-index-status-to-services.sql new file mode 100644 index 000000000..10628e987 --- /dev/null +++ b/DSL/Liquibase/changelog/migrations/20260907120000_add-llm-index-status-to-services.sql @@ -0,0 +1,4 @@ +-- liquibase formatted sql + +ALTER TABLE services + ADD COLUMN llm_index_status llm_index_status DEFAULT NULL; diff --git a/DSL/Liquibase/changelog/migrations/rollback/20260907120000_add-llm-index-status-to-services_rollback.sql b/DSL/Liquibase/changelog/migrations/rollback/20260907120000_add-llm-index-status-to-services_rollback.sql new file mode 100644 index 000000000..4b7137d11 --- /dev/null +++ b/DSL/Liquibase/changelog/migrations/rollback/20260907120000_add-llm-index-status-to-services_rollback.sql @@ -0,0 +1,5 @@ +-- liquibase formatted sql +-- rollback + +ALTER TABLE services + DROP COLUMN llm_index_status; diff --git a/DSL/Resql/services/POST/services/update_service_llm_sync_status.sql b/DSL/Resql/services/POST/services/update_service_llm_sync_status.sql new file mode 100644 index 000000000..dec78460e --- /dev/null +++ b/DSL/Resql/services/POST/services/update_service_llm_sync_status.sql @@ -0,0 +1,3 @@ +UPDATE services +SET llm_index_status = :status::llm_index_status +WHERE service_id = :serviceId; diff --git a/DSL/Ruuter/services/POST/services/reindex-service.yml b/DSL/Ruuter/services/POST/services/reindex-service.yml new file mode 100644 index 000000000..c49e22913 --- /dev/null +++ b/DSL/Ruuter/services/POST/services/reindex-service.yml @@ -0,0 +1,110 @@ +declaration: + call: declare + version: 0.1 + description: "Wrapper for manual re-index triggered from the UI. Fetches the service, validates it's active, then calls service-index-llm as a sub-flow and handles crashes (e.g. LLM service unreachable) by writing FAILED to the DB" + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: serviceId + type: string + description: "Service UUID to re-index" + headers: + - field: cookie + type: string + description: "Cookie field" + +assign_id: + assign: + serviceId: ${incoming.body.serviceId} + +check_required: + switch: + - condition: ${serviceId == null || serviceId === ''} + next: return_bad_request + +fetch_service: + call: http.post + args: + url: "[#SERVICE_RESQL]/get-service-by-id" + body: + id: ${serviceId} + result: service_result + +check_service_found: + switch: + - condition: ${service_result.response.body == null || service_result.response.body.length === 0} + next: return_not_found + +assign_service: + assign: + service: ${service_result.response.body[0]} + +check_service_active: + switch: + - condition: ${service.state !== 'active'} + next: return_not_active + +call_index_llm: + call: http.post + args: + url: "[#SERVICE_RUUTER]/services/service-index-llm" + headers: + cookie: ${incoming.headers.cookie} + body: + serviceId: ${serviceId} + name: ${service.name} + description: ${service.description} + examples: ${service.examples} + entities: ${service.entities} + type: ${service.type} + state: ${service.state} + isCommon: ${service.isCommon} + result: index_llm_result + +check_index_llm_result: + switch: + - condition: ${index_llm_result != null && index_llm_result.response != null && 200 <= index_llm_result.response.statusCodeValue && index_llm_result.response.statusCodeValue < 300} + next: return_ok + next: mark_llm_sync_failed + +mark_llm_sync_failed: + call: http.post + args: + url: "[#SERVICE_RESQL]/services/update_service_llm_sync_status" + body: + serviceId: ${serviceId} + status: FAILED + result: update_sync_res + next: log_reindex_failure + +log_reindex_failure: + log: "Re-index failed for service ${serviceId}" + next: return_failed + +return_ok: + status: 200 + return: "Service re-indexed started" + next: end + +return_failed: + status: 500 + return: "Re-index failed" + next: end + +return_not_found: + status: 404 + return: "Service not found, re-index skipped" + next: end + +return_not_active: + status: 400 + return: "Service is not active, LLM indexing skipped" + next: end + +return_bad_request: + status: 400 + return: "serviceId is required" + next: end diff --git a/DSL/Ruuter/services/POST/services/service-index-llm.yml b/DSL/Ruuter/services/POST/services/service-index-llm.yml new file mode 100644 index 000000000..96925f813 --- /dev/null +++ b/DSL/Ruuter/services/POST/services/service-index-llm.yml @@ -0,0 +1,116 @@ +declaration: + call: declare + version: 0.1 + description: "Triggers LLM service enriching for a service. Used by manual re-index and service activation flow." + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: serviceId + type: string + description: "Service UUID to index" + - field: name + type: string + description: "Service name" + - field: description + type: string + description: "Service description" + - field: examples + type: array + description: "Example queries" + - field: entities + type: array + description: "Expected entity names" + - field: type + type: string + description: "HTTP method (GET/POST)" + - field: state + type: string + description: "Service state (active/inactive/draft)" + - field: isCommon + type: boolean + description: "Is common service" + headers: + - field: cookie + type: string + description: "Cookie field" + +assign_id: + assign: + serviceId: ${incoming.body.serviceId} + +check_required: + switch: + - condition: ${serviceId == null || serviceId === ''} + next: return_bad_request + +mark_in_progress: + call: http.post + args: + url: "[#SERVICE_RESQL]/services/update_service_llm_sync_status" + body: + serviceId: ${serviceId} + status: IN_PROGRESS + result: in_progress_res + +call_llm_enrich: + call: http.post + args: + url: "[#LLM_RUUTER_PUBLIC]/services/enrich" + body: + service_id: ${serviceId} + name: ${incoming.body.name} + description: ${incoming.body.description} + examples: ${incoming.body.examples} + entities: ${incoming.body.entities} + ruuter_type: ${incoming.body.type} + current_state: ${incoming.body.state} + is_common: ${incoming.body.isCommon} + result: llm_enrich_result + +check_llm_enrich_result: + switch: + - condition: ${llm_enrich_result != null && llm_enrich_result.response != null && 200 <= llm_enrich_result.response.statusCodeValue && llm_enrich_result.response.statusCodeValue < 300 && llm_enrich_result.response.body.response.success === true} + next: mark_indexed + next: mark_failed_llm_call + +mark_indexed: + call: http.post + args: + url: "[#SERVICE_RESQL]/services/update_service_llm_sync_status" + body: + serviceId: ${serviceId} + status: SUCCESS + result: update_res + next: return_ok + +mark_failed_llm_call: + call: http.post + args: + url: "[#SERVICE_RESQL]/services/update_service_llm_sync_status" + body: + serviceId: ${serviceId} + status: FAILED + result: update_res + next: log_llm_failure + +log_llm_failure: + log: "LLM indexing failed for service ${serviceId}" + next: return_failed + +return_ok: + status: 200 + return: "Service enrichment job queued successfully. Processing asynchronously." + next: end + +return_failed: + status: 500 + return: "LLM indexing failed" + next: end + +return_bad_request: + status: 400 + return: "serviceId is required" + next: end diff --git a/DSL/Ruuter/services/POST/services/status.yml b/DSL/Ruuter/services/POST/services/status.yml index 115ce7ba7..2acb7b637 100644 --- a/DSL/Ruuter/services/POST/services/status.yml +++ b/DSL/Ruuter/services/POST/services/status.yml @@ -200,21 +200,23 @@ activate_all_mcq_services: keyword: "${name}_mcq_" format: "yml" result: active_move_results - next: call_llm_enrich + next: call_llm_index -call_llm_enrich: +call_llm_index: call: http.post args: - url: "[#LLM_RUUTER_PUBLIC]/services/enrich" + url: "[#SERVICE_RUUTER]/services/service-index-llm" + headers: + cookie: ${incoming.headers.cookie} body: - service_id: ${id} + serviceId: ${id} name: ${name} description: ${service_data_result.response.body[0].description} examples: ${service_data_result.response.body[0].examples} entities: ${service_data_result.response.body[0].entities} - ruuter_type: ${ruuter_type} - current_state: ${new_state} - is_common: ${service_data_result.response.body[0].isCommon} + type: ${ruuter_type} + state: ${new_state} + isCommon: ${service_data_result.response.body[0].isCommon} result: llm_enrich_result error: llm_enrich_error next: return_ok