feat(tools): persona selector across standalone tools + dashboard chat

Wire the legal-domain persona picker into corpus, deep-research, korrespond and
the dashboard chat. Each endpoint reads the chosen profile, resolves its packages
against client 57, and scopes retrieval via package_ids (falling back to family
when omitted). New dashboard tenants now subscribe to all DBN domain packages so
persona switching survives the subscription intersection.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 23:03:31 +02:00
parent 662fbf7d6d
commit d156f8cf6b
13 changed files with 251 additions and 20 deletions
+12 -3
View File
@@ -36,7 +36,8 @@ final class DbnDeepResearchAgent
string $advocateRole = '',
?array $priorContext = null,
string $branchNotes = '',
array $subQuestionsOverride = []
array $subQuestionsOverride = [],
?string $persona = null
): array {
$seedQuery = trim($seedQuery);
$pastedText = trim($pastedText);
@@ -50,7 +51,15 @@ final class DbnDeepResearchAgent
}
$client = dbnToolsRequireClient();
$package = $this->requireFamilyPackage((int)$client['id']);
$personaResolved = dbnToolsResolvePersona((int)$client['id'], $persona);
$packageIds = array_values(array_filter(
array_map('intval', $personaResolved['package_ids'] ?? []),
static fn(int $id): bool => $id > 0
));
if (!$packageIds) {
// Persona resolved without a package → fall back to the legacy family package.
$packageIds = [(int)$this->requireFamilyPackage((int)$client['id'])['id']];
}
dbnToolsBootCaveau();
$aiPortalRoot = dbnToolsAiPortalRoot();
@@ -230,7 +239,7 @@ final class DbnDeepResearchAgent
[
'search_private' => false,
'search_shared' => true,
'package_ids' => [(int)$package['id']],
'package_ids' => $packageIds,
'shared_doc_ids' => $sharedDocIds,
'chunk_limit' => $controls['chunk_limit'],
'search_method' => 'hybrid',