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
+15 -7
View File
@@ -243,7 +243,7 @@ PROMPT;
*
* @return array Final result payload (matches NDJSON 'final' event shape).
*/
public function generate(array $intake, array $classify, ?callable $emit = null, string $engine = 'azure_mini'): array
public function generate(array $intake, array $classify, ?callable $emit = null, string $engine = 'azure_mini', ?string $persona = null): array
{
$draftDeployment = ($this->azure instanceof DbnBedrockGateway)
? (($engine === 'claude_sonnet' || $engine === 'azure_full')
@@ -259,7 +259,7 @@ PROMPT;
// ── Retrieve law ────────────────────────────────────────────────────────
if ($emit) { $emit('progress', ['detail' => self::L('fetching_law', $userLang)]); }
$retrieval = $this->retrieveLaw($body, $classify['applicable_acts'] ?? []);
$retrieval = $this->retrieveLaw($body, $classify['applicable_acts'] ?? [], $persona);
if ($emit) {
$emit('retrieval', [
'sources_count' => count($retrieval['sources']),
@@ -420,12 +420,20 @@ PROMPT;
*
* @return array{sources:array, applied_slices:string[]}
*/
private function retrieveLaw(string $body, array $applicableActs): array
private function retrieveLaw(string $body, array $applicableActs, ?string $persona = null): array
{
$client = dbnToolsRequireClient();
$package = dbnToolsFetchPackage(dbnToolsRequiredPackageSlug());
if (!$package) {
return ['sources' => [], 'applied_slices' => []];
$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) {
$package = dbnToolsFetchPackage(dbnToolsRequiredPackageSlug());
if (!$package) {
return ['sources' => [], 'applied_slices' => []];
}
$packageIds = [(int)$package['id']];
}
dbnToolsBootCaveau();
@@ -476,7 +484,7 @@ PROMPT;
$chunks = $rag->searchAll($q, 5, null, [
'search_private' => false,
'search_shared' => true,
'package_ids' => [(int)$package['id']],
'package_ids' => $packageIds,
'shared_doc_ids' => $sharedDocIds,
'chunk_limit' => 5,
'search_method' => 'hybrid',