Initial commit
This commit is contained in:
135
src/LLMSummarizer.php
Normal file
135
src/LLMSummarizer.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ContextPaging;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* LLM-backed summarizer using OpenAI-compatible API.
|
||||
*/
|
||||
class LLMSummarizer implements SummarizerInterface
|
||||
{
|
||||
private CompletionsClientInterface $client;
|
||||
private string $model;
|
||||
private string $systemPrompt;
|
||||
private int $maxTokens;
|
||||
private float $temperature;
|
||||
|
||||
/**
|
||||
* @param CompletionsClientInterface $client The LLM client
|
||||
* @param string $model Model to use for summarization
|
||||
* @param string $systemPrompt System prompt for summarization
|
||||
* @param int $maxTokens Max tokens for summary output
|
||||
* @param float $temperature Temperature for generation
|
||||
*/
|
||||
public function __construct(
|
||||
CompletionsClientInterface $client,
|
||||
string $model = 'HuggingFaceTB/SmolLM3-3B',
|
||||
string $systemPrompt = 'You are a summarization assistant. Summarize the given text concisely, preserving key information. Be brief but comprehensive.',
|
||||
int $maxTokens = 200,
|
||||
float $temperature = 0.3
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->model = $model;
|
||||
$this->systemPrompt = $systemPrompt;
|
||||
$this->maxTokens = $maxTokens;
|
||||
$this->temperature = $temperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a summary of the content.
|
||||
*
|
||||
* @param string $content The content to summarize
|
||||
* @param array $context Optional context (role, previous messages, etc.)
|
||||
* @return string The summary
|
||||
*/
|
||||
public function summarize(string $content, array $context = []): string
|
||||
{
|
||||
// Build the prompt
|
||||
$userPrompt = $this->buildUserPrompt($content, $context);
|
||||
|
||||
$messages = [
|
||||
['role' => 'system', 'content' => $this->systemPrompt],
|
||||
['role' => 'user', 'content' => $userPrompt],
|
||||
];
|
||||
|
||||
$response = $this->client->chat($messages, [
|
||||
'model' => $this->model,
|
||||
'max_tokens' => $this->maxTokens,
|
||||
'temperature' => $this->temperature,
|
||||
]);
|
||||
|
||||
return $this->extractContent($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the user prompt for summarization.
|
||||
*/
|
||||
private function buildUserPrompt(string $content, array $context): string
|
||||
{
|
||||
$role = $context['role'] ?? 'unknown';
|
||||
$instruction = $context['instruction'] ?? 'Summarize in 2-3 sentences:';
|
||||
|
||||
$prompt = "{$instruction}\n\n";
|
||||
|
||||
if ($role !== 'unknown') {
|
||||
$prompt .= "[Role: {$role}]\n";
|
||||
}
|
||||
|
||||
$prompt .= $content;
|
||||
|
||||
return $prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract content from the response.
|
||||
*/
|
||||
private function extractContent(ResponseInterface $response): string
|
||||
{
|
||||
$body = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
if (!isset($body['choices'][0]['message']['content'])) {
|
||||
throw new \RuntimeException('No content in summarizer response');
|
||||
}
|
||||
|
||||
return trim($body['choices'][0]['message']['content']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model.
|
||||
*/
|
||||
public function setModel(string $model): self
|
||||
{
|
||||
$this->model = $model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max tokens for output.
|
||||
*/
|
||||
public function setMaxTokens(int $maxTokens): self
|
||||
{
|
||||
$this->maxTokens = $maxTokens;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the temperature.
|
||||
*/
|
||||
public function setTemperature(float $temperature): self
|
||||
{
|
||||
$this->temperature = $temperature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the system prompt.
|
||||
*/
|
||||
public function setSystemPrompt(string $prompt): self
|
||||
{
|
||||
$this->systemPrompt = $prompt;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user