From 6a7b6021aefe11064a9412d8247d72b5fc61aeda Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Wed, 16 Jul 2025 01:13:06 +0200 Subject: [PATCH] Use JSON Path to convert responses --- examples/composer.json | 1 + examples/openrouter/stream-gemini.php | 37 ++ src/platform/composer.json | 1 + src/platform/phpstan.dist.neon | 1 + .../src/Bridge/Albert/PlatformFactory.php | 4 +- .../Azure/Meta/LlamaResultConverter.php | 41 -- .../src/Bridge/Azure/Meta/PlatformFactory.php | 2 +- .../Bridge/Azure/OpenAi/PlatformFactory.php | 4 +- .../Gemini/Embeddings/ResultConverter.php | 47 -- .../src/Bridge/Gemini/PlatformFactory.php | 8 +- .../LmStudio/Completions/ResultConverter.php | 40 -- .../LmStudio/Embeddings/ResultConverter.php | 48 -- .../src/Bridge/LmStudio/PlatformFactory.php | 12 +- .../Mistral/Embeddings/ResultConverter.php | 54 -- .../Bridge/Mistral/Llm/ResultConverter.php | 192 ------ .../src/Bridge/Mistral/PlatformFactory.php | 2 +- .../OpenAi/Embeddings/ResultConverter.php | 47 -- .../src/Bridge/OpenAi/Gpt/ResultConverter.php | 189 ------ .../src/Bridge/OpenAi/PlatformFactory.php | 3 +- .../src/Bridge/OpenRouter/PlatformFactory.php | 2 +- .../src/Bridge/OpenRouter/ResultConverter.php | 45 -- .../src/Bridge/Voyage/PlatformFactory.php | 2 +- .../src/Bridge/Voyage/ResultConverter.php | 44 -- src/platform/src/Contract/ResultConverter.php | 131 ++++ .../ResultExtractorInterface.php | 28 + .../ResultExtractor/StreamResultExtractor.php | 102 +++ .../ResultExtractor/TextResultExtractor.php | 39 ++ .../ToolCallResultExtractor.php | 62 ++ .../ResultExtractor/VectorResultExtractor.php | 42 ++ .../Gemini/Embeddings/ResultConverterTest.php | 63 -- .../Completions/ResultConverterTest.php | 34 - .../Embeddings/ResultConverterTest.php | 89 --- .../OpenAi/Embeddings/ResultConverterTest.php | 66 -- .../Bridge/OpenAi/Gpt/ResultConverterTest.php | 191 ------ .../tests/Contract/ResultConverterTest.php | 156 +++++ .../VectorResultExtractorTest.php | 45 ++ .../fixtures/embeddings-specific-success.json | 14 + .../fixtures/embeddings-standard-success.json | 21 + .../fixtures/openai-response-chat.json | 36 ++ .../fixtures/openai-response-choices.json | 58 ++ .../fixtures/openai-response-error.json | 8 + .../fixtures/openai-response-stream-chunks | 607 ++++++++++++++++++ .../openai-response-stream-toolcall-chunks | 406 ++++++++++++ .../openai-response-toolcall-choices.json | 67 ++ .../openai-response-toolcall-multiple.json | 54 ++ .../fixtures/openai-response-toolcall.json | 46 ++ 46 files changed, 1978 insertions(+), 1213 deletions(-) create mode 100644 examples/openrouter/stream-gemini.php delete mode 100644 src/platform/src/Bridge/Azure/Meta/LlamaResultConverter.php delete mode 100644 src/platform/src/Bridge/Gemini/Embeddings/ResultConverter.php delete mode 100644 src/platform/src/Bridge/LmStudio/Completions/ResultConverter.php delete mode 100644 src/platform/src/Bridge/LmStudio/Embeddings/ResultConverter.php delete mode 100644 src/platform/src/Bridge/Mistral/Embeddings/ResultConverter.php delete mode 100644 src/platform/src/Bridge/Mistral/Llm/ResultConverter.php delete mode 100644 src/platform/src/Bridge/OpenAi/Embeddings/ResultConverter.php delete mode 100644 src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php delete mode 100644 src/platform/src/Bridge/OpenRouter/ResultConverter.php delete mode 100644 src/platform/src/Bridge/Voyage/ResultConverter.php create mode 100644 src/platform/src/Contract/ResultConverter.php create mode 100644 src/platform/src/Contract/ResultExtractor/ResultExtractorInterface.php create mode 100644 src/platform/src/Contract/ResultExtractor/StreamResultExtractor.php create mode 100644 src/platform/src/Contract/ResultExtractor/TextResultExtractor.php create mode 100644 src/platform/src/Contract/ResultExtractor/ToolCallResultExtractor.php create mode 100644 src/platform/src/Contract/ResultExtractor/VectorResultExtractor.php delete mode 100644 src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php delete mode 100644 src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php delete mode 100644 src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php delete mode 100644 src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php delete mode 100644 src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php create mode 100644 src/platform/tests/Contract/ResultConverterTest.php create mode 100644 src/platform/tests/Contract/ResultExtractor/VectorResultExtractorTest.php create mode 100644 src/platform/tests/Contract/fixtures/embeddings-specific-success.json create mode 100644 src/platform/tests/Contract/fixtures/embeddings-standard-success.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-chat.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-choices.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-error.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-stream-chunks create mode 100644 src/platform/tests/Contract/fixtures/openai-response-stream-toolcall-chunks create mode 100644 src/platform/tests/Contract/fixtures/openai-response-toolcall-choices.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-toolcall-multiple.json create mode 100644 src/platform/tests/Contract/fixtures/openai-response-toolcall.json diff --git a/examples/composer.json b/examples/composer.json index 43646835..b5c56c58 100644 --- a/examples/composer.json +++ b/examples/composer.json @@ -22,6 +22,7 @@ "symfony/event-dispatcher": "^6.4|^7.0", "symfony/filesystem": "^6.4|^7.0", "symfony/finder": "^6.4|^7.0", + "symfony/json-path": "7.3.*", "symfony/process": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0" }, diff --git a/examples/openrouter/stream-gemini.php b/examples/openrouter/stream-gemini.php new file mode 100644 index 00000000..a4e61b3e --- /dev/null +++ b/examples/openrouter/stream-gemini.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\AI\Agent\Agent; +use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory; +use Symfony\AI\Platform\Message\Message; +use Symfony\AI\Platform\Message\MessageBag; +use Symfony\AI\Platform\Model; + +require_once dirname(__DIR__).'/bootstrap.php'; + +$platform = PlatformFactory::create(env('OPENROUTER_KEY'), http_client()); +// In case free is running into 429 rate limit errors, you can use the paid model: +// $model = new Model('google/gemini-2.0-flash-lite-001'); +$model = new Model('google/gemini-2.0-flash-exp:free'); + +$agent = new Agent($platform, $model, logger: logger()); +$messages = new MessageBag( + Message::forSystem('You are a helpful assistant and explain your answer lengthy.'), + Message::ofUser('Tina has one brother and one sister. How many sisters do Tina\'s siblings have?'), +); +$result = $agent->call($messages, [ + 'stream' => true, +]); + +foreach ($result->getContent() as $word) { + echo $word; +} +echo \PHP_EOL; diff --git a/src/platform/composer.json b/src/platform/composer.json index d8d3b622..b61a21d3 100644 --- a/src/platform/composer.json +++ b/src/platform/composer.json @@ -28,6 +28,7 @@ "psr/log": "^3.0", "symfony/clock": "^6.4 || ^7.1", "symfony/http-client": "^6.4 || ^7.1", + "symfony/json-path": "7.3.*", "symfony/property-access": "^6.4 || ^7.1", "symfony/property-info": "^6.4 || ^7.1", "symfony/serializer": "^6.4 || ^7.1", diff --git a/src/platform/phpstan.dist.neon b/src/platform/phpstan.dist.neon index 860d59d7..0e437328 100644 --- a/src/platform/phpstan.dist.neon +++ b/src/platform/phpstan.dist.neon @@ -7,6 +7,7 @@ parameters: paths: - src/ - tests/ + treatPhpDocTypesAsCertain: false ignoreErrors: - message: "#^Method .*::test.*\\(\\) has no return type specified\\.$#" diff --git a/src/platform/src/Bridge/Albert/PlatformFactory.php b/src/platform/src/Bridge/Albert/PlatformFactory.php index 32fd939e..4e0de7b5 100644 --- a/src/platform/src/Bridge/Albert/PlatformFactory.php +++ b/src/platform/src/Bridge/Albert/PlatformFactory.php @@ -11,8 +11,6 @@ namespace Symfony\AI\Platform\Bridge\Albert; -use Symfony\AI\Platform\Bridge\OpenAi\Embeddings; -use Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Contract; use Symfony\AI\Platform\Exception\InvalidArgumentException; use Symfony\AI\Platform\Platform; @@ -40,7 +38,7 @@ public static function create( new GptModelClient($httpClient, $apiKey, $baseUrl), new EmbeddingsModelClient($httpClient, $apiKey, $baseUrl), ], - [new Gpt\ResultConverter(), new Embeddings\ResultConverter()], + [Contract\ResultConverter::create()], Contract::create(), ); } diff --git a/src/platform/src/Bridge/Azure/Meta/LlamaResultConverter.php b/src/platform/src/Bridge/Azure/Meta/LlamaResultConverter.php deleted file mode 100644 index 28d1a4d0..00000000 --- a/src/platform/src/Bridge/Azure/Meta/LlamaResultConverter.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\Azure\Meta; - -use Symfony\AI\Platform\Bridge\Meta\Llama; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\TextResult; -use Symfony\AI\Platform\ResultConverterInterface; - -/** - * @author Christopher Hertel - */ -final readonly class LlamaResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Llama; - } - - public function convert(RawResultInterface $result, array $options = []): TextResult - { - $data = $result->getData(); - - if (!isset($data['choices'][0]['message']['content'])) { - throw new RuntimeException('Response does not contain output.'); - } - - return new TextResult($data['choices'][0]['message']['content']); - } -} diff --git a/src/platform/src/Bridge/Azure/Meta/PlatformFactory.php b/src/platform/src/Bridge/Azure/Meta/PlatformFactory.php index b912d951..6afce646 100644 --- a/src/platform/src/Bridge/Azure/Meta/PlatformFactory.php +++ b/src/platform/src/Bridge/Azure/Meta/PlatformFactory.php @@ -30,6 +30,6 @@ public static function create( ): Platform { $modelClient = new LlamaModelClient($httpClient ?? HttpClient::create(), $baseUrl, $apiKey); - return new Platform([$modelClient], [new LlamaResultConverter()], $contract); + return new Platform([$modelClient], [Contract\ResultConverter::create()], $contract); } } diff --git a/src/platform/src/Bridge/Azure/OpenAi/PlatformFactory.php b/src/platform/src/Bridge/Azure/OpenAi/PlatformFactory.php index f4ca9401..6f49d650 100644 --- a/src/platform/src/Bridge/Azure/OpenAi/PlatformFactory.php +++ b/src/platform/src/Bridge/Azure/OpenAi/PlatformFactory.php @@ -11,8 +11,6 @@ namespace Symfony\AI\Platform\Bridge\Azure\OpenAi; -use Symfony\AI\Platform\Bridge\OpenAi\Embeddings; -use Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Bridge\OpenAi\Whisper; use Symfony\AI\Platform\Bridge\OpenAi\Whisper\AudioNormalizer; use Symfony\AI\Platform\Contract; @@ -41,7 +39,7 @@ public static function create( return new Platform( [$gptModelClient, $embeddingsModelClient, $whisperModelClient], - [new Gpt\ResultConverter(), new Embeddings\ResultConverter(), new Whisper\ResultConverter()], + [new Whisper\ResultConverter(), Contract\ResultConverter::create()], $contract ?? Contract::create(new AudioNormalizer()), ); } diff --git a/src/platform/src/Bridge/Gemini/Embeddings/ResultConverter.php b/src/platform/src/Bridge/Gemini/Embeddings/ResultConverter.php deleted file mode 100644 index 518c2ccf..00000000 --- a/src/platform/src/Bridge/Gemini/Embeddings/ResultConverter.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\Gemini\Embeddings; - -use Symfony\AI\Platform\Bridge\Gemini\Embeddings; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Valtteri R - */ -final readonly class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function convert(RawResultInterface $result, array $options = []): VectorResult - { - $data = $result->getData(); - - if (!isset($data['embeddings'])) { - throw new RuntimeException('Response does not contain data.'); - } - - return new VectorResult( - ...array_map( - static fn (array $item): Vector => new Vector($item['values']), - $data['embeddings'], - ), - ); - } -} diff --git a/src/platform/src/Bridge/Gemini/PlatformFactory.php b/src/platform/src/Bridge/Gemini/PlatformFactory.php index b5b16f4d..e6d09a44 100644 --- a/src/platform/src/Bridge/Gemini/PlatformFactory.php +++ b/src/platform/src/Bridge/Gemini/PlatformFactory.php @@ -13,10 +13,10 @@ use Symfony\AI\Platform\Bridge\Gemini\Contract\GeminiContract; use Symfony\AI\Platform\Bridge\Gemini\Embeddings\ModelClient as EmbeddingsModelClient; -use Symfony\AI\Platform\Bridge\Gemini\Embeddings\ResultConverter as EmbeddingsResultConverter; use Symfony\AI\Platform\Bridge\Gemini\Gemini\ModelClient as GeminiModelClient; -use Symfony\AI\Platform\Bridge\Gemini\Gemini\ResultConverter as GeminiResultConverter; use Symfony\AI\Platform\Contract; +use Symfony\AI\Platform\Contract\ResultConverter; +use Symfony\AI\Platform\Contract\ResultExtractor\VectorResultExtractor; use Symfony\AI\Platform\Platform; use Symfony\Component\HttpClient\EventSourceHttpClient; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -36,7 +36,9 @@ public static function create( return new Platform( [new EmbeddingsModelClient($httpClient, $apiKey), new GeminiModelClient($httpClient, $apiKey)], - [new EmbeddingsResultConverter(), new GeminiResultConverter()], + [new Gemini\ResultConverter(), ResultConverter::create([ + new VectorResultExtractor('$.embeddings[*].values'), + ])], $contract ?? GeminiContract::create(), ); } diff --git a/src/platform/src/Bridge/LmStudio/Completions/ResultConverter.php b/src/platform/src/Bridge/LmStudio/Completions/ResultConverter.php deleted file mode 100644 index b9c7ad37..00000000 --- a/src/platform/src/Bridge/LmStudio/Completions/ResultConverter.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\LmStudio\Completions; - -use Symfony\AI\Platform\Bridge\LmStudio\Completions; -use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter as OpenAiResponseConverter; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\ResultInterface; -use Symfony\AI\Platform\ResultConverterInterface; - -/** - * @author André Lubian - */ -final class ResultConverter implements ResultConverterInterface -{ - public function __construct( - private readonly OpenAiResponseConverter $gptResponseConverter = new OpenAiResponseConverter(), - ) { - } - - public function supports(Model $model): bool - { - return $model instanceof Completions; - } - - public function convert(RawResultInterface $result, array $options = []): ResultInterface - { - return $this->gptResponseConverter->convert($result, $options); - } -} diff --git a/src/platform/src/Bridge/LmStudio/Embeddings/ResultConverter.php b/src/platform/src/Bridge/LmStudio/Embeddings/ResultConverter.php deleted file mode 100644 index cf06c55b..00000000 --- a/src/platform/src/Bridge/LmStudio/Embeddings/ResultConverter.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\LmStudio\Embeddings; - -use Symfony\AI\Platform\Bridge\LmStudio\Embeddings; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Christopher Hertel - * @author André Lubian - */ -final class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function convert(RawResultInterface $result, array $options = []): VectorResult - { - $data = $result->getData(); - - if (!isset($data['data'])) { - throw new RuntimeException('Response does not contain data.'); - } - - return new VectorResult( - ...array_map( - static fn (array $item): Vector => new Vector($item['embedding']), - $data['data'] - ), - ); - } -} diff --git a/src/platform/src/Bridge/LmStudio/PlatformFactory.php b/src/platform/src/Bridge/LmStudio/PlatformFactory.php index f3d5c6ee..92bed71a 100644 --- a/src/platform/src/Bridge/LmStudio/PlatformFactory.php +++ b/src/platform/src/Bridge/LmStudio/PlatformFactory.php @@ -30,13 +30,9 @@ public static function create( $httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient); return new Platform( - [ - new ModelClient($httpClient, $hostUrl), - new Completions\ModelClient($httpClient, $hostUrl), - ], - [ - new Embeddings\ResultConverter(), - new Completions\ResultConverter(), - ], $contract); + [new ModelClient($httpClient, $hostUrl), new Completions\ModelClient($httpClient, $hostUrl)], + [Contract\ResultConverter::create()], + $contract, + ); } } diff --git a/src/platform/src/Bridge/Mistral/Embeddings/ResultConverter.php b/src/platform/src/Bridge/Mistral/Embeddings/ResultConverter.php deleted file mode 100644 index 3f838d1a..00000000 --- a/src/platform/src/Bridge/Mistral/Embeddings/ResultConverter.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\Mistral\Embeddings; - -use Symfony\AI\Platform\Bridge\Mistral\Embeddings; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Christopher Hertel - */ -final readonly class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function convert(RawResultInterface|RawHttpResult $result, array $options = []): VectorResult - { - $httpResponse = $result->getObject(); - - if (200 !== $httpResponse->getStatusCode()) { - throw new RuntimeException(\sprintf('Unexpected response code %d: ', $httpResponse->getStatusCode()).$httpResponse->getContent(false)); - } - - $data = $result->getData(); - - if (!isset($data['data'])) { - throw new RuntimeException('Response does not contain data.'); - } - - return new VectorResult( - ...array_map( - static fn (array $item): Vector => new Vector($item['embedding']), - $data['data'] - ), - ); - } -} diff --git a/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php b/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php deleted file mode 100644 index a6b84026..00000000 --- a/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php +++ /dev/null @@ -1,192 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\Mistral\Llm; - -use Symfony\AI\Platform\Bridge\Mistral\Mistral; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\ChoiceResult; -use Symfony\AI\Platform\Result\RawHttpResult; -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; -use Symfony\Component\HttpClient\Chunk\ServerSentEvent; -use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Component\HttpClient\Exception\JsonException; -use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; - -/** - * @author Christopher Hertel - */ -final readonly class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Mistral; - } - - /** - * @param array $options - */ - public function convert(RawResultInterface|RawHttpResult $result, array $options = []): ResultInterface - { - $httpResponse = $result->getObject(); - - if ($options['stream'] ?? false) { - return new StreamResult($this->convertStream($httpResponse)); - } - - if (200 !== $code = $httpResponse->getStatusCode()) { - throw new RuntimeException(\sprintf('Unexpected response code %d: ', $code).$httpResponse->getContent(false)); - } - - $data = $result->getData(); - - if (!isset($data['choices'])) { - throw new RuntimeException('Response does not contain choices.'); - } - - $choices = array_map($this->convertChoice(...), $data['choices']); - - return 1 === \count($choices) ? $choices[0] : new ChoiceResult(...$choices); - } - - private function convertStream(HttpResponse $result): \Generator - { - $toolCalls = []; - foreach ((new EventSourceHttpClient())->stream($result) as $chunk) { - if (!$chunk instanceof ServerSentEvent || '[DONE]' === $chunk->getData()) { - continue; - } - - try { - $data = $chunk->getArrayData(); - } catch (JsonException) { - // try catch only needed for Symfony 6.4 - continue; - } - - 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 $toolCalls - * @param array $data - * - * @return array - */ - 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 $data - */ - private function streamIsToolCall(array $data): bool - { - return isset($data['choices'][0]['delta']['tool_calls']); - } - - /** - * @param array $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 ('stop' === $choice['finish_reason']) { - 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((string) $toolCall['function']['arguments'], true, \JSON_THROW_ON_ERROR); - - return new ToolCall($toolCall['id'], $toolCall['function']['name'], $arguments); - } -} diff --git a/src/platform/src/Bridge/Mistral/PlatformFactory.php b/src/platform/src/Bridge/Mistral/PlatformFactory.php index f17e4a6d..5e7147b0 100644 --- a/src/platform/src/Bridge/Mistral/PlatformFactory.php +++ b/src/platform/src/Bridge/Mistral/PlatformFactory.php @@ -32,7 +32,7 @@ public static function create( return new Platform( [new Embeddings\ModelClient($httpClient, $apiKey), new Llm\ModelClient($httpClient, $apiKey)], - [new Embeddings\ResultConverter(), new Llm\ResultConverter()], + [Contract\ResultConverter::create()], $contract ?? Contract::create(new ToolNormalizer()), ); } diff --git a/src/platform/src/Bridge/OpenAi/Embeddings/ResultConverter.php b/src/platform/src/Bridge/OpenAi/Embeddings/ResultConverter.php deleted file mode 100644 index 4ad7912f..00000000 --- a/src/platform/src/Bridge/OpenAi/Embeddings/ResultConverter.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenAi\Embeddings; - -use Symfony\AI\Platform\Bridge\OpenAi\Embeddings; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Christopher Hertel - */ -final class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function convert(RawResultInterface $result, array $options = []): VectorResult - { - $data = $result->getData(); - - if (!isset($data['data'])) { - throw new RuntimeException('Response does not contain data.'); - } - - return new VectorResult( - ...array_map( - static fn (array $item): Vector => new Vector($item['embedding']), - $data['data'] - ), - ); - } -} diff --git a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php deleted file mode 100644 index 72714e81..00000000 --- a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php +++ /dev/null @@ -1,189 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenAi\Gpt; - -use Symfony\AI\Platform\Bridge\OpenAi\Gpt; -use Symfony\AI\Platform\Exception\ContentFilterException; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\ChoiceResult; -use Symfony\AI\Platform\Result\RawHttpResult; -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 as PlatformResponseConverter; -use Symfony\Component\HttpClient\Chunk\ServerSentEvent; -use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Component\HttpClient\Exception\JsonException; -use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; - -/** - * @author Christopher Hertel - * @author Denis Zunke - */ -final class ResultConverter implements PlatformResponseConverter -{ - public function supports(Model $model): bool - { - return $model instanceof Gpt; - } - - public function convert(RawResultInterface|RawHttpResult $result, array $options = []): ResultInterface - { - if ($options['stream'] ?? false) { - return new StreamResult($this->convertStream($result->getObject())); - } - - $data = $result->getData(); - - if (isset($data['error']['code']) && 'content_filter' === $data['error']['code']) { - throw new ContentFilterException($data['error']['message']); - } - - if (!isset($data['choices'])) { - throw new RuntimeException('Response does not contain choices.'); - } - - $choices = array_map($this->convertChoice(...), $data['choices']); - - return 1 === \count($choices) ? $choices[0] : new ChoiceResult(...$choices); - } - - private function convertStream(HttpResponse $result): \Generator - { - $toolCalls = []; - foreach ((new EventSourceHttpClient())->stream($result) as $chunk) { - if (!$chunk instanceof ServerSentEvent || '[DONE]' === $chunk->getData()) { - continue; - } - - try { - $data = $chunk->getArrayData(); - } catch (JsonException) { - // try catch only needed for Symfony 6.4 - continue; - } - - 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 $toolCalls - * @param array $data - * - * @return array - */ - 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 $data - */ - private function streamIsToolCall(array $data): bool - { - return isset($data['choices'][0]['delta']['tool_calls']); - } - - /** - * @param array $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, \JSON_THROW_ON_ERROR); - - return new ToolCall($toolCall['id'], $toolCall['function']['name'], $arguments); - } -} diff --git a/src/platform/src/Bridge/OpenAi/PlatformFactory.php b/src/platform/src/Bridge/OpenAi/PlatformFactory.php index c8f97df4..509fe9ec 100644 --- a/src/platform/src/Bridge/OpenAi/PlatformFactory.php +++ b/src/platform/src/Bridge/OpenAi/PlatformFactory.php @@ -40,10 +40,9 @@ public static function create( new WhisperModelClient($httpClient, $apiKey), ], [ - new Gpt\ResultConverter(), - new Embeddings\ResultConverter(), new DallE\ResultConverter(), new WhisperResponseConverter(), + Contract\ResultConverter::create(), ], $contract ?? Contract::create(new AudioNormalizer()), ); diff --git a/src/platform/src/Bridge/OpenRouter/PlatformFactory.php b/src/platform/src/Bridge/OpenRouter/PlatformFactory.php index 9f52ec01..dab1342c 100644 --- a/src/platform/src/Bridge/OpenRouter/PlatformFactory.php +++ b/src/platform/src/Bridge/OpenRouter/PlatformFactory.php @@ -34,7 +34,7 @@ public static function create( return new Platform( [new ModelClient($httpClient, $apiKey)], - [new ResultConverter()], + [Contract\ResultConverter::create()], $contract ?? Contract::create( new AssistantMessageNormalizer(), new MessageBagNormalizer(), diff --git a/src/platform/src/Bridge/OpenRouter/ResultConverter.php b/src/platform/src/Bridge/OpenRouter/ResultConverter.php deleted file mode 100644 index 79ab8b8c..00000000 --- a/src/platform/src/Bridge/OpenRouter/ResultConverter.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter; - -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\ResultInterface; -use Symfony\AI\Platform\Result\TextResult; -use Symfony\AI\Platform\ResultConverterInterface; - -/** - * @author rglozman - */ -final readonly class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return true; - } - - public function convert(RawResultInterface $result, array $options = []): ResultInterface - { - $data = $result->getData(); - - if (!isset($data['choices'][0]['message'])) { - throw new RuntimeException('Response does not contain message.'); - } - - if (!isset($data['choices'][0]['message']['content'])) { - throw new RuntimeException('Message does not contain content.'); - } - - return new TextResult($data['choices'][0]['message']['content']); - } -} diff --git a/src/platform/src/Bridge/Voyage/PlatformFactory.php b/src/platform/src/Bridge/Voyage/PlatformFactory.php index cb82e43f..e9c28cdf 100644 --- a/src/platform/src/Bridge/Voyage/PlatformFactory.php +++ b/src/platform/src/Bridge/Voyage/PlatformFactory.php @@ -29,6 +29,6 @@ public static function create( ): Platform { $httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient); - return new Platform([new ModelClient($httpClient, $apiKey)], [new ResultConverter()], $contract); + return new Platform([new ModelClient($httpClient, $apiKey)], [Contract\ResultConverter::create()], $contract); } } diff --git a/src/platform/src/Bridge/Voyage/ResultConverter.php b/src/platform/src/Bridge/Voyage/ResultConverter.php deleted file mode 100644 index a3b91250..00000000 --- a/src/platform/src/Bridge/Voyage/ResultConverter.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\Voyage; - -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\ResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Christopher Hertel - */ -final readonly class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Voyage; - } - - public function convert(RawResultInterface $result, array $options = []): ResultInterface - { - $result = $result->getData(); - - if (!isset($result['data'])) { - throw new RuntimeException('Response does not contain embedding data.'); - } - - $vectors = array_map(fn (array $data) => new Vector($data['embedding']), $result['data']); - - return new VectorResult($vectors[0]); - } -} diff --git a/src/platform/src/Contract/ResultConverter.php b/src/platform/src/Contract/ResultConverter.php new file mode 100644 index 00000000..ef86f97f --- /dev/null +++ b/src/platform/src/Contract/ResultConverter.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract; + +use Symfony\AI\Platform\Contract\ResultExtractor\ResultExtractorInterface; +use Symfony\AI\Platform\Contract\ResultExtractor\StreamResultExtractor; +use Symfony\AI\Platform\Contract\ResultExtractor\TextResultExtractor; +use Symfony\AI\Platform\Contract\ResultExtractor\ToolCallResultExtractor; +use Symfony\AI\Platform\Contract\ResultExtractor\VectorResultExtractor; +use Symfony\AI\Platform\Exception\RuntimeException; +use Symfony\AI\Platform\Model; +use Symfony\AI\Platform\Result\ChoiceResult; +use Symfony\AI\Platform\Result\RawHttpResult; +use Symfony\AI\Platform\Result\RawResultInterface; +use Symfony\AI\Platform\Result\ResultInterface; +use Symfony\AI\Platform\Result\StreamResult; +use Symfony\AI\Platform\ResultConverterInterface; +use Symfony\Component\HttpClient\Chunk\ServerSentEvent; +use Symfony\Component\HttpClient\EventSourceHttpClient; +use Symfony\Component\JsonPath\JsonCrawler; +use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; + +/** + * The ResultConverter is responsible for converting the json output of a model into structured result objects. + * Is uses a set of ResultExtractors defining default JsonPath expressions to extract the relevant data. + * With the `create()` method, you can overwrite the default extractors with different configuration of those instances. + * + * @author Christopher Hertel + */ +final readonly class ResultConverter implements ResultConverterInterface +{ + /** + * @param ResultExtractorInterface[] $resultExtractors + */ + public function __construct( + private iterable $resultExtractors, + private StreamResultExtractor $streamExtractor, + ) { + } + + /** + * Can be used to create a ResultConverter and provides a mechanism to overwrite the ResultExtractor with + * instances that have different JsonPath expressions configured: + * + * For example: + * ResultConverter::create([ + * new VectorResultExtractor('$.embeddings[*].values'), + * ]) + * + * @param list $overwrites + */ + public static function create(array $overwrites = []): self + { + $defaults = [ + VectorResultExtractor::class => new VectorResultExtractor(), + ToolCallResultExtractor::class => new ToolCallResultExtractor(), + TextResultExtractor::class => new TextResultExtractor(), + ]; + $streamExtractor = new StreamResultExtractor(); + + foreach ($overwrites as $overwrite) { + if ($overwrite instanceof StreamResultExtractor) { + $streamExtractor = $overwrite; + continue; + } + + if (!$overwrite instanceof ResultExtractorInterface) { + throw new RuntimeException(\sprintf('Expected instance of "%s", got "%s"', ResultExtractorInterface::class, get_debug_type($overwrite))); + } + + $defaults[$overwrite::class] = $overwrite; + } + + return new self(array_values($defaults), $streamExtractor); + } + + public function supports(Model $model): bool + { + return true; + } + + public function convert(RawResultInterface|RawHttpResult $result, array $options = []): ResultInterface + { + if ($options['stream'] ?? false) { + return new StreamResult($this->convertStream($result->getObject())); + } + + $crawler = new JsonCrawler($result->getObject()->getContent(false)); + + $choices = []; + foreach ($this->resultExtractors as $jsonPathConverter) { + if (!$jsonPathConverter->supports($crawler)) { + continue; + } + + $choices += $jsonPathConverter->extract($crawler); + } + + if ([] === $choices) { + throw new RuntimeException('No suitable extractor found for the provided data.'); + } + + if (1 < \count($choices)) { + return new ChoiceResult(...$choices); + } + + return reset($choices); + } + + private function convertStream(HttpResponse $result): \Generator + { + foreach ((new EventSourceHttpClient())->stream($result) as $chunk) { + if (!$chunk instanceof ServerSentEvent || '[DONE]' === $chunk->getData()) { + continue; + } + + yield from $this->streamExtractor->extract( + new JsonCrawler($chunk->getData()) + ); + } + } +} diff --git a/src/platform/src/Contract/ResultExtractor/ResultExtractorInterface.php b/src/platform/src/Contract/ResultExtractor/ResultExtractorInterface.php new file mode 100644 index 00000000..419684da --- /dev/null +++ b/src/platform/src/Contract/ResultExtractor/ResultExtractorInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract\ResultExtractor; + +use Symfony\AI\Platform\Result\ResultInterface; +use Symfony\Component\JsonPath\JsonCrawler; + +/** + * @author Christopher Hertel + */ +interface ResultExtractorInterface +{ + public function supports(JsonCrawler $crawler): bool; + + /** + * @return ResultInterface[] + */ + public function extract(JsonCrawler $crawler): array; +} diff --git a/src/platform/src/Contract/ResultExtractor/StreamResultExtractor.php b/src/platform/src/Contract/ResultExtractor/StreamResultExtractor.php new file mode 100644 index 00000000..a2d29129 --- /dev/null +++ b/src/platform/src/Contract/ResultExtractor/StreamResultExtractor.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract\ResultExtractor; + +use Symfony\AI\Platform\Result\ToolCall; +use Symfony\AI\Platform\Result\ToolCallResult; +use Symfony\Component\JsonPath\JsonCrawler; +use Symfony\Component\JsonPath\JsonPath; + +/** + * @phpstan-type ToolCallArray array{ + * id: string, + * type: 'function', + * function: array{ + * name: string, + * arguments: string + * } + * } + * + * @author Christopher Hertel + */ +final class StreamResultExtractor +{ + /** + * @var ToolCallArray[] + */ + private array $toolCalls = []; + + public function __construct( + private string|JsonPath $textPath = '$.choices[*].delta.content', + private string|JsonPath $toolCallsPath = '$.choices[*].delta.tool_calls', + private string|JsonPath $finishReasonPath = '$.choices[*].finish_reason', + ) { + } + + /** + * @return iterable + */ + public function extract(JsonCrawler $crawler): iterable + { + if ([] !== $text = array_filter($crawler->find($this->textPath))) { + yield from $text; + } + + if ($this->streamIsToolCall($crawler)) { + $this->convertStreamToToolCalls($crawler); + } + + if ([] !== $this->toolCalls && $this->isToolCallsStreamFinished($crawler)) { + yield new ToolCallResult(...array_map($this->convertToolCall(...), $this->toolCalls)); + $this->toolCalls = []; + } + } + + private function convertStreamToToolCalls(JsonCrawler $crawler): void + { + foreach ($crawler->find($this->toolCallsPath) as $choice) { + foreach ($choice as $i => $toolCall) { + if (isset($toolCall['id'])) { + // initialize tool call + $this->toolCalls[$i] = [ + 'id' => $toolCall['id'], + 'function' => $toolCall['function'], + ]; + continue; + } + + // add arguments delta to tool call + $this->toolCalls[$i]['function']['arguments'] .= $toolCall['function']['arguments']; + } + } + } + + private function streamIsToolCall(JsonCrawler $crawler): bool + { + return [] !== $crawler->find($this->toolCallsPath); + } + + private function isToolCallsStreamFinished(JsonCrawler $crawler): bool + { + return \in_array('tool_calls', $crawler->find($this->finishReasonPath), true); + } + + /** + * @param ToolCallArray $toolCall + */ + private function convertToolCall(array $toolCall): ToolCall + { + $arguments = json_decode($toolCall['function']['arguments'], true, \JSON_THROW_ON_ERROR); + + return new ToolCall($toolCall['id'], $toolCall['function']['name'], $arguments); + } +} diff --git a/src/platform/src/Contract/ResultExtractor/TextResultExtractor.php b/src/platform/src/Contract/ResultExtractor/TextResultExtractor.php new file mode 100644 index 00000000..b5fbc4d0 --- /dev/null +++ b/src/platform/src/Contract/ResultExtractor/TextResultExtractor.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract\ResultExtractor; + +use Symfony\AI\Platform\Result\TextResult; +use Symfony\Component\JsonPath\JsonCrawler; +use Symfony\Component\JsonPath\JsonPath; + +/** + * @author Christopher Hertel + */ +readonly class TextResultExtractor implements ResultExtractorInterface +{ + public function __construct( + private string|JsonPath $jsonPath = '$.choices[?length(@.message.content) >= 0].message.content', + ) { + } + + public function supports(JsonCrawler $crawler): bool + { + return [] !== array_filter($crawler->find($this->jsonPath)); + } + + public function extract(JsonCrawler $crawler): array + { + $data = $crawler->find($this->jsonPath); + + return array_map(static fn (string $text): TextResult => new TextResult($text), $data); + } +} diff --git a/src/platform/src/Contract/ResultExtractor/ToolCallResultExtractor.php b/src/platform/src/Contract/ResultExtractor/ToolCallResultExtractor.php new file mode 100644 index 00000000..0afe16d2 --- /dev/null +++ b/src/platform/src/Contract/ResultExtractor/ToolCallResultExtractor.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract\ResultExtractor; + +use Symfony\AI\Platform\Result\ToolCall; +use Symfony\AI\Platform\Result\ToolCallResult; +use Symfony\Component\JsonPath\JsonCrawler; +use Symfony\Component\JsonPath\JsonPath; + +/** + * @author Christopher Hertel + */ +readonly class ToolCallResultExtractor implements ResultExtractorInterface +{ + public function __construct( + private string|JsonPath $jsonPath = '$.choices[*].message.tool_calls', + private string|JsonPath $idPath = '$.choices[*].message.tool_calls[*].id', + private string|JsonPath $functionNamePath = '$.choices[*].message.tool_calls[*].function.name', + private string|JsonPath $functionArgumentsPath = '$.choices[*].message.tool_calls[*].function.arguments', + ) { + } + + public function supports(JsonCrawler $crawler): bool + { + return [] !== $crawler->find($this->idPath); + } + + public function extract(JsonCrawler $crawler): array + { + $choices = $crawler->find($this->jsonPath); + $ids = $crawler->find($this->idPath); + $functionNames = $crawler->find($this->functionNamePath); + $functionArguments = $crawler->find($this->functionArgumentsPath); + + $results = []; + foreach ($choices as $toolCallResult) { + $limit = \count($toolCallResult); + + $toolCalls = []; + for ($i = 0; $i < $limit; ++$i) { + $toolCalls[] = new ToolCall( + array_shift($ids), + array_shift($functionNames), + json_decode(array_shift($functionArguments), true), + ); + } + + $results[] = new ToolCallResult(...$toolCalls); + } + + return $results; + } +} diff --git a/src/platform/src/Contract/ResultExtractor/VectorResultExtractor.php b/src/platform/src/Contract/ResultExtractor/VectorResultExtractor.php new file mode 100644 index 00000000..da4e1a87 --- /dev/null +++ b/src/platform/src/Contract/ResultExtractor/VectorResultExtractor.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Contract\ResultExtractor; + +use Symfony\AI\Platform\Result\VectorResult; +use Symfony\AI\Platform\Vector\Vector; +use Symfony\Component\JsonPath\JsonCrawler; +use Symfony\Component\JsonPath\JsonPath; + +/** + * @author Christopher Hertel + */ +readonly class VectorResultExtractor implements ResultExtractorInterface +{ + public function __construct( + private string|JsonPath $jsonPath = '$.data[*].embedding', + ) { + } + + public function supports(JsonCrawler $crawler): bool + { + return [] !== $crawler->find($this->jsonPath); + } + + public function extract(JsonCrawler $crawler): array + { + $data = $crawler->find($this->jsonPath); + + return [new VectorResult( + ...array_map(static fn (array $vector): Vector => new Vector($vector), $data), + )]; + } +} diff --git a/src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php b/src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php deleted file mode 100644 index 7c6ec1d7..00000000 --- a/src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Embeddings; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Small; -use PHPUnit\Framework\Attributes\UsesClass; -use PHPUnit\Framework\TestCase; -use Symfony\AI\Platform\Bridge\Gemini\Embeddings; -use Symfony\AI\Platform\Bridge\Gemini\Embeddings\ResultConverter; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\Vector\Vector; -use Symfony\Contracts\HttpClient\ResponseInterface; - -#[CoversClass(ResultConverter::class)] -#[Small] -#[UsesClass(Vector::class)] -#[UsesClass(VectorResult::class)] -#[UsesClass(Embeddings::class)] -final class ResultConverterTest extends TestCase -{ - public function testItConvertsAResponseToAVectorResult() - { - $result = $this->createStub(ResponseInterface::class); - $result - ->method('toArray') - ->willReturn(json_decode($this->getEmbeddingStub(), true)); - - $vectorResult = (new ResultConverter())->convert(new RawHttpResult($result)); - $convertedContent = $vectorResult->getContent(); - - $this->assertCount(2, $convertedContent); - - $this->assertSame([0.3, 0.4, 0.4], $convertedContent[0]->getData()); - $this->assertSame([0.0, 0.0, 0.2], $convertedContent[1]->getData()); - } - - private function getEmbeddingStub(): string - { - return <<<'JSON' - { - "embeddings": [ - { - "values": [0.3, 0.4, 0.4] - }, - { - "values": [0.0, 0.0, 0.2] - } - ] - } - JSON; - } -} diff --git a/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php b/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php deleted file mode 100644 index 4e7c1c4b..00000000 --- a/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Tests\Bridge\LmStudio\Completions; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Small; -use PHPUnit\Framework\Attributes\UsesClass; -use PHPUnit\Framework\TestCase; -use Symfony\AI\Platform\Bridge\LmStudio\Completions; -use Symfony\AI\Platform\Bridge\LmStudio\Completions\ResultConverter; -use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter as OpenAiResultConverter; - -#[CoversClass(ResultConverter::class)] -#[UsesClass(Completions::class)] -#[UsesClass(OpenAiResultConverter::class)] -#[Small] -class ResultConverterTest extends TestCase -{ - public function testItSupportsCompletionsModel() - { - $converter = new ResultConverter(); - - $this->assertTrue($converter->supports(new Completions('test-model'))); - } -} diff --git a/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php b/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php deleted file mode 100644 index 16b6b25d..00000000 --- a/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php +++ /dev/null @@ -1,89 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Tests\Bridge\LmStudio\Embeddings; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Small; -use PHPUnit\Framework\Attributes\UsesClass; -use PHPUnit\Framework\TestCase; -use Symfony\AI\Platform\Bridge\LmStudio\Embeddings; -use Symfony\AI\Platform\Bridge\LmStudio\Embeddings\ResultConverter; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\Vector\Vector; -use Symfony\Contracts\HttpClient\ResponseInterface; - -#[CoversClass(ResultConverter::class)] -#[Small] -#[UsesClass(Vector::class)] -#[UsesClass(VectorResult::class)] -#[UsesClass(Embeddings::class)] -class ResultConverterTest extends TestCase -{ - public function testItConvertsAResponseToAVectorResult() - { - $result = $this->createStub(ResponseInterface::class); - $result - ->method('toArray') - ->willReturn( - json_decode( - <<<'JSON' - { - "object": "list", - "data": [ - { - "object": "embedding", - "index": 0, - "embedding": [0.3, 0.4, 0.4] - }, - { - "object": "embedding", - "index": 1, - "embedding": [0.0, 0.0, 0.2] - } - ] - } - JSON, - true - ) - ); - - $vectorResult = (new ResultConverter())->convert(new RawHttpResult($result)); - $convertedContent = $vectorResult->getContent(); - - $this->assertCount(2, $convertedContent); - - $this->assertSame([0.3, 0.4, 0.4], $convertedContent[0]->getData()); - $this->assertSame([0.0, 0.0, 0.2], $convertedContent[1]->getData()); - } - - public function testItThrowsExceptionWhenResponseDoesNotContainData() - { - $result = $this->createStub(ResponseInterface::class); - $result - ->method('toArray') - ->willReturn(['invalid' => 'response']); - - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Response does not contain data'); - - (new ResultConverter())->convert(new RawHttpResult($result)); - } - - public function testItSupportsEmbeddingsModel() - { - $converter = new ResultConverter(); - - $this->assertTrue($converter->supports(new Embeddings('test-model'))); - } -} diff --git a/src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php b/src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php deleted file mode 100644 index ec48f4ab..00000000 --- a/src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Embeddings; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Small; -use PHPUnit\Framework\Attributes\UsesClass; -use PHPUnit\Framework\TestCase; -use Symfony\AI\Platform\Bridge\OpenAi\Embeddings\ResultConverter; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\Vector\Vector; -use Symfony\Contracts\HttpClient\ResponseInterface; - -#[CoversClass(ResultConverter::class)] -#[Small] -#[UsesClass(Vector::class)] -#[UsesClass(VectorResult::class)] -class ResultConverterTest extends TestCase -{ - public function testItConvertsAResponseToAVectorResult() - { - $result = $this->createStub(ResponseInterface::class); - $result - ->method('toArray') - ->willReturn(json_decode($this->getEmbeddingStub(), true)); - - $vectorResult = (new ResultConverter())->convert(new RawHttpResult($result)); - $convertedContent = $vectorResult->getContent(); - - $this->assertCount(2, $convertedContent); - - $this->assertSame([0.3, 0.4, 0.4], $convertedContent[0]->getData()); - $this->assertSame([0.0, 0.0, 0.2], $convertedContent[1]->getData()); - } - - private function getEmbeddingStub(): string - { - return <<<'JSON' - { - "object": "list", - "data": [ - { - "object": "embedding", - "index": 0, - "embedding": [0.3, 0.4, 0.4] - }, - { - "object": "embedding", - "index": 1, - "embedding": [0.0, 0.0, 0.2] - } - ] - } - JSON; - } -} diff --git a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php b/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php deleted file mode 100644 index 8f0a6f2f..00000000 --- a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php +++ /dev/null @@ -1,191 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Gpt; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Small; -use PHPUnit\Framework\Attributes\UsesClass; -use PHPUnit\Framework\TestCase; -use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter; -use Symfony\AI\Platform\Exception\ContentFilterException; -use Symfony\AI\Platform\Exception\RuntimeException; -use Symfony\AI\Platform\Result\ChoiceResult; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\AI\Platform\Result\TextResult; -use Symfony\AI\Platform\Result\ToolCall; -use Symfony\AI\Platform\Result\ToolCallResult; -use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; -use Symfony\Contracts\HttpClient\ResponseInterface; - -#[CoversClass(ResultConverter::class)] -#[Small] -#[UsesClass(ChoiceResult::class)] -#[UsesClass(TextResult::class)] -#[UsesClass(ToolCall::class)] -#[UsesClass(ToolCallResult::class)] -class ResultConverterTest extends TestCase -{ - public function testConvertTextResult() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - $httpResponse->method('toArray')->willReturn([ - 'choices' => [ - [ - 'message' => [ - 'role' => 'assistant', - 'content' => 'Hello world', - ], - 'finish_reason' => 'stop', - ], - ], - ]); - - $result = $converter->convert(new RawHttpResult($httpResponse)); - - $this->assertInstanceOf(TextResult::class, $result); - $this->assertSame('Hello world', $result->getContent()); - } - - public function testConvertToolCallResult() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - $httpResponse->method('toArray')->willReturn([ - 'choices' => [ - [ - 'message' => [ - 'role' => 'assistant', - 'content' => null, - 'tool_calls' => [ - [ - 'id' => 'call_123', - 'type' => 'function', - 'function' => [ - 'name' => 'test_function', - 'arguments' => '{"arg1": "value1"}', - ], - ], - ], - ], - 'finish_reason' => 'tool_calls', - ], - ], - ]); - - $result = $converter->convert(new RawHttpResult($httpResponse)); - - $this->assertInstanceOf(ToolCallResult::class, $result); - $toolCalls = $result->getContent(); - $this->assertCount(1, $toolCalls); - $this->assertSame('call_123', $toolCalls[0]->id); - $this->assertSame('test_function', $toolCalls[0]->name); - $this->assertSame(['arg1' => 'value1'], $toolCalls[0]->arguments); - } - - public function testConvertMultipleChoices() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - $httpResponse->method('toArray')->willReturn([ - 'choices' => [ - [ - 'message' => [ - 'role' => 'assistant', - 'content' => 'Choice 1', - ], - 'finish_reason' => 'stop', - ], - [ - 'message' => [ - 'role' => 'assistant', - 'content' => 'Choice 2', - ], - 'finish_reason' => 'stop', - ], - ], - ]); - - $result = $converter->convert(new RawHttpResult($httpResponse)); - - $this->assertInstanceOf(ChoiceResult::class, $result); - $choices = $result->getContent(); - $this->assertCount(2, $choices); - $this->assertSame('Choice 1', $choices[0]->getContent()); - $this->assertSame('Choice 2', $choices[1]->getContent()); - } - - public function testContentFilterException() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - - $httpResponse->expects($this->exactly(1)) - ->method('toArray') - ->willReturnCallback(function ($throw = true) { - if ($throw) { - throw new class extends \Exception implements ClientExceptionInterface { - public function getResponse(): ResponseInterface - { - throw new RuntimeException('Not implemented'); - } - }; - } - - return [ - 'error' => [ - 'code' => 'content_filter', - 'message' => 'Content was filtered', - ], - ]; - }); - - self::expectException(ContentFilterException::class); - self::expectExceptionMessage('Content was filtered'); - - $converter->convert(new RawHttpResult($httpResponse)); - } - - public function testThrowsExceptionWhenNoChoices() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - $httpResponse->method('toArray')->willReturn([]); - - self::expectException(RuntimeException::class); - self::expectExceptionMessage('Response does not contain choices'); - - $converter->convert(new RawHttpResult($httpResponse)); - } - - public function testThrowsExceptionForUnsupportedFinishReason() - { - $converter = new ResultConverter(); - $httpResponse = self::createMock(ResponseInterface::class); - $httpResponse->method('toArray')->willReturn([ - 'choices' => [ - [ - 'message' => [ - 'role' => 'assistant', - 'content' => 'Test content', - ], - 'finish_reason' => 'unsupported_reason', - ], - ], - ]); - - self::expectException(RuntimeException::class); - self::expectExceptionMessage('Unsupported finish reason "unsupported_reason"'); - - $converter->convert(new RawHttpResult($httpResponse)); - } -} diff --git a/src/platform/tests/Contract/ResultConverterTest.php b/src/platform/tests/Contract/ResultConverterTest.php new file mode 100644 index 00000000..ad25451f --- /dev/null +++ b/src/platform/tests/Contract/ResultConverterTest.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Tests\Contract; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\TestCase; +use Symfony\AI\Platform\Contract\ResultConverter; +use Symfony\AI\Platform\Contract\ResultExtractor\VectorResultExtractor; +use Symfony\AI\Platform\Result\ChoiceResult; +use Symfony\AI\Platform\Result\RawHttpResult; +use Symfony\AI\Platform\Result\TextResult; +use Symfony\AI\Platform\Result\ToolCall; +use Symfony\AI\Platform\Result\ToolCallResult; +use Symfony\AI\Platform\Result\VectorResult; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\JsonMockResponse; + +#[CoversClass(ResultConverter::class)] +final class ResultConverterTest extends TestCase +{ + public function testStandardVectorResultConversion() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/embeddings-standard-success.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/embeddings'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(VectorResult::class, $actual); + $this->assertCount(1, $actual->getContent()); + $this->assertSame(5, $actual->getContent()[0]->getDimensions()); + } + + public function testSpecificVectorResultSuccess() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/embeddings-specific-success.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/embeddings'); + + $converter = ResultConverter::create([ + new VectorResultExtractor('$.embeddings[*].values'), + ]); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(VectorResult::class, $actual); + $this->assertCount(1, $actual->getContent()); + $this->assertSame(6, $actual->getContent()[0]->getDimensions()); + } + + public function testStandardTextResult() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/openai-response-chat.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/completions'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(TextResult::class, $actual); + $this->assertSame('Arrr, matey! Symfony be a treasure of a framework for building web applications in PHP!', $actual->getContent()); + } + + public function testStandardToolCallResult() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/openai-response-toolcall.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/completions'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(ToolCallResult::class, $actual); + $this->assertContainsOnlyInstancesOf(ToolCall::class, $toolCalls = $actual->getContent()); + $this->assertCount(1, $toolCalls); + $this->assertSame('call_1234', $toolCalls[0]->id); + $this->assertSame('my_tool', $toolCalls[0]->name); + $this->assertSame(['myParam' => 'abcdefg'], $toolCalls[0]->arguments); + } + + public function testMultipleStandardToolCallResult() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/openai-response-toolcall-multiple.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/completions'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(ToolCallResult::class, $actual); + $this->assertContainsOnlyInstancesOf(ToolCall::class, $toolCalls = $actual->getContent()); + $this->assertCount(2, $toolCalls); + $this->assertSame('call_1234', $toolCalls[0]->id); + $this->assertSame('my_tool', $toolCalls[0]->name); + $this->assertSame(['myParam' => 'abcdefg'], $toolCalls[0]->arguments); + $this->assertSame('call_2345', $toolCalls[1]->id); + $this->assertSame('foo_bar', $toolCalls[1]->name); + $this->assertSame(['foo' => 'bar'], $toolCalls[1]->arguments); + } + + public function testMultipleStandardToolCallChoiceResult() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/openai-response-toolcall-choices.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/completions'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(ChoiceResult::class, $actual); + $this->assertContainsOnlyInstancesOf(ToolCallResult::class, $toolCallResults = $actual->getContent()); + $this->assertCount(2, $toolCallResults); + $this->assertCount(1, $toolCallResults[0]->getContent()); + $this->assertCount(1, $toolCallResults[1]->getContent()); + $this->assertSame('call_1234', $toolCallResults[0]->getContent()[0]->id); + $this->assertSame('my_tool', $toolCallResults[0]->getContent()[0]->name); + $this->assertSame(['myParam' => 'abcdefg'], $toolCallResults[0]->getContent()[0]->arguments); + $this->assertSame('call_4321', $toolCallResults[1]->getContent()[0]->id); + $this->assertSame('my_tool_two', $toolCallResults[1]->getContent()[0]->name); + $this->assertSame(['foo' => 'bar'], $toolCallResults[1]->getContent()[0]->arguments); + } + + public function testStandardChoicesResult() + { + $httpClient = new MockHttpClient($this->jsonMockResponseFromFile(__DIR__.'/fixtures/openai-response-choices.json')); + $response = $httpClient->request('POST', 'https://api.example.com/v1/completions'); + + $converter = ResultConverter::create(); + + $actual = $converter->convert(new RawHttpResult($response)); + + $this->assertInstanceOf(ChoiceResult::class, $actual); + $this->assertContainsOnlyInstancesOf(TextResult::class, $choices = $actual->getContent()); + $this->assertCount(3, $choices); + $this->assertSame('1 Arrr, matey! Symfony be a treasure chest of tools fer building web applications in PHP!', $choices[0]->getContent()); + $this->assertSame('2 Arrr, my pirate! Symfony be a treasure chest of tools fer building web applications in PHP!', $choices[1]->getContent()); + $this->assertSame('3 Ahoy there, matey! Symfony be a treasure chest of a framework for PHP', $choices[2]->getContent()); + } + + /** + * This can be replaced by `JsonMockResponse::fromFile` when dropping Symfony 6.4. + */ + private function jsonMockResponseFromFile(string $file): JsonMockResponse + { + return new JsonMockResponse(json_decode(file_get_contents($file), true)); + } +} diff --git a/src/platform/tests/Contract/ResultExtractor/VectorResultExtractorTest.php b/src/platform/tests/Contract/ResultExtractor/VectorResultExtractorTest.php new file mode 100644 index 00000000..f73cfc5b --- /dev/null +++ b/src/platform/tests/Contract/ResultExtractor/VectorResultExtractorTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Tests\Contract\ResultExtractor; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\TestCase; +use Symfony\AI\Platform\Contract\ResultExtractor\VectorResultExtractor; +use Symfony\Component\JsonPath\JsonCrawler; + +#[CoversClass(VectorResultExtractor::class)] +final class VectorResultExtractorTest extends TestCase +{ + public function testStandardSuccess() + { + $json = file_get_contents(\dirname(__DIR__).'/fixtures/embeddings-standard-success.json'); + + $extractor = new VectorResultExtractor(); + + $actual = $extractor->extract(new JsonCrawler($json)); + $this->assertCount(1, $actual); + $this->assertCount(1, $actual[0]->getContent()); + $this->assertSame(5, $actual[0]->getContent()[0]->getDimensions()); + } + + public function testSpecificSuccess() + { + $json = file_get_contents(\dirname(__DIR__).'/fixtures/embeddings-specific-success.json'); + + $extractor = new VectorResultExtractor('$.embeddings[*].values'); + + $actual = $extractor->extract(new JsonCrawler($json)); + $this->assertCount(1, $actual); + $this->assertCount(1, $actual[0]->getContent()); + $this->assertSame(6, $actual[0]->getContent()[0]->getDimensions()); + } +} diff --git a/src/platform/tests/Contract/fixtures/embeddings-specific-success.json b/src/platform/tests/Contract/fixtures/embeddings-specific-success.json new file mode 100644 index 00000000..00f0bed2 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/embeddings-specific-success.json @@ -0,0 +1,14 @@ +{ + "embeddings": [ + { + "values": [ + 0.003826603, + -0.0008243268, + 0.016683463, + -0.08654552, + -0.0003032509, + 0.00097318884 + ] + } + ] +} diff --git a/src/platform/tests/Contract/fixtures/embeddings-standard-success.json b/src/platform/tests/Contract/fixtures/embeddings-standard-success.json new file mode 100644 index 00000000..d3374155 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/embeddings-standard-success.json @@ -0,0 +1,21 @@ +{ + "object": "list", + "data": [ + { + "object": "embedding", + "index": 0, + "embedding": [ + 0.013870293, + -0.024086641, + -0.017051745, + 0.059303116, + -0.038576424 + ] + } + ], + "model": "text-embedding-3-small", + "usage": { + "prompt_tokens": 64, + "total_tokens": 64 + } +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-chat.json b/src/platform/tests/Contract/fixtures/openai-response-chat.json new file mode 100644 index 00000000..646ab525 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-chat.json @@ -0,0 +1,36 @@ +{ + "id": "chatcmpl-Bxbzz33g2Hd5XBeM97CW7ST0Nm9PW", + "object": "chat.completion", + "created": 1753547119, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Arrr, matey! Symfony be a treasure of a framework for building web applications in PHP!", + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 26, + "completion_tokens": 193, + "total_tokens": 219, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_34a54ae93c" +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-choices.json b/src/platform/tests/Contract/fixtures/openai-response-choices.json new file mode 100644 index 00000000..13af4fc4 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-choices.json @@ -0,0 +1,58 @@ +{ + "id": "chatcmpl-BxdTNw2Um2TGqieRwqR84AgL3HVZd", + "object": "chat.completion", + "created": 1753552785, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "1 Arrr, matey! Symfony be a treasure chest of tools fer building web applications in PHP!", + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": "2 Arrr, my pirate! Symfony be a treasure chest of tools fer building web applications in PHP!", + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 2, + "message": { + "role": "assistant", + "content": "3 Ahoy there, matey! Symfony be a treasure chest of a framework for PHP", + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 26, + "completion_tokens": 701, + "total_tokens": 727, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_62a23a81ef" +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-error.json b/src/platform/tests/Contract/fixtures/openai-response-error.json new file mode 100644 index 00000000..4cbec310 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-error.json @@ -0,0 +1,8 @@ +{ + "error": { + "message": "Incorrect API key provided: sk-abcd****************************************6789. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-stream-chunks b/src/platform/tests/Contract/fixtures/openai-response-stream-chunks new file mode 100644 index 00000000..c2fb1cf4 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-stream-chunks @@ -0,0 +1,607 @@ +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" purpose"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" an"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" that"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" any"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" living"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" organism"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" be"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" understood"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" various"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" perspectives"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"—"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"bi"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ecological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" philosophical"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" **"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"Bi"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Perspective"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"**"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" From"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" biological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" standpoint"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ants"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" all"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" organisms"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" exist"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" primarily"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" survive"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" reproduce"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" pass"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" their"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" genetic"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" material"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Each"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" plays"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" role"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" colony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" lifecycle"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" contributing"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" tasks"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" such"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"aging"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" food"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" caring"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" queen"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" larvae"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" defending"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" nest"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" maintaining"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" its"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" environment"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" **"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"Ec"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Perspective"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"**"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Ant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"s"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" hold"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" significant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" roles"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" their"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ecosystems"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" They"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" help"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" soil"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" aer"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ation"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" decomposition"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" nutrient"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" cycling"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Ant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"s"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" act"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" seed"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" dispers"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ers"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" aiding"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" plant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" reproduction"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" transporting"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" seeds"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" away"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" parent"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" plant"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" which"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" enhance"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" biodiversity"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Additionally"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" they"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" serve"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" prey"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" various"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" animals"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" thereby"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" contributing"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" food"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" web"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" **"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"Ph"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ilos"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"oph"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ical"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Perspective"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"**"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" From"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" philosophical"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" angle"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" considering"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" \""},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"purpose"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"\""},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ants"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" touches"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" deeper"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" questions"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" meaning"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" value"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" nature"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" Some"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" might"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" argue"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" that"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" every"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" living"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" being"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" has"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" intrinsic"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" value"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" regardless"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" its"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" utility"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" humans"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" behaviors"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" social"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" structures"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ants"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" reflect"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" complex"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" forms"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" cooperation"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" community"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" prompting"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" discussions"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" about"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" altru"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ism"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" individuality"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" interconnected"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ness"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" life"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"In"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" summary"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" while"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ants"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" serve"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" critical"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" functions"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" ecosystems"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" contribute"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" biological"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" diversity"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" our"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" planet"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" question"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" their"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" \""},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"purpose"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"\""},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" be"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" expansive"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" lead"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" broader"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" contempl"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"ations"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" about"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" life"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" existence"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" our"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" place"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":" world"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc3yELRbA9xSZSYgj1iem873Y036","object":"chat.completion.chunk","created":1753547366,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_62a23a81ef","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + +data: [DONE] diff --git a/src/platform/tests/Contract/fixtures/openai-response-stream-toolcall-chunks b/src/platform/tests/Contract/fixtures/openai-response-stream-toolcall-chunks new file mode 100644 index 00000000..57c1171d --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-stream-toolcall-chunks @@ -0,0 +1,406 @@ +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_xG5e2wujAmDl8aRv4zo0bSio","type":"function","function":{"name":"youtube_transcript","arguments":""}}],"refusal":null},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"video"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Id"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"6"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"u"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"X"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"W"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"-"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ulp"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"j"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"0"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"s"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7rF9K5efpvSIdpEu9HYAn3MSDw","object":"chat.completion.chunk","created":1753547607,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" video"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" discusses"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" advantages"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" PHP"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" framework"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" emphasizing"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" that"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" about"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"80"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"%"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" websites"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" use"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" PHP"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" server"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"-side"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" language"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Learning"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" not"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" only"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" enhances"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" PHP"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" skills"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" but"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" introduces"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" various"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" software"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" architecture"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" patterns"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" applicable"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" across"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" different"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" programming"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" languages"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" speaker"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" shares"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" personal"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" success"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" story"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" where"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" software"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" architecture"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" helped"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" them"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" secure"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" job"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" that"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" required"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" work"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" C"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"#"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" through"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" an"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" understanding"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" gained"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" video"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" highlights"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" that"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" full"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"-stack"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" framework"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" enabling"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" creation"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" deployment"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" applications"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" both"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" front"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"-end"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" technologies"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" ("},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"like"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" HTML"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" CSS"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Java"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"Script"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":")"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" back"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"-end"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" components"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" ("},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"like"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" PHP"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" databases"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":")."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" integrate"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" modern"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Java"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"Script"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" frameworks"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" such"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Vue"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":".js"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" React"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":".js"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" It"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" features"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" powerful"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" CLI"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" tool"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" building"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" debugging"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" generating"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" code"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" speaker"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" comm"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"ends"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" Symfony"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" excellent"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" documentation"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" which"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" beneficial"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" newcomers"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" \n\n"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" video"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" concludes"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" encouraging"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" viewers"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" engage"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" channel"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" its"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":" content"},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + +data: {"id":"chatcmpl-Bxc7tsf8N50WhcCiH91VkYx12Y2jO","object":"chat.completion.chunk","created":1753547609,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_34a54ae93c","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + +data: [DONE] + diff --git a/src/platform/tests/Contract/fixtures/openai-response-toolcall-choices.json b/src/platform/tests/Contract/fixtures/openai-response-toolcall-choices.json new file mode 100644 index 00000000..1e9c4136 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-toolcall-choices.json @@ -0,0 +1,67 @@ +{ + "id": "chatcmpl-Bxc1qPiJMaVsgyKm5OxsryT7zqCDQ", + "object": "chat.completion", + "created": 1753547234, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_1234", + "type": "function", + "function": { + "name": "my_tool", + "arguments": "{\"myParam\":\"abcdefg\"}" + } + } + ], + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "tool_calls" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_4321", + "type": "function", + "function": { + "name": "my_tool_two", + "arguments": "{\"foo\":\"bar\"}" + } + } + ], + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 82, + "completion_tokens": 24, + "total_tokens": 106, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_34a54ae93c" +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-toolcall-multiple.json b/src/platform/tests/Contract/fixtures/openai-response-toolcall-multiple.json new file mode 100644 index 00000000..5ba5594a --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-toolcall-multiple.json @@ -0,0 +1,54 @@ +{ + "id": "chatcmpl-Bxc1qPiJMaVsgyKm5OxsryT7zqCDQ", + "object": "chat.completion", + "created": 1753547234, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_1234", + "type": "function", + "function": { + "name": "my_tool", + "arguments": "{\"myParam\":\"abcdefg\"}" + } + }, + { + "id": "call_2345", + "type": "function", + "function": { + "name": "foo_bar", + "arguments": "{\"foo\":\"bar\"}" + } + } + ], + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 82, + "completion_tokens": 24, + "total_tokens": 106, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_34a54ae93c" +} diff --git a/src/platform/tests/Contract/fixtures/openai-response-toolcall.json b/src/platform/tests/Contract/fixtures/openai-response-toolcall.json new file mode 100644 index 00000000..2bba4573 --- /dev/null +++ b/src/platform/tests/Contract/fixtures/openai-response-toolcall.json @@ -0,0 +1,46 @@ +{ + "id": "chatcmpl-Bxc1qPiJMaVsgyKm5OxsryT7zqCDQ", + "object": "chat.completion", + "created": 1753547234, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_1234", + "type": "function", + "function": { + "name": "my_tool", + "arguments": "{\"myParam\":\"abcdefg\"}" + } + } + ], + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 82, + "completion_tokens": 24, + "total_tokens": 106, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_34a54ae93c" +}