retrievals['knowledge_hits'] ?? []; $preferredDomain = (string) ($trace->plan['preferred_domain'] ?? ''); usort($knowledgeHits, static function (array $left, array $right) use ($preferredDomain) { $leftScore = (float) ($left['score'] ?? 0); $rightScore = (float) ($right['score'] ?? 0); if ($preferredDomain !== '') { if (($left['domain'] ?? '') === $preferredDomain) { $leftScore += 0.05; } if (($right['domain'] ?? '') === $preferredDomain) { $rightScore += 0.05; } } return $rightScore <=> $leftScore; }); $limit = max(1, min(12, (int) AiConfig::getVal('assistant_kb_topk', '6'))); $trace->rankedHits = array_slice($knowledgeHits, 0, $limit); $payload = AiAssistantContextService::composePayload( $trace->rankedHits, $trace->retrievals['match_items'] ?? [], $trace->retrievals['crypto_items'] ?? [], $trace->retrievals['web_news_items'] ?? [], $trace->plan ); $trace->finalSources = $payload['sources'] ?? []; $trace->contextText = (string) ($payload['context_text'] ?? '{}'); $trace->hasContext = !empty($payload['has_context']); return $trace; } }