fix p46
This commit is contained in:
@@ -3006,6 +3006,15 @@ final readonly class AgentRunner
|
||||
return $shopResults;
|
||||
}
|
||||
|
||||
return $this->sortDecoratedShopProductsByLength($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{index: int, length: float|null, product: mixed}> $decorated
|
||||
* @return ShopProductResult[]
|
||||
*/
|
||||
private function sortDecoratedShopProductsByLength(array $decorated): array
|
||||
{
|
||||
usort($decorated, static function (array $a, array $b): int {
|
||||
if ($a['length'] === null && $b['length'] === null) {
|
||||
return $a['index'] <=> $b['index'];
|
||||
@@ -3041,6 +3050,112 @@ final readonly class AgentRunner
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{type: string, value: float}|null
|
||||
*/
|
||||
private function resolveShopResultLengthFilter(string $prompt, string $shopSearchQuery): ?array
|
||||
{
|
||||
if (!$this->agentRunnerConfig->isShopResultLengthFilterEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$text = trim($prompt . ' ' . $shopSearchQuery);
|
||||
if ($text === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->agentRunnerConfig->getShopResultMinLengthFilterPatterns() as $pattern) {
|
||||
$value = $this->extractShopLengthFilterPatternValue($pattern, $text);
|
||||
if ($value !== null) {
|
||||
return ['type' => 'min', 'value' => $value];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->agentRunnerConfig->getShopResultMaxLengthFilterPatterns() as $pattern) {
|
||||
$value = $this->extractShopLengthFilterPatternValue($pattern, $text);
|
||||
if ($value !== null) {
|
||||
return ['type' => 'max', 'value' => $value];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function extractShopLengthFilterPatternValue(string $pattern, string $text): ?float
|
||||
{
|
||||
if (@preg_match($pattern, $text, $matches) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = $matches['value'] ?? ($matches[1] ?? null);
|
||||
if (!is_scalar($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$normalized = str_replace(',', '.', (string) $value);
|
||||
if (!is_numeric($normalized)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (float) $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShopProductResult[] $shopResults
|
||||
* @param array{type: string, value: float} $lengthFilter
|
||||
* @return ShopProductResult[]
|
||||
*/
|
||||
private function filterDirectShopAnswerResultsByLength(array $shopResults, array $lengthFilter): array
|
||||
{
|
||||
$decorated = [];
|
||||
|
||||
foreach (array_values($shopResults) as $index => $product) {
|
||||
if (!$product instanceof ShopProductResult) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$length = $this->extractShopProductLengthMeters($product);
|
||||
if ($length === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($lengthFilter['type'] === 'min' && $length < $lengthFilter['value'])
|
||||
|| ($lengthFilter['type'] === 'max' && $length > $lengthFilter['value'])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$decorated[] = [
|
||||
'index' => $index,
|
||||
'length' => $length,
|
||||
'product' => $product,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->sortDecoratedShopProductsByLength($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{type: string, value: float} $lengthFilter
|
||||
*/
|
||||
private function buildDirectShopAnswerLengthFilterNote(array $lengthFilter): string
|
||||
{
|
||||
$template = $lengthFilter['type'] === 'max'
|
||||
? $this->agentRunnerConfig->getDirectShopResultAnswerMaxLengthFilterNote()
|
||||
: $this->agentRunnerConfig->getDirectShopResultAnswerMinLengthFilterNote();
|
||||
|
||||
return str_replace('{value}', $this->formatShopLengthFilterValue($lengthFilter['value']), $template);
|
||||
}
|
||||
|
||||
private function formatShopLengthFilterValue(float $value): string
|
||||
{
|
||||
if (abs($value - round($value)) < 0.00001) {
|
||||
return (string) (int) round($value);
|
||||
}
|
||||
|
||||
return rtrim(rtrim(str_replace('.', ',', sprintf('%.2F', $value)), '0'), ',');
|
||||
}
|
||||
|
||||
private function extractShopProductLengthMeters(ShopProductResult $product): ?float
|
||||
{
|
||||
$text = trim(implode(' ', array_filter([
|
||||
@@ -3153,13 +3268,26 @@ final readonly class AgentRunner
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($shopResults === []) {
|
||||
$answerShopResults = $shopResults;
|
||||
$lengthFilter = $this->resolveShopResultLengthFilter($prompt, $shopSearchQuery);
|
||||
if ($lengthFilter !== null) {
|
||||
$answerShopResults = $this->filterDirectShopAnswerResultsByLength($answerShopResults, $lengthFilter);
|
||||
}
|
||||
|
||||
if ($answerShopResults === []) {
|
||||
return $this->agentRunnerConfig->getDirectShopResultAnswerNoResultsMessage();
|
||||
}
|
||||
|
||||
$lines = [$this->agentRunnerConfig->getDirectShopResultAnswerIntro()];
|
||||
|
||||
if ($this->isShopResultLengthSortRequested($prompt . ' ' . $shopSearchQuery)) {
|
||||
if ($lengthFilter !== null) {
|
||||
$note = trim($this->buildDirectShopAnswerLengthFilterNote($lengthFilter));
|
||||
if ($note !== '') {
|
||||
$lines[] = $note;
|
||||
}
|
||||
}
|
||||
|
||||
if ($lengthFilter !== null || $this->isShopResultLengthSortRequested($prompt . ' ' . $shopSearchQuery)) {
|
||||
$note = trim($this->agentRunnerConfig->getDirectShopResultAnswerSortedByLengthNote());
|
||||
if ($note !== '') {
|
||||
$lines[] = $note;
|
||||
@@ -3167,7 +3295,7 @@ final readonly class AgentRunner
|
||||
}
|
||||
|
||||
$lines[] = '';
|
||||
foreach ($this->buildDirectShopProductLines($shopResults, 'accessory_or_consumable') as $line) {
|
||||
foreach ($this->buildDirectShopProductLines($answerShopResults, 'accessory_or_consumable') as $line) {
|
||||
$lines[] = $line;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user