Skip to content

Commit 765ce19

Browse files
✨ add rag metadata
1 parent 7ff8739 commit 765ce19

9 files changed

Lines changed: 109 additions & 32 deletions

File tree

src/Error/ErrorItem.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ class ErrorItem
1717
public string $detail;
1818

1919
/**
20-
* @param string $detail Explicit information on the issue.
21-
* @param string|null $pointer A JSON Pointer to the location of the body property.
20+
* @param array $rawResponse Raw error response from the API.
2221
*/
23-
public function __construct(string $detail, ?string $pointer = null)
22+
public function __construct(array $rawResponse)
2423
{
25-
$this->detail = $detail;
26-
$this->pointer = $pointer;
24+
$this->detail = $rawResponse['detail'];
25+
$this->pointer = $rawResponse['pointer'];
2726
}
2827
}

src/Error/MindeeV2HttpException.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class MindeeV2HttpException extends MindeeException
2626
* Note: PHP's `RuntimeException` class uses `$code` for the error code.
2727
*/
2828
public ?string $errorCode;
29+
/**
30+
* @var array List of associated errors.
31+
*/
32+
public array $errors;
2933

3034
/**
3135
* @param ErrorResponse $response Server Error response.
@@ -37,5 +41,6 @@ public function __construct(ErrorResponse $response)
3741
$this->detail = $response->detail;
3842
$this->errorCode = $response->code;
3943
$this->title = $response->title;
44+
$this->errors = $response->errors;
4045
}
4146
}

src/Input/LocalResponse.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function isValidHMACSignature(string $secretKey, string $signature): bool
125125
* @return mixed An instance of responseClass populated with the file content.
126126
* @throws MindeeException If the provided class cannot be instantiated.
127127
*/
128-
public function deserializeResponse(string $responseClass)
128+
public function deserializeResponse(string $responseClass): mixed
129129
{
130130
try {
131131
$data = $this->toArray();

src/Parsing/V2/InferenceResult.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class InferenceResult
1919
*/
2020
public ?RawText $rawText;
2121

22+
/**
23+
* @var RagMetadata|null RAG metadata.
24+
*/
25+
public ?RagMetadata $rag;
26+
2227
/**
2328
* @param array $serverResponse Raw server response array.
2429
*/
@@ -28,6 +33,9 @@ public function __construct(array $serverResponse)
2833
$this->rawText = isset($serverResponse['raw_text'])
2934
? new RawText($serverResponse['raw_text'])
3035
: null;
36+
$this->rag = isset(
37+
$serverResponse['rag']
38+
) ? new RagMetadata($serverResponse['rag']) : null;
3139
}
3240

3341
/**

src/Parsing/V2/RagMetadata.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Mindee\Parsing\V2;
4+
5+
/**
6+
* Metadata about the RAG operation.
7+
*/
8+
class RagMetadata
9+
{
10+
/**
11+
* @var string|null ID of the matched document, if present.
12+
*/
13+
public ?string $retrievedDocumentId;
14+
15+
/**
16+
* @param array $rawResponse Raw response from the server.
17+
*/
18+
public function __construct(array $rawResponse)
19+
{
20+
$this->retrievedDocumentId = $rawResponse['retrieved_document_id'] ?? null;
21+
}
22+
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
namespace V2;
4+
35
use Mindee\ClientV2;
46
use Mindee\Http\MindeeApiV2;
57
use Mindee\Input\InferenceParameters;
@@ -11,7 +13,6 @@
1113
use PHPUnit\Framework\MockObject\MockObject;
1214
use PHPUnit\Framework\TestCase;
1315

14-
1516
class ClientV2Test extends TestCase
1617
{
1718
private static function makeClientWithMockedApi(MindeeApiV2 $mockedApi): ClientV2
@@ -27,7 +28,7 @@ private static function makeClientWithMockedApi(MindeeApiV2 $mockedApi): ClientV
2728
public function testEnqueuePostAsync(): void
2829
{
2930
$predictable = $this->createMock(MindeeApiV2::class);
30-
$syntheticResponse = file_get_contents(__DIR__ . '/resources/v2/job/ok_processing.json');
31+
$syntheticResponse = file_get_contents(\TestingUtilities::getV2DataDir() . '/job/ok_processing.json');
3132
$predictable->expects($this->once())
3233
->method('reqPostInferenceEnqueue')
3334
->with(
@@ -38,7 +39,7 @@ public function testEnqueuePostAsync(): void
3839

3940
$mindeeClient = self::makeClientWithMockedApi($predictable);
4041

41-
$input = new PathInput(__DIR__ . '/resources/file_types/pdf/blank_1.pdf');
42+
$input = new PathInput(\TestingUtilities::getFileTypesDir() . '/pdf/blank_1.pdf');
4243
$params = new InferenceParameters('dummy-model-id');
4344

4445
$response = $mindeeClient->enqueueInference($input, $params);
@@ -52,7 +53,7 @@ public function testDocumentGetJobAsync(): void
5253
/** @var MindeeApiV2&MockObject $predictable */
5354
$predictable = $this->createMock(MindeeApiV2::class);
5455

55-
$syntheticResponse = file_get_contents(__DIR__ . '/resources/v2/job/ok_processing.json');
56+
$syntheticResponse = file_get_contents(\TestingUtilities::getV2DataDir() . '/job/ok_processing.json');
5657
$processing = new JobResponse(json_decode($syntheticResponse, true));
5758

5859
$predictable->expects($this->once())
@@ -73,7 +74,7 @@ public function testDocumentGetInferenceAsync(): void
7374
/** @var MindeeApiV2&MockObject $predictable */
7475
$predictable = $this->createMock(MindeeApiV2::class);
7576

76-
$jsonFile = __DIR__ . '/resources/v2/products/financial_document/complete.json';
77+
$jsonFile = \TestingUtilities::getV2DataDir() . '/products/financial_document/complete.json';
7778
$this->assertFileExists($jsonFile, 'Test resource file must exist');
7879

7980
$json = json_decode(file_get_contents($jsonFile), true);
@@ -108,7 +109,7 @@ public function testDocumentGetInferenceAsync(): void
108109

109110
public function testInferenceLoadsLocally(): void
110111
{
111-
$jsonFile = __DIR__ . '/resources/v2/products/financial_document/complete.json';
112+
$jsonFile = \TestingUtilities::getV2DataDir() . '/products/financial_document/complete.json';
112113
$this->assertFileExists($jsonFile, 'Test resource file must exist');
113114

114115
$localResponse = new LocalResponse($jsonFile);
Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
21
<?php
32

3+
namespace V2;
4+
45
use Mindee\ClientV2;
56
use Mindee\Error\MindeeV2HttpException;
67
use Mindee\Input\InferenceParameters;
@@ -23,7 +24,7 @@ protected function setUp(): void
2324

2425
public function testParseFileEmptyMultiPageMustSucceed(): void
2526
{
26-
$source = new PathInput(__DIR__ . '/resources/file_types/pdf/multipage_cut-2.pdf');
27+
$source = new PathInput(\TestingUtilities::getFileTypesDir() . '/pdf/multipage_cut-2.pdf');
2728
$inferenceParams = new InferenceParameters($this->modelId, rag: false, rawText: true);
2829

2930
$response = $this->mindeeClient->enqueueAndGetInference($source, $inferenceParams);
@@ -92,22 +93,30 @@ public function testParseFileFilledSinglePageMustSucceed(): void
9293

9394
public function testInvalidModelMustThrowError(): void
9495
{
95-
$source = new PathInput(__DIR__ . '/resources/file_types/pdf/multipage_cut-2.pdf');
96+
$source = new PathInput(\TestingUtilities::getFileTypesDir() . '/pdf/multipage_cut-2.pdf');
9697

9798
$inferenceParams = new InferenceParameters('INVALID MODEL ID');
9899

99-
$this->expectException(MindeeV2HttpException::class);
100-
$this->expectExceptionMessage('422');
101-
102-
$this->mindeeClient->enqueueInference($source, $inferenceParams);
100+
try {
101+
$this->mindeeClient->enqueueInference($source, $inferenceParams);
102+
} catch (MindeeV2HttpException $e) {
103+
$this->assertEquals(404, $e->getCode());
104+
$this->assertStringStartsWith('404-', $e->errorCode);
105+
$this->assertNotEmpty($e->title);
106+
$this->assertIsArray($e->errors);
107+
}
103108
}
104109

105110
public function testInvalidJobMustThrowError(): void
106111
{
107-
$this->expectException(MindeeV2HttpException::class);
108-
$this->expectExceptionMessage('422');
109-
110-
$this->mindeeClient->getInference('not-a-valid-job-ID');
112+
try {
113+
$this->mindeeClient->getInference('not-a-valid-job-ID');
114+
} catch (MindeeV2HttpException $e) {
115+
$this->assertEquals(422, $e->getCode());
116+
$this->assertStringStartsWith('422-', $e->errorCode);
117+
$this->assertNotEmpty($e->title);
118+
$this->assertIsArray($e->errors);
119+
}
111120
}
112121

113122
public function testUrlInputSourceMustNotRaiseErrors(): void

tests/V2/InferenceTest.php renamed to tests/V2/Parsing/InferenceResponseTest.php

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
<?php
22

3-
namespace V2;
3+
namespace V2\parsing;
44

5+
use Mindee\Error\ErrorItem;
56
use Mindee\Geometry\Point;
67
use Mindee\Input\LocalResponse;
8+
use Mindee\Parsing\V2\ErrorResponse;
79
use Mindee\Parsing\V2\Field\FieldConfidence;
810
use Mindee\Parsing\V2\Field\ListField;
911
use Mindee\Parsing\V2\Field\ObjectField;
1012
use Mindee\Parsing\V2\Field\SimpleField;
1113
use Mindee\Parsing\V2\InferenceResponse;
14+
use Mindee\Parsing\V2\JobResponse;
1215
use PHPUnit\Framework\TestCase;
1316
use TestingUtilities;
1417

15-
require_once(__DIR__ . "/../TestingUtilities.php");
18+
require_once(__DIR__ . "/../../TestingUtilities.php");
1619

1720
/**
1821
* InferenceV2 – field integrity checks
1922
*/
20-
class InferenceTest extends TestCase
23+
class InferenceResponseTest extends TestCase
2124
{
2225
private function loadFromResource(string $resourcePath): InferenceResponse
2326
{
@@ -30,10 +33,9 @@ private function loadFromResource(string $resourcePath): InferenceResponse
3033

3134
private function readFileAsString(string $path): string
3235
{
33-
$fullPath = TestingUtilities::getRootDataDir() . $path;
34-
$this->assertFileExists($fullPath, "Resource file must exist: $path");
36+
$this->assertFileExists($path, "Resource file must exist: $path");
3537

36-
return file_get_contents($fullPath);
38+
return file_get_contents($path);
3739
}
3840

3941
/**
@@ -292,7 +294,7 @@ public function testRawTextsMustBeAccessible(): void
292294
$this->assertEquals('This is the raw text of the first page...', $first->content);
293295

294296
foreach ($rawText->pages as $page) {
295-
$this->assertEquals('string', gettype($page->content));
297+
$this->assertIsString($page->content);
296298
}
297299
}
298300

@@ -301,8 +303,10 @@ public function testRawTextsMustBeAccessible(): void
301303
*/
302304
public function testRstDisplayMustBeAccessible(): void
303305
{
304-
$response = $this->loadFromResource('/v2/inference/standard_field_types.json');
305-
$expectedRst = $this->readFileAsString('/v2/inference/standard_field_types.rst');
306+
$response = $this->loadFromResource('v2/inference/standard_field_types.json');
307+
$expectedRst = $this->readFileAsString(
308+
\TestingUtilities::getV2DataDir() . '/inference/standard_field_types.rst'
309+
);
306310
$inference = $response->inference;
307311
$this->assertNotNull($inference);
308312
$this->assertEquals($expectedRst, strval($response->inference));
@@ -358,4 +362,32 @@ public function testCoordinatesAndLocationDataMustBeAccessible(): void
358362
$this->assertTrue(FieldConfidence::Low->lt($dateField->confidence));
359363
$this->assertEquals('Medium', $dateField->confidence->value);
360364
}
365+
366+
public function testRagMetadataWhenMatched()
367+
{
368+
$response = $this->loadFromResource('v2/inference/rag_matched.json');
369+
$inference = $response->inference;
370+
$this->assertNotNull($inference);
371+
$this->assertEquals('12345abc-1234-1234-1234-123456789abc', $inference->result->rag->retrievedDocumentId);
372+
}
373+
374+
public function testRagMetadataWhenNotMatched()
375+
{
376+
$response = $this->loadFromResource('v2/inference/rag_not_matched.json');
377+
$inference = $response->inference;
378+
$this->assertNotNull($inference);
379+
$this->assertNull($inference->result->rag->retrievedDocumentId);
380+
}
381+
382+
public function testShouldLoadWith422Error()
383+
{
384+
$jsonResponse = json_decode(file_get_contents(\TestingUtilities::getV2DataDir() . '/job/fail_422.json'), true);
385+
$response = new JobResponse($jsonResponse);
386+
$this->assertNotNull($response->job);
387+
$this->assertInstanceOf(ErrorResponse::class, $response->job->error);
388+
$this->assertEquals(422, $response->job->error->status);
389+
$this->assertStringStartsWith("422-", $response->job->error->code);
390+
$this->assertEquals(1, count($response->job->error->errors));
391+
$this->assertInstanceOf(ErrorItem::class, $response->job->error->errors[0]);
392+
}
361393
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php

0 commit comments

Comments
 (0)