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
+7 -1
View File
@@ -11,5 +11,11 @@ $language = dbnToolsNormalizeLanguage($input['language'] ?? 'en');
dbnToolsWithTelemetry('search', $language, function () use ($input, $language): array { dbnToolsWithTelemetry('search', $language, function () use ($input, $language): array {
$query = dbnToolsString($input, 'query', 2000); $query = dbnToolsString($input, 'query', 2000);
$limit = max(1, min(10, (int)($input['limit'] ?? 6))); $limit = max(1, min(10, (int)($input['limit'] ?? 6)));
return (new DbnLegalToolsService())->search($query, $language, $limit); $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);
}); });
+26 -2
View File
@@ -15,13 +15,19 @@ final class DbnLegalToolsService
$this->azure = $azure ?: new DbnAzureOpenAiGateway(); $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); $query = trim($query);
if (mb_strlen($query, 'UTF-8') < 3) { if (mb_strlen($query, 'UTF-8') < 3) {
dbnToolsAbort('Search query must be at least 3 characters.', 422, 'query_too_short'); dbnToolsAbort('Search query must be at least 3 characters.', 422, 'query_too_short');
} }
$limit = max(1, min(10, $limit)); $limit = max(1, min(10, $limit));
$temporalMode = in_array($temporalMode, ['legal_conservative', 'disabled'], true) ? $temporalMode : 'disabled';
$trace = [ $trace = [
$this->trace('Query interpretation', 'Searching Do Better Norge private corpus plus the subscribed family-legal package.', 'complete'), $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, 'min_private' => 0,
'include_beta_website' => true, '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) { } catch (Throwable $e) {
$retrievalNote = 'SQL keyword fallback after ClientRagPipeline error'; $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'); $trace[] = $this->trace('Search fallback', 'Pipeline retrieval failed; using direct SQL keyword fallback without storing the query.', 'warning');
@@ -493,6 +509,14 @@ PROMPT;
'section' => $chunk['section_title'] ?? null, 'section' => $chunk['section_title'] ?? null,
'authority_type' => $chunk['authority_type'] ?? null, 'authority_type' => $chunk['authority_type'] ?? null,
'jurisdiction' => $chunk['jurisdiction'] ?? 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,
]; ];
} }