62 lines
1.2 KiB
PHP
62 lines
1.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Agent;
|
|
|
|
final class StreamChunker
|
|
{
|
|
private string $buffer = '';
|
|
private bool $insideCodeBlock = false;
|
|
private int $minChunkSize = 120;
|
|
|
|
public function push(string $token): ?string
|
|
{
|
|
$this->buffer .= $token;
|
|
|
|
if (str_contains($token, '```')) {
|
|
$this->insideCodeBlock = !$this->insideCodeBlock;
|
|
}
|
|
|
|
if ($this->shouldFlush()) {
|
|
$out = $this->buffer;
|
|
$this->buffer = '';
|
|
return $out;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function flush(): ?string
|
|
{
|
|
if ($this->buffer === '') {
|
|
return null;
|
|
}
|
|
|
|
$out = $this->buffer;
|
|
$this->buffer = '';
|
|
return $out;
|
|
}
|
|
|
|
private function shouldFlush(): bool
|
|
{
|
|
if ($this->insideCodeBlock) {
|
|
return false;
|
|
}
|
|
|
|
if (str_ends_with($this->buffer, "\n\n")) {
|
|
return true;
|
|
}
|
|
|
|
if (preg_match('/[.!?]\s$/', $this->buffer)) {
|
|
return true;
|
|
}
|
|
|
|
if (preg_match('/\n[-*] .+\n$/', $this->buffer)) {
|
|
return true;
|
|
}
|
|
|
|
return mb_strlen($this->buffer) >= $this->minChunkSize;
|
|
}
|
|
}
|