| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- <?php
- declare(strict_types=1);
- namespace App\Helpers;
- use App\Enums\Status;
- final class ChunkParser
- {
- public string $chunk = '';
- private string $buffer = '';
- private array $results = [];
- public function __construct(private readonly array $tags = ['think', 'content', 'fields'], private readonly string $name = 'inference_rag_')
- {
- foreach ($this->tags as $tag) {
- $this->results[$tag] = null;
- }
- }
- public function append(string $chunk): self
- {
- $this->chunk = $chunk;
- $this->buffer .= $chunk;
- return $this;
- }
- public function parse(): self
- {
- if ($this->buffer === '') {
- return $this;
- }
- foreach ($this->tags as $tag) {
- $positions = $this->positions($this->buffer, $tag);
- if (count($positions) >= 1) {
- $length = strlen('<|' . $this->name . $tag . '|>');
- $content = substr($this->buffer, $positions[0] + $length, ($positions[1] ?? null) - $positions[0] - $length);
- $this->results[$tag] = $content;
- } else {
- $this->results[$tag] = null;
- }
- }
- return $this;
- }
- private function positions(string $buffer, string $tag): array
- {
- $pattern = "/<\\|" . $this->name . $tag . "\\|>/";
- $matches = [];
- preg_match_all($pattern, $buffer, $matches, PREG_OFFSET_CAPTURE);
- return !empty($matches[0]) ? array_column($matches[0], 1) : [];
- }
- public function all(): array
- {
- return $this->results;
- }
- public function toArray(): array
- {
- return ['think' => $this->think, 'content' => $this->content, 'fields' => $this->fields, 'status' => $this->getStatus()];
- }
- private function getStatus(): ?Status
- {
- if ($this->think && !$this->content) {
- return Status::Thinking;
- }
- if ($this->content) {
- return Status::Typing;
- }
- return null;
- }
- public function __get(string $tag)
- {
- if($tag === 'status') {
- return $this->getStatus();
- }
- $string = $this->results[$tag] ?? null;
- if ($tag === 'fields') {
- try {
- return json_decode($string, true);
- } catch (\Throwable) {
- return [];
- }
- }
- return $string;
- }
- }
|