feat: pass temporal_mode and as_of_date through DBN search API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 18:45:54 +02:00
parent 1f4f01bda3
commit 3c8d7ebc34
2 changed files with 45 additions and 15 deletions
+9 -3
View File
@@ -9,7 +9,13 @@ $input = dbnToolsJsonInput(12000);
$language = dbnToolsNormalizeLanguage($input['language'] ?? 'en');
dbnToolsWithTelemetry('search', $language, function () use ($input, $language): array {
$query = dbnToolsString($input, 'query', 2000);
$limit = max(1, min(10, (int)($input['limit'] ?? 6)));
return (new DbnLegalToolsService())->search($query, $language, $limit);
$query = dbnToolsString($input, 'query', 2000);
$limit = max(1, min(10, (int)($input['limit'] ?? 6)));
$temporalMode = in_array($input['temporal_mode'] ?? '', ['legal_conservative', 'disabled'], true)
? $input['temporal_mode']
: 'disabled';
$asOfDate = isset($input['as_of_date']) && preg_match('/^\d{4}(-\d{2}(-\d{2})?)?$/', $input['as_of_date'])
? $input['as_of_date']
: null;
return (new DbnLegalToolsService())->search($query, $language, $limit, $temporalMode, $asOfDate);
});
+36 -12
View File
@@ -15,13 +15,19 @@ final class DbnLegalToolsService
$this->azure = $azure ?: new DbnAzureOpenAiGateway();
}
public function search(string $query, string $language = 'en', int $limit = 6): array
{
public function search(
string $query,
string $language = 'en',
int $limit = 6,
string $temporalMode = 'disabled',
?string $asOfDate = null
): array {
$query = trim($query);
if (mb_strlen($query, 'UTF-8') < 3) {
dbnToolsAbort('Search query must be at least 3 characters.', 422, 'query_too_short');
}
$limit = max(1, min(10, $limit));
$temporalMode = in_array($temporalMode, ['legal_conservative', 'disabled'], true) ? $temporalMode : 'disabled';
$trace = [
$this->trace('Query interpretation', 'Searching Do Better Norge private corpus plus the subscribed family-legal package.', 'complete'),
@@ -56,6 +62,16 @@ final class DbnLegalToolsService
'min_private' => 0,
'include_beta_website' => true,
]);
// Apply temporal reranking after retrieval (optional)
if ($temporalMode === 'legal_conservative' && !empty($chunks)) {
$temporalLayerPath = __DIR__ . '/../../ai-portal/platform/includes/LegalTemporalLayer.php';
if (file_exists($temporalLayerPath)) {
require_once $temporalLayerPath;
$layer = new LegalTemporalLayer(['temporal_mode' => $temporalMode]);
$chunks = $layer->rerank($chunks, $query, $asOfDate);
}
}
} catch (Throwable $e) {
$retrievalNote = 'SQL keyword fallback after ClientRagPipeline error';
$trace[] = $this->trace('Search fallback', 'Pipeline retrieval failed; using direct SQL keyword fallback without storing the query.', 'warning');
@@ -483,16 +499,24 @@ PROMPT;
$score = isset($chunk['similarity']) ? round((float)$chunk['similarity'], 4) : null;
$rawExcerpt = dbnToolsExcerpt((string)($chunk['content'] ?? ''), 620);
return [
'title' => $title,
'excerpt' => $docSummary ?? $rawExcerpt,
'chunk_text' => $rawExcerpt,
'package_or_corpus' => (string)($chunk['source_name'] ?? $chunk['source_type'] ?? 'Do Better Norge'),
'score' => $score,
'document_id' => isset($chunk['document_id']) ? (int)$chunk['document_id'] : null,
'chunk_id' => isset($chunk['id']) ? (int)$chunk['id'] : null,
'section' => $chunk['section_title'] ?? null,
'authority_type' => $chunk['authority_type'] ?? null,
'jurisdiction' => $chunk['jurisdiction'] ?? null,
'title' => $title,
'excerpt' => $docSummary ?? $rawExcerpt,
'chunk_text' => $rawExcerpt,
'package_or_corpus' => (string)($chunk['source_name'] ?? $chunk['source_type'] ?? 'Do Better Norge'),
'score' => $score,
'document_id' => isset($chunk['document_id']) ? (int)$chunk['document_id'] : null,
'chunk_id' => isset($chunk['id']) ? (int)$chunk['id'] : null,
'section' => $chunk['section_title'] ?? null,
'authority_type' => $chunk['authority_type'] ?? null,
'jurisdiction' => $chunk['jurisdiction'] ?? null,
// Temporal annotations (present when temporal_mode = 'legal_conservative')
'temporal_state' => $chunk['temporal_state'] ?? null,
'temporal_kind' => $chunk['temporal_kind'] ?? null,
'temporal_reason' => $chunk['temporal_reason'] ?? null,
'currentness_warning' => $chunk['currentness_warning'] ?? null,
'valid_from' => $chunk['valid_from'] ?? null,
'valid_until' => $chunk['valid_until'] ?? null,
'is_current_version' => $chunk['is_current_version'] ?? null,
];
}