Files
context-paging/src/ContextRequest.php
2026-03-28 09:01:07 +00:00

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;
}
}