Skip to content

Commit 8929d72

Browse files
authored
Structured extraction support (#14)
* Structured extraction support * Fix styling --------- Co-authored-by: avvertix <5672748+avvertix@users.noreply.github.com>
1 parent 170fad0 commit 8929d72

10 files changed

Lines changed: 530 additions & 0 deletions

src/Connectors/LibrarianConnector.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use OneOffTech\LibrarianClient\Resources\LibraryResource;
88
use OneOffTech\LibrarianClient\Resources\PromptResource;
99
use OneOffTech\LibrarianClient\Resources\QuestionResource;
10+
use OneOffTech\LibrarianClient\Resources\StructuredExtractionResource;
1011
use OneOffTech\LibrarianClient\Resources\SummaryResource;
1112
use OneOffTech\LibrarianClient\Responses\LibrarianResponse;
1213
use Saloon\Http\Auth\TokenAuthenticator;
@@ -114,4 +115,9 @@ public function classifiers(string $library_id): ClassifierResource
114115
{
115116
return new ClassifierResource($library_id, $this);
116117
}
118+
119+
public function extractions(string $library_id): StructuredExtractionResource
120+
{
121+
return new StructuredExtractionResource($library_id, $this);
122+
}
117123
}

src/Dto/Extraction.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace OneOffTech\LibrarianClient\Dto;
4+
5+
use Saloon\Contracts\DataObjects\WithResponse;
6+
use Saloon\Traits\Responses\HasResponse;
7+
8+
class Extraction implements WithResponse
9+
{
10+
use HasResponse;
11+
12+
public function __construct(
13+
public readonly array $content,
14+
) {}
15+
}

src/Dto/ResponseSchema.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace OneOffTech\LibrarianClient\Dto;
4+
5+
class ResponseSchema
6+
{
7+
public function __construct(
8+
public readonly array $schema,
9+
) {}
10+
11+
public static function fromString(string $schema): static
12+
{
13+
return new static(json_decode($schema, associative: true));
14+
}
15+
16+
public static function fromArray(array $schema): static
17+
{
18+
return new static($schema);
19+
}
20+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace OneOffTech\LibrarianClient\Requests\StructuredExtraction;
4+
5+
use OneOffTech\LibrarianClient\Dto\Document;
6+
use OneOffTech\LibrarianClient\Dto\Extraction;
7+
use OneOffTech\LibrarianClient\Dto\ResponseSchema;
8+
use Saloon\Contracts\Body\HasBody;
9+
use Saloon\Enums\Method;
10+
use Saloon\Http\Request;
11+
use Saloon\Http\Response;
12+
use Saloon\Traits\Body\HasJsonBody;
13+
14+
class ExtractRequest extends Request implements HasBody
15+
{
16+
use HasJsonBody;
17+
18+
protected Method $method = Method::POST;
19+
20+
public function __construct(
21+
protected readonly string $library_id,
22+
protected readonly Document $document,
23+
protected readonly ResponseSchema $responseSchema,
24+
protected readonly ?array $sections = null,
25+
protected readonly ?string $instructions = null,
26+
) {
27+
//
28+
}
29+
30+
public function resolveEndpoint(): string
31+
{
32+
return "/library/{$this->library_id}/structured_extract";
33+
}
34+
35+
protected function defaultBody(): array
36+
{
37+
return [
38+
'doc' => $this->document->data,
39+
'response_model' => $this->responseSchema->schema,
40+
'instructions' => $this->instructions ?? '',
41+
'sections' => $this->sections,
42+
];
43+
}
44+
45+
public function createDtoFromResponse(Response $response): Extraction
46+
{
47+
$data = $response->json();
48+
49+
return (new Extraction(
50+
content: $data,
51+
))->setResponse($response);
52+
}
53+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace OneOffTech\LibrarianClient\Resources;
4+
5+
use OneOffTech\LibrarianClient\Dto\Document;
6+
use OneOffTech\LibrarianClient\Dto\Extraction;
7+
use OneOffTech\LibrarianClient\Dto\ResponseSchema;
8+
use OneOffTech\LibrarianClient\Requests\StructuredExtraction\ExtractRequest;
9+
use Saloon\Http\BaseResource;
10+
use Saloon\Http\Connector;
11+
12+
class StructuredExtractionResource extends BaseResource
13+
{
14+
/**
15+
* Constructor
16+
*/
17+
public function __construct(
18+
readonly protected string $library_id,
19+
Connector $connector
20+
) {
21+
parent::__construct($connector);
22+
}
23+
24+
public function extract(string $structuredResponseModel, Document $from, ?array $sections = null, ?string $instructions = null): Extraction
25+
{
26+
return $this->connector->send(new ExtractRequest(
27+
library_id: $this->library_id,
28+
document: $from,
29+
responseSchema: ResponseSchema::fromString($structuredResponseModel),
30+
sections: $sections,
31+
instructions: $instructions,
32+
))
33+
->dto();
34+
}
35+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"statusCode": 200,
3+
"headers": {
4+
"content-length": "235",
5+
"content-type": "application\/json"
6+
},
7+
"data": "{\"dates\":[{\"date\":\"2025-03-22\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"},{\"date\":\"2025-04-15\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"}]}"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"statusCode": 200,
3+
"headers": {
4+
"content-length": "235",
5+
"content-type": "application\/json"
6+
},
7+
"data": "{\"dates\":[{\"date\":\"2025-03-22\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"},{\"date\":\"2025-04-15\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"}]}"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"statusCode": 200,
3+
"headers": {
4+
"content-length": "235",
5+
"content-type": "application\/json"
6+
},
7+
"data": "{\"dates\":[{\"date\":\"2025-03-22\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"},{\"date\":\"2025-04-15\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"}]}"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"statusCode": 200,
3+
"headers": {
4+
"content-length": "235",
5+
"content-type": "application\/json"
6+
},
7+
"data": "{\"dates\":[{\"date\":\"2025-03-22\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"},{\"date\":\"2025-04-15\",\"context\":\"We have some dates 22 march 2025, 15\/04\/2025 of relevance for the extraction.\"}]}"
8+
}

0 commit comments

Comments
 (0)