|
3 | 3 | import com.mindee.MindeeException; |
4 | 4 | import com.mindee.input.LocalInputSource; |
5 | 5 | import com.mindee.input.URLInputSource; |
| 6 | +import com.mindee.v2.clientoptions.BaseAnnotationParameters; |
6 | 7 | import com.mindee.v2.clientoptions.BaseProductParameters; |
| 8 | +import com.mindee.v2.clientoptions.BaseRagDocumentUploadParameters; |
7 | 9 | import com.mindee.v2.clientoptions.BaseSearchParameters; |
8 | 10 | import com.mindee.v2.clientoptions.PollingOptions; |
9 | 11 | import com.mindee.v2.http.MindeeApiV2; |
10 | 12 | import com.mindee.v2.http.MindeeHttpApiV2; |
11 | 13 | import com.mindee.v2.http.MindeeHttpExceptionV2; |
| 14 | +import com.mindee.v2.parsing.BaseRagAnnotationResponse; |
12 | 15 | import com.mindee.v2.parsing.BaseResponse; |
13 | 16 | import com.mindee.v2.parsing.JobResponse; |
14 | 17 | import com.mindee.v2.parsing.error.ErrorResponse; |
@@ -277,6 +280,230 @@ public SearchResponse searchModels(String modelName, String modelType) { |
277 | 280 | .reqGetSearch(ModelSearchParameters.builder().name(modelName).modelType(modelType).build()); |
278 | 281 | } |
279 | 282 |
|
| 283 | + /** |
| 284 | + * Not recommended for general use, prefer {@link #uploadAndGetRagDocument}. |
| 285 | + * You will need to poll until the document is ready for use. |
| 286 | + * Add a document to the RAG database. |
| 287 | + * |
| 288 | + * @param inputSource The file to upload. |
| 289 | + * @param parameters RAG document upload parameters. |
| 290 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 291 | + */ |
| 292 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadRagDocument( |
| 293 | + LocalInputSource inputSource, |
| 294 | + BaseRagDocumentUploadParameters<TAnnotationResponse> parameters |
| 295 | + ) throws IOException { |
| 296 | + logger.log(System.Logger.Level.INFO, "Adding a document to the RAG database"); |
| 297 | + return mindeeApi.reqPostRagDocument(parameters, inputSource); |
| 298 | + } |
| 299 | + |
| 300 | + /** |
| 301 | + * Add a document to the RAG database, poll, and return the initial annotation. |
| 302 | + * |
| 303 | + * @param inputSource The file to upload. |
| 304 | + * @param parameters RAG document upload parameters. |
| 305 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 306 | + */ |
| 307 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadAndGetRagDocument( |
| 308 | + LocalInputSource inputSource, |
| 309 | + BaseRagDocumentUploadParameters<TAnnotationResponse> parameters |
| 310 | + ) throws IOException, InterruptedException { |
| 311 | + return uploadAndGetRagDocument(inputSource, parameters, null); |
| 312 | + } |
| 313 | + |
| 314 | + /** |
| 315 | + * Add a document to the RAG database, poll, and return the initial annotation. |
| 316 | + * |
| 317 | + * @param inputSource The file to upload. |
| 318 | + * @param parameters RAG document upload parameters. |
| 319 | + * @param pollingOptions Polling options (if null, default options are used). |
| 320 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 321 | + */ |
| 322 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadAndGetRagDocument( |
| 323 | + LocalInputSource inputSource, |
| 324 | + BaseRagDocumentUploadParameters<TAnnotationResponse> parameters, |
| 325 | + PollingOptions pollingOptions |
| 326 | + ) throws IOException, InterruptedException { |
| 327 | + if (pollingOptions == null) { |
| 328 | + pollingOptions = PollingOptions.builder().build(); |
| 329 | + } |
| 330 | + TAnnotationResponse initialResponse = uploadRagDocument(inputSource, parameters); |
| 331 | + if (!"Processing".equals(initialResponse.getStatus())) { |
| 332 | + return initialResponse; |
| 333 | + } |
| 334 | + return pollForRagDocument(parameters.getResponseClass(), initialResponse, pollingOptions); |
| 335 | + } |
| 336 | + |
| 337 | + /** |
| 338 | + * Not recommended for general use, prefer {@link #getReadyRagDocument}. |
| 339 | + * You will need to poll until the document is ready for use. |
| 340 | + * Get a document's info and annotations from the RAG database. |
| 341 | + * |
| 342 | + * @param responseClass The class of the response. |
| 343 | + * @param documentId The document's ID. |
| 344 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 345 | + */ |
| 346 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getRagDocument( |
| 347 | + Class<TAnnotationResponse> responseClass, |
| 348 | + String documentId |
| 349 | + ) { |
| 350 | + logger.log(System.Logger.Level.INFO, "Getting RAG document ID: {0}", documentId); |
| 351 | + return mindeeApi.reqGetRagAnnotation(responseClass, documentId); |
| 352 | + } |
| 353 | + |
| 354 | + /** |
| 355 | + * Get a document's info and annotations from the RAG database, polling if it is still processing. |
| 356 | + * |
| 357 | + * @param responseClass The class of the response. |
| 358 | + * @param documentId The document's ID. |
| 359 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 360 | + */ |
| 361 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getReadyRagDocument( |
| 362 | + Class<TAnnotationResponse> responseClass, |
| 363 | + String documentId |
| 364 | + ) throws InterruptedException { |
| 365 | + return getReadyRagDocument(responseClass, documentId, null); |
| 366 | + } |
| 367 | + |
| 368 | + /** |
| 369 | + * Get a document's info and annotations from the RAG database, polling if it is still processing. |
| 370 | + * |
| 371 | + * @param responseClass The class of the response. |
| 372 | + * @param documentId The document's ID. |
| 373 | + * @param pollingOptions Polling options (if null, default options are used). |
| 374 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 375 | + */ |
| 376 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getReadyRagDocument( |
| 377 | + Class<TAnnotationResponse> responseClass, |
| 378 | + String documentId, |
| 379 | + PollingOptions pollingOptions |
| 380 | + ) throws InterruptedException { |
| 381 | + TAnnotationResponse initialResponse = getRagDocument(responseClass, documentId); |
| 382 | + if (!"Processing".equals(initialResponse.getStatus())) { |
| 383 | + return initialResponse; |
| 384 | + } |
| 385 | + |
| 386 | + if (pollingOptions == null) { |
| 387 | + pollingOptions = PollingOptions.builder().build(); |
| 388 | + } |
| 389 | + return pollForRagDocument(responseClass, initialResponse, pollingOptions); |
| 390 | + } |
| 391 | + |
| 392 | + /** |
| 393 | + * Not recommended for general use, prefer {@link #updateAndGetRagAnnotation}. |
| 394 | + * You will need to poll until the document is ready for use. |
| 395 | + * Update a document's annotations in the RAG database. |
| 396 | + * |
| 397 | + * @param parameters Annotation parameters. |
| 398 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 399 | + */ |
| 400 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateRagAnnotation( |
| 401 | + BaseAnnotationParameters<TAnnotationResponse> parameters |
| 402 | + ) { |
| 403 | + logger |
| 404 | + .log(System.Logger.Level.INFO, "Updating RAG document ID: {0}", parameters.getDocumentId()); |
| 405 | + return mindeeApi.reqPatchRagAnnotation(parameters); |
| 406 | + } |
| 407 | + |
| 408 | + /** |
| 409 | + * Update a document's annotations in the RAG database and poll until complete. |
| 410 | + * |
| 411 | + * @param parameters Annotation parameters. |
| 412 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 413 | + */ |
| 414 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateAndGetRagAnnotation( |
| 415 | + BaseAnnotationParameters<TAnnotationResponse> parameters |
| 416 | + ) throws InterruptedException { |
| 417 | + return updateAndGetRagAnnotation(parameters, null); |
| 418 | + } |
| 419 | + |
| 420 | + /** |
| 421 | + * Update a document's annotations in the RAG database and poll until complete. |
| 422 | + * |
| 423 | + * @param parameters Annotation parameters. |
| 424 | + * @param pollingOptions Polling options (if null, default options are used). |
| 425 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 426 | + */ |
| 427 | + public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateAndGetRagAnnotation( |
| 428 | + BaseAnnotationParameters<TAnnotationResponse> parameters, |
| 429 | + PollingOptions pollingOptions |
| 430 | + ) throws InterruptedException { |
| 431 | + TAnnotationResponse initialResponse = updateRagAnnotation(parameters); |
| 432 | + if (!"Processing".equals(initialResponse.getStatus())) { |
| 433 | + return initialResponse; |
| 434 | + } |
| 435 | + |
| 436 | + if (pollingOptions == null) { |
| 437 | + pollingOptions = PollingOptions.builder().build(); |
| 438 | + } |
| 439 | + return pollForRagDocument(parameters.getResponseClass(), initialResponse, pollingOptions); |
| 440 | + } |
| 441 | + |
| 442 | + /** |
| 443 | + * Delete a document from the RAG database. |
| 444 | + * For extraction models only. |
| 445 | + * |
| 446 | + * @param documentId The document's ID. |
| 447 | + * @return true if successful. |
| 448 | + */ |
| 449 | + public boolean deleteExtractionRagDocument(String documentId) { |
| 450 | + logger.log(System.Logger.Level.INFO, "Deleting RAG document ID: {0}", documentId); |
| 451 | + return mindeeApi.reqDeleteExtractionRagDocument(documentId); |
| 452 | + } |
| 453 | + |
| 454 | + /** |
| 455 | + * Poll until the RAG document is finished processing or the max number of attempts is reached. |
| 456 | + * |
| 457 | + * @param responseClass The class of the response. |
| 458 | + * @param initialResponse The initial annotation response. |
| 459 | + * @param pollingOptions Polling options. |
| 460 | + * @return an instance of {@link BaseRagAnnotationResponse}. |
| 461 | + * @throws InterruptedException Throws if the thread is interrupted. |
| 462 | + */ |
| 463 | + private <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse pollForRagDocument( |
| 464 | + Class<TAnnotationResponse> responseClass, |
| 465 | + BaseRagAnnotationResponse initialResponse, |
| 466 | + PollingOptions pollingOptions |
| 467 | + ) throws InterruptedException { |
| 468 | + logger |
| 469 | + .log(System.Logger.Level.INFO, "Polling for RAG document ID: {0}", initialResponse.getId()); |
| 470 | + int maxRetries = pollingOptions.getMaxRetries() + 1; |
| 471 | + |
| 472 | + logger |
| 473 | + .log( |
| 474 | + System.Logger.Level.DEBUG, |
| 475 | + "Waiting {0} seconds before attempting to retrieve the result...", |
| 476 | + pollingOptions.getInitialDelaySec() |
| 477 | + ); |
| 478 | + |
| 479 | + interruptibleSleep( |
| 480 | + (long) (pollingOptions.getInitialDelaySec() * 1000), |
| 481 | + pollingOptions.getCancelToken() |
| 482 | + ); |
| 483 | + |
| 484 | + String documentId = initialResponse.getId(); |
| 485 | + long intervalMillis = (long) (pollingOptions.getIntervalSec() * 1000); |
| 486 | + int retryCount = 1; |
| 487 | + |
| 488 | + while (retryCount < maxRetries) { |
| 489 | + interruptibleSleep(intervalMillis, pollingOptions.getCancelToken()); |
| 490 | + logger.log(System.Logger.Level.DEBUG, "Poll attempt {0} of {1}", retryCount, maxRetries); |
| 491 | + |
| 492 | + TAnnotationResponse response = getRagDocument(responseClass, documentId); |
| 493 | + retryCount++; |
| 494 | + |
| 495 | + String status = response.getStatus(); |
| 496 | + if ("Processing".equals(status)) { |
| 497 | + continue; |
| 498 | + } else if ("Failed".equals(status)) { |
| 499 | + throw new MindeeException("RAG failed without an error payload."); |
| 500 | + } else { |
| 501 | + return response; |
| 502 | + } |
| 503 | + } |
| 504 | + throw new MindeeException("RAG polling not complete after " + retryCount + " attempts."); |
| 505 | + } |
| 506 | + |
280 | 507 | /** |
281 | 508 | * Common logic for polling an asynchronous job for local & url files. |
282 | 509 | * |
|
0 commit comments