103 lines
2.7 KiB
PHP
103 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ContextPaging;
|
|
|
|
use GuzzleHttp\Psr7\ServerRequest;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
/**
|
|
* Extended ServerRequest with context size tracking.
|
|
*/
|
|
class ContextRequest extends ServerRequest
|
|
{
|
|
private ?TokenCounter $tokenCounter = null;
|
|
|
|
/**
|
|
* Create from a standard ServerRequestInterface.
|
|
*/
|
|
public static function fromRequest(ServerRequestInterface $request): self
|
|
{
|
|
return new self(
|
|
method: $request->getMethod(),
|
|
uri: $request->getUri(),
|
|
headers: $request->getHeaders(),
|
|
body: $request->getBody(),
|
|
version: $request->getProtocolVersion(),
|
|
serverParams: $request->getServerParams()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Set the token counter instance.
|
|
*/
|
|
public function withTokenCounter(TokenCounter $counter): self
|
|
{
|
|
$new = clone $this;
|
|
$new->tokenCounter = $counter;
|
|
return $new;
|
|
}
|
|
|
|
/**
|
|
* Get the token counter (lazy-load default if not set).
|
|
*/
|
|
public function getTokenCounter(): TokenCounter
|
|
{
|
|
if ($this->tokenCounter === null) {
|
|
$this->tokenCounter = new TokenCounter();
|
|
}
|
|
return $this->tokenCounter;
|
|
}
|
|
|
|
/**
|
|
* Calculate and store context size for the given messages.
|
|
*
|
|
* @param array $messages Array of ['role' => '...', 'content' => '...']
|
|
* @param string $encoding Encoding name (cl100k_base or o200k_base).
|
|
* @param int $perMessage Overhead tokens per message.
|
|
* @param int $replyPrimer Tokens added after all messages.
|
|
* @return self New request instance with context_size attribute.
|
|
*/
|
|
public function contextSize(
|
|
array $messages,
|
|
string $encoding = 'cl100k_base',
|
|
int $perMessage = 4,
|
|
int $replyPrimer = 3
|
|
): self {
|
|
$count = $this->getTokenCounter()->contextSize(
|
|
$messages,
|
|
$encoding,
|
|
$perMessage,
|
|
$replyPrimer
|
|
);
|
|
|
|
return $this->withAttribute('context_size', [
|
|
'tokens' => $count,
|
|
'encoding' => $encoding,
|
|
'message_count' => count($messages),
|
|
'per_message' => $perMessage,
|
|
'reply_primer' => $replyPrimer,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get the stored context size, if any.
|
|
*
|
|
* @return array|null ['tokens' => int, 'encoding' => string, ...]
|
|
*/
|
|
public function getContextSize(): ?array
|
|
{
|
|
return $this->getAttribute('context_size');
|
|
}
|
|
|
|
/**
|
|
* Get just the token count from stored context size.
|
|
*/
|
|
public function getContextTokenCount(): ?int
|
|
{
|
|
$ctx = $this->getContextSize();
|
|
return $ctx['tokens'] ?? null;
|
|
}
|
|
}
|