p67
This commit is contained in:
@@ -700,6 +700,17 @@ final readonly class AgentRunner
|
||||
'meta'
|
||||
);
|
||||
|
||||
$followUpActionsMessage = $this->buildFollowUpActionsMessage(
|
||||
isCommerceIntent: $this->isCommerceIntent($commerceIntent),
|
||||
hasShopResults: $shopResults !== [],
|
||||
hasKnowledge: $this->isDirectKnowledgeEvidence($knowledgeEvidenceState),
|
||||
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure
|
||||
);
|
||||
|
||||
if ($followUpActionsMessage !== '') {
|
||||
yield $this->systemMsg($followUpActionsMessage, 'meta');
|
||||
}
|
||||
|
||||
/* if ($sources !== []) {
|
||||
yield $this->emitSources(
|
||||
$sources,
|
||||
@@ -4850,20 +4861,27 @@ final readonly class AgentRunner
|
||||
return $this->agentRunnerConfig->getProductionUiTemplate('relevance_default');
|
||||
}
|
||||
|
||||
private function buildFollowUpActionsMessage(bool $isCommerceIntent, bool $hasShopResults, bool $hasKnowledge): string
|
||||
{
|
||||
if (!$isCommerceIntent && !$hasShopResults && !$hasKnowledge) {
|
||||
private function buildFollowUpActionsMessage(
|
||||
bool $isCommerceIntent,
|
||||
bool $hasShopResults,
|
||||
bool $hasKnowledge,
|
||||
bool $shopSearchHadSystemFailure
|
||||
): string {
|
||||
if (!$this->agentRunnerConfig->isProductionUiFollowUpActionsEnabled()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$actions = [];
|
||||
$seenActionKeys = [];
|
||||
|
||||
if ($isCommerceIntent || $hasShopResults) {
|
||||
$actions = array_merge($actions, $this->agentRunnerConfig->getProductionUiFollowUpActions('commerce'));
|
||||
if ($hasShopResults) {
|
||||
$this->appendFollowUpActions($actions, $seenActionKeys, $this->agentRunnerConfig->getProductionUiFollowUpActions('shop_results'));
|
||||
} elseif ($isCommerceIntent && !$shopSearchHadSystemFailure) {
|
||||
$this->appendFollowUpActions($actions, $seenActionKeys, $this->agentRunnerConfig->getProductionUiFollowUpActions('commerce'));
|
||||
}
|
||||
|
||||
if ($hasKnowledge || $hasShopResults) {
|
||||
$actions = array_merge($actions, $this->agentRunnerConfig->getProductionUiFollowUpActions('knowledge'));
|
||||
if ($hasKnowledge) {
|
||||
$this->appendFollowUpActions($actions, $seenActionKeys, $this->agentRunnerConfig->getProductionUiFollowUpActions('knowledge'));
|
||||
}
|
||||
|
||||
if ($actions === []) {
|
||||
@@ -4876,15 +4894,10 @@ final readonly class AgentRunner
|
||||
. '<div class="retriex-action-chip-row">';
|
||||
|
||||
foreach ($actions as $action) {
|
||||
$label = (string) ($action['label'] ?? '');
|
||||
$actionPrompt = (string) ($action['prompt'] ?? '');
|
||||
if ($label === '' || $actionPrompt === '') {
|
||||
continue;
|
||||
}
|
||||
$html .= '<button type="button" class="retriex-action-chip" data-retriex-action-prompt="'
|
||||
. htmlspecialchars($actionPrompt, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
|
||||
. htmlspecialchars($action['prompt'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
|
||||
. '">'
|
||||
. htmlspecialchars($label, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
|
||||
. htmlspecialchars($action['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
|
||||
. '</button>';
|
||||
}
|
||||
|
||||
@@ -4893,6 +4906,34 @@ final readonly class AgentRunner
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{label:string, prompt:string}> $actions
|
||||
* @param array<string, bool> $seenActionKeys
|
||||
* @param array<int, array{label:string, prompt:string}> $items
|
||||
*/
|
||||
private function appendFollowUpActions(array &$actions, array &$seenActionKeys, array $items): void
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$label = trim((string) ($item['label'] ?? ''));
|
||||
$actionPrompt = trim((string) ($item['prompt'] ?? ''));
|
||||
|
||||
if ($label === '' || $actionPrompt === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = mb_strtolower($label . "\n" . $actionPrompt, 'UTF-8');
|
||||
if (isset($seenActionKeys[$key])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$seenActionKeys[$key] = true;
|
||||
$actions[] = [
|
||||
'label' => $label,
|
||||
'prompt' => $actionPrompt,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private function buildShopSearchMetaMessage(
|
||||
string $query,
|
||||
string $commerceIntent,
|
||||
|
||||
@@ -979,12 +979,23 @@ final class AgentRunnerConfig
|
||||
return $this->getRequiredInt('production_ui.shop_results.max_cards');
|
||||
}
|
||||
|
||||
public function isProductionUiFollowUpActionsEnabled(): bool
|
||||
{
|
||||
if ($this->chatMessages !== null) {
|
||||
return $this->chatMessages->getBool('agent.production_ui.follow_up_actions.enabled');
|
||||
}
|
||||
|
||||
return $this->getOptionalBool('production_ui.follow_up_actions.enabled', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{label:string, prompt:string}>
|
||||
*/
|
||||
public function getProductionUiFollowUpActions(string $group): array
|
||||
{
|
||||
return $this->getChatActionList('agent.production_ui.follow_up_actions.' . $group, 'production_ui.follow_up_actions.' . $group);
|
||||
$legacyGroup = $group === 'shop_results' ? 'commerce' : $group;
|
||||
|
||||
return $this->getChatActionList('agent.production_ui.follow_up_actions.' . $group, 'production_ui.follow_up_actions.' . $legacyGroup);
|
||||
}
|
||||
|
||||
public function getNoLlmProductField(string $key): string
|
||||
|
||||
@@ -172,6 +172,11 @@ final class ChatMessagesConfig
|
||||
throw new \InvalidArgumentException(sprintf('RetrieX chat messages config key "%s" must be a string.', $path));
|
||||
}
|
||||
|
||||
public function getBool(string $path): bool
|
||||
{
|
||||
return $this->bool($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{label:string, prompt:string}>
|
||||
*/
|
||||
@@ -211,6 +216,14 @@ final class ChatMessagesConfig
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->requiredBoolPaths() as $path) {
|
||||
try {
|
||||
$this->bool($path);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$errors[] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->requiredActionListPaths() as $path) {
|
||||
try {
|
||||
$this->actionList($path);
|
||||
@@ -443,10 +456,21 @@ final class ChatMessagesConfig
|
||||
{
|
||||
return [
|
||||
'agent.production_ui.follow_up_actions.commerce',
|
||||
'agent.production_ui.follow_up_actions.shop_results',
|
||||
'agent.production_ui.follow_up_actions.knowledge',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
private function requiredBoolPaths(): array
|
||||
{
|
||||
return [
|
||||
'agent.production_ui.follow_up_actions.enabled',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
@@ -566,6 +590,29 @@ final class ChatMessagesConfig
|
||||
throw new \InvalidArgumentException(sprintf('RetrieX chat messages config key "%s" must be a non-empty string.', $path));
|
||||
}
|
||||
|
||||
private function bool(string $path): bool
|
||||
{
|
||||
$value = $this->value($path);
|
||||
|
||||
if (is_bool($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_scalar($value)) {
|
||||
$normalized = strtolower(trim((string) $value));
|
||||
|
||||
if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($normalized, ['0', 'false', 'no', 'off'], true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('RetrieX chat messages config key "%s" must be boolean.', $path));
|
||||
}
|
||||
|
||||
private function value(string $path): mixed
|
||||
{
|
||||
$current = $this->config;
|
||||
|
||||
Reference in New Issue
Block a user