mirror of
https://github.com/symfony/ai-scaleway-platform.git
synced 2026-03-23 23:32:07 +01:00
[Platform] Extract duplicated completions conversion methods into CompletionsConversionTrait
This commit is contained in:
committed by
Christopher Hertel
parent
5b38eea9bf
commit
3f18dd3e83
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\AI\Platform\Bridge\Scaleway\Llm;
|
||||
|
||||
use Symfony\AI\Platform\Bridge\Generic\Completions\CompletionsConversionTrait;
|
||||
use Symfony\AI\Platform\Bridge\Scaleway\Scaleway;
|
||||
use Symfony\AI\Platform\Exception\ContentFilterException;
|
||||
use Symfony\AI\Platform\Exception\RuntimeException;
|
||||
@@ -19,9 +20,6 @@ use Symfony\AI\Platform\Result\ChoiceResult;
|
||||
use Symfony\AI\Platform\Result\RawResultInterface;
|
||||
use Symfony\AI\Platform\Result\ResultInterface;
|
||||
use Symfony\AI\Platform\Result\StreamResult;
|
||||
use Symfony\AI\Platform\Result\TextResult;
|
||||
use Symfony\AI\Platform\Result\ToolCall;
|
||||
use Symfony\AI\Platform\Result\ToolCallResult;
|
||||
use Symfony\AI\Platform\ResultConverterInterface;
|
||||
|
||||
/**
|
||||
@@ -29,6 +27,8 @@ use Symfony\AI\Platform\ResultConverterInterface;
|
||||
*/
|
||||
final class ResultConverter implements ResultConverterInterface
|
||||
{
|
||||
use CompletionsConversionTrait;
|
||||
|
||||
public function supports(Model $model): bool
|
||||
{
|
||||
return $model instanceof Scaleway;
|
||||
@@ -58,119 +58,4 @@ final class ResultConverter implements ResultConverterInterface
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private function convertStream(RawResultInterface $result): \Generator
|
||||
{
|
||||
$toolCalls = [];
|
||||
foreach ($result->getDataStream() as $data) {
|
||||
if ($this->streamIsToolCall($data)) {
|
||||
$toolCalls = $this->convertStreamToToolCalls($toolCalls, $data);
|
||||
}
|
||||
|
||||
if ([] !== $toolCalls && $this->isToolCallsStreamFinished($data)) {
|
||||
yield new ToolCallResult(...array_map($this->convertToolCall(...), $toolCalls));
|
||||
}
|
||||
|
||||
if (!isset($data['choices'][0]['delta']['content'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $data['choices'][0]['delta']['content'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $toolCalls
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function convertStreamToToolCalls(array $toolCalls, array $data): array
|
||||
{
|
||||
if (!isset($data['choices'][0]['delta']['tool_calls'])) {
|
||||
return $toolCalls;
|
||||
}
|
||||
|
||||
foreach ($data['choices'][0]['delta']['tool_calls'] as $i => $toolCall) {
|
||||
if (isset($toolCall['id'])) {
|
||||
// initialize tool call
|
||||
$toolCalls[$i] = [
|
||||
'id' => $toolCall['id'],
|
||||
'function' => $toolCall['function'],
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
// add arguments delta to tool call
|
||||
$toolCalls[$i]['function']['arguments'] .= $toolCall['function']['arguments'];
|
||||
}
|
||||
|
||||
return $toolCalls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
private function streamIsToolCall(array $data): bool
|
||||
{
|
||||
return isset($data['choices'][0]['delta']['tool_calls']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
private function isToolCallsStreamFinished(array $data): bool
|
||||
{
|
||||
return isset($data['choices'][0]['finish_reason']) && 'tool_calls' === $data['choices'][0]['finish_reason'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* index: int,
|
||||
* message: array{
|
||||
* role: 'assistant',
|
||||
* content: ?string,
|
||||
* tool_calls: array{
|
||||
* id: string,
|
||||
* type: 'function',
|
||||
* function: array{
|
||||
* name: string,
|
||||
* arguments: string
|
||||
* },
|
||||
* },
|
||||
* refusal: ?mixed
|
||||
* },
|
||||
* logprobs: string,
|
||||
* finish_reason: 'stop'|'length'|'tool_calls'|'content_filter',
|
||||
* } $choice
|
||||
*/
|
||||
private function convertChoice(array $choice): ToolCallResult|TextResult
|
||||
{
|
||||
if ('tool_calls' === $choice['finish_reason']) {
|
||||
return new ToolCallResult(...array_map([$this, 'convertToolCall'], $choice['message']['tool_calls']));
|
||||
}
|
||||
|
||||
if (\in_array($choice['finish_reason'], ['stop', 'length'], true)) {
|
||||
return new TextResult($choice['message']['content']);
|
||||
}
|
||||
|
||||
throw new RuntimeException(\sprintf('Unsupported finish reason "%s".', $choice['finish_reason']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* id: string,
|
||||
* type: 'function',
|
||||
* function: array{
|
||||
* name: string,
|
||||
* arguments: string
|
||||
* }
|
||||
* } $toolCall
|
||||
*/
|
||||
private function convertToolCall(array $toolCall): ToolCall
|
||||
{
|
||||
$arguments = json_decode($toolCall['function']['arguments'], true, flags: \JSON_THROW_ON_ERROR);
|
||||
|
||||
return new ToolCall($toolCall['id'], $toolCall['function']['name'], $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-generic-platform": "^0.6",
|
||||
"symfony/ai-platform": "^0.6",
|
||||
"symfony/http-client": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user