feat: add MCP server for the website chatbot over a mirrored TYPO3 content feed
This commit is contained in:
1 parent
ff7ddf7a9e
commit
1b4384e3f3
52 files changed
+5117
-4
No files matched your search
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Chatbot\Search;
|
||||
|
||||
/**
|
||||
* Cuts a window of about LENGTH characters out of a document, around its first match.
|
||||
*
|
||||
* The excerpt keeps search results small; get_document fetches the rest.
|
||||
*/
|
||||
final class Excerpt
|
||||
{
|
||||
public const LENGTH = 600;
|
||||
|
||||
/**
|
||||
* @param list<string> $terms lower-cased, matched as prefixes like the full-text search
|
||||
*/
|
||||
public static function around(string $text, array $terms, int $length = self::LENGTH): string
|
||||
{
|
||||
$text = trim((string) preg_replace('/\s+/u', ' ', $text));
|
||||
$textLength = mb_strlen($text);
|
||||
|
||||
if ($textLength <= $length) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$position = null;
|
||||
$lower = mb_strtolower($text);
|
||||
foreach ($terms as $term) {
|
||||
$found = mb_strpos($lower, $term);
|
||||
if (false !== $found && (null === $position || $found < $position)) {
|
||||
$position = $found;
|
||||
}
|
||||
}
|
||||
|
||||
// Start a third of the window before the match, so it is read in context.
|
||||
$start = max(0, min(($position ?? 0) - intdiv($length, 3), $textLength - $length));
|
||||
$excerpt = mb_substr($text, $start, $length);
|
||||
|
||||
if ($start > 0) {
|
||||
$space = mb_strpos($excerpt, ' ');
|
||||
$excerpt = '…'.(false !== $space && $space < 40 ? mb_substr($excerpt, $space + 1) : $excerpt);
|
||||
}
|
||||
|
||||
if ($start + $length < $textLength) {
|
||||
$space = mb_strrpos($excerpt, ' ');
|
||||
$excerpt = (false !== $space && mb_strlen($excerpt) - $space < 40 ? mb_substr($excerpt, 0, $space) : $excerpt).'…';
|
||||
}
|
||||
|
||||
return $excerpt;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user