Skip to content

Commit bd353a4

Browse files
authored
Merge pull request #8 from ilyachase/feat/move-stop-reason
Feat/move stop reason
2 parents 79c18a8 + 62ff5df commit bd353a4

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"autoload-dev": {
2222
"psr-4": {
23-
"LLM\\Tests\\": "tests/src"
23+
"LLM\\Tests\\": "tests/"
2424
}
2525
},
2626
"config": {

src/Parsers/ChatResponseParser.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use LLM\Agents\OpenAI\Client\Exception\RateLimitException;
1010
use LLM\Agents\OpenAI\Client\Exception\TimeoutException;
1111
use LLM\Agents\OpenAI\Client\StreamChunkCallbackInterface;
12-
use LLM\Agents\LLM\Response\FinishReason;
1312
use LLM\Agents\LLM\Response\Response;
1413
use LLM\Agents\LLM\Response\StreamChatResponse;
1514
use LLM\Agents\LLM\Response\ToolCall;

src/Parsers/FinishReason.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\OpenAI\Client\Parsers;
6+
7+
enum FinishReason: string
8+
{
9+
case Stop = 'stop';
10+
case ToolCalls = 'tool_calls';
11+
case Limit = 'limit';
12+
case Timeout = 'timeout';
13+
case Length = 'length';
14+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Tests\Parsers;
6+
7+
use ArrayIterator;
8+
use LLM\Agents\OpenAI\Client\Parsers\ChatResponseParser;
9+
use OpenAI\Contracts\ResponseStreamContract;
10+
use PHPUnit\Framework\TestCase;
11+
use Psr\EventDispatcher\EventDispatcherInterface;
12+
use ReflectionClass;
13+
use Traversable;
14+
use OpenAI\Responses\Chat\CreateStreamedResponseDelta;
15+
use OpenAI\Responses\Chat\CreateStreamedResponseChoice;
16+
use OpenAI\Responses\Chat\CreateStreamedResponse;
17+
18+
class ChatResponseParserTest extends TestCase
19+
{
20+
private function makeDelta(?string $content): object
21+
{
22+
$toolCalls = [];
23+
$deltaClass = new ReflectionClass(CreateStreamedResponseDelta::class);
24+
$delta = $deltaClass->newInstanceWithoutConstructor();
25+
$deltaClass->getProperty('content')->setValue($delta, $content);
26+
$deltaClass->getProperty('role')->setValue($delta, null);
27+
$deltaClass->getProperty('toolCalls')->setValue($delta, $toolCalls);
28+
return $delta;
29+
}
30+
31+
private function makeChoice(object $delta, $finishReason = null): object
32+
{
33+
$choiceClass = new ReflectionClass(CreateStreamedResponseChoice::class);
34+
$choice = $choiceClass->newInstanceWithoutConstructor();
35+
$choiceClass->getProperty('delta')->setValue($choice, $delta);
36+
$choiceClass->getProperty('finishReason')->setValue($choice, $finishReason);
37+
return $choice;
38+
}
39+
40+
private function makeChunk(array $choices): object
41+
{
42+
$chunkClass = new ReflectionClass(CreateStreamedResponse::class);
43+
$chunk = $chunkClass->newInstanceWithoutConstructor();
44+
$chunkClass->getProperty('choices')->setValue($chunk, $choices);
45+
return $chunk;
46+
}
47+
48+
private function makeStream(array $chunks): object
49+
{
50+
return new class($chunks) implements ResponseStreamContract {
51+
private array $chunks;
52+
public function __construct(array $chunks) { $this->chunks = $chunks; }
53+
public function getIterator(): Traversable { return new ArrayIterator($this->chunks); }
54+
};
55+
}
56+
57+
public function test_parse_with_mock_stream_contract_returns_expected_response(): void
58+
{
59+
$chunk1 = $this->makeChunk([
60+
$this->makeChoice($this->makeDelta('Hello, world!'))
61+
]);
62+
$chunk2 = $this->makeChunk([
63+
$this->makeChoice($this->makeDelta(null), 'stop')
64+
]);
65+
$mockStream = $this->makeStream([$chunk1, $chunk2]);
66+
67+
$mockDispatcher = $this->createMock(EventDispatcherInterface::class);
68+
$parser = new ChatResponseParser($mockDispatcher);
69+
$result = $parser->parse($mockStream);
70+
71+
$this->assertSame('Hello, world!', $result->content);
72+
$this->assertSame('stop', $result->finishReason);
73+
}
74+
}

0 commit comments

Comments
 (0)