feat(tools): add letter length + summary depth controls; harden korrespond §-discipline
- Summarize: new depth param (brief/standard/detailed) with depth-aware prompt instructions and coverage mandate; wired through API + JS - Korrespond: new letter length param (concise/standard/detailed) injected as Lengde: instruction in draft pass; wired through API + JS - Korrespond draft prompt: add §-discipline rule (cite only directly relevant §§) plus Opphevet guard (aligned with dobetterlegal-tools) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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', ?string $persona = null): array
|
||||
public function generate(array $intake, array $classify, ?callable $emit = null, string $engine = 'azure_mini', ?string $persona = null, string $length = 'standard'): array
|
||||
{
|
||||
$draftDeployment = ($this->azure instanceof DbnBedrockGateway)
|
||||
? (($engine === 'claude_sonnet' || $engine === 'azure_full')
|
||||
@@ -270,7 +270,7 @@ PROMPT;
|
||||
// ── Draft in Norwegian bokmål ───────────────────────────────────────────
|
||||
if ($emit) { $emit('progress', ['detail' => self::L('drafting_no', $userLang)]); }
|
||||
$draftNo = $this->draftNorwegian(
|
||||
$intake, $classify, $retrieval['sources'], $bodyLabel, $outputType, $tone, $goal, $draftDeployment
|
||||
$intake, $classify, $retrieval['sources'], $bodyLabel, $outputType, $tone, $goal, $draftDeployment, $length
|
||||
);
|
||||
|
||||
// ── Self-check: verify citations, deadline, goal, tone ──────────────────
|
||||
@@ -550,7 +550,8 @@ PROMPT;
|
||||
|
||||
private function draftNorwegian(
|
||||
array $intake, array $classify, array $sources, string $bodyLabel,
|
||||
string $outputType, string $tone, string $goal, string $draftDeployment = self::DRAFT_DEPLOYMENT
|
||||
string $outputType, string $tone, string $goal, string $draftDeployment = self::DRAFT_DEPLOYMENT,
|
||||
string $length = 'standard'
|
||||
): string {
|
||||
$context = $this->buildContextBlob($intake);
|
||||
$toneLabel = $this->toneLabelNorsk($tone);
|
||||
@@ -574,9 +575,16 @@ PROMPT;
|
||||
|
||||
$goalLine = $goal !== '' ? ('Brukerens mål: ' . $goal) : 'Brukerens mål: ikke spesifisert — utled fra konteksten.';
|
||||
|
||||
$lengthLabel = match($length) {
|
||||
'concise' => 'Kort og poengtert — maks 2-3 avsnitt. Kom raskt til poenget.',
|
||||
'detailed' => 'Utfyllende — inkluder full bakgrunn, alle argumenter og rettslig begrunnelse.',
|
||||
default => 'Standard lengde — 4-6 avsnitt.',
|
||||
};
|
||||
|
||||
$prompt = <<<PROMPT
|
||||
Du skriver utkast til korrespondanse til {$bodyLabel}. Skriv på norsk bokmål.
|
||||
Tone: {$toneLabel}.
|
||||
Lengde: {$lengthLabel}
|
||||
|
||||
{$goalLine}
|
||||
|
||||
@@ -588,6 +596,8 @@ REGLER FOR LOVHENVISNINGER (kritisk):
|
||||
fra passasjelisten. Eksempel: "etter forvaltningsloven § 17 [CITE:2]".
|
||||
- Hvis du ikke finner dekning i passasjene, skriv UTEN §-henvisning.
|
||||
- IKKE finn på §-nummer eller artikkelnumre.
|
||||
- IKKE siter §-er som er markert "(Opphevet)" eller "Opphevet ved lov" i passasjene — de gjelder ikke lenger.
|
||||
- Siter kun §-er som er DIREKTE RELEVANTE for den juridiske saken i brevet. Ikke siter §-er fra lovteksten som ikke brukes i argumentasjonen.
|
||||
|
||||
{$sourcesBlock}
|
||||
|
||||
|
||||
+23
-4
@@ -1854,7 +1854,8 @@ PROMPT;
|
||||
string $text,
|
||||
string $language = 'en',
|
||||
string $engine = 'azure_mini',
|
||||
string $corpusContext = ''
|
||||
string $corpusContext = '',
|
||||
string $depth = 'standard'
|
||||
): array {
|
||||
$text = $this->requirePasteText($text);
|
||||
$engine = in_array($engine, ['azure_mini', 'azure_full', 'gpu'], true) ? $engine : 'azure_mini';
|
||||
@@ -1870,16 +1871,34 @@ PROMPT;
|
||||
. $text;
|
||||
}
|
||||
|
||||
$depthInstructions = match($depth) {
|
||||
'brief' => [
|
||||
'what_we_found' => '1-2 sentence executive summary covering the main outcome',
|
||||
'key_facts' => 'up to 3 most important facts',
|
||||
'coverage' => '',
|
||||
],
|
||||
'detailed' => [
|
||||
'what_we_found' => 'comprehensive 6-10 sentence summary covering every fact, decision, party, date, and legal implication',
|
||||
'key_facts' => 'every fact, decision, and legal reference mentioned in the document',
|
||||
'coverage' => "\nCover ALL parties, ALL key decisions, ALL dates, and ALL legal references present in the document. Do not omit facts because they seem minor — err on the side of inclusion.",
|
||||
],
|
||||
default => [
|
||||
'what_we_found' => '3-5 sentence summary covering all key outcomes, parties, and decisions',
|
||||
'key_facts' => 'all key facts',
|
||||
'coverage' => "\nCover ALL parties, ALL key decisions, ALL dates, and ALL legal references present in the document.",
|
||||
],
|
||||
};
|
||||
|
||||
$prompt = <<<PROMPT
|
||||
Summarise the following document in {$locale}. Do not invent facts not present in the text.
|
||||
Return JSON only — no extra text before or after the JSON object.
|
||||
Return JSON only — no extra text before or after the JSON object.{$depthInstructions['coverage']}
|
||||
|
||||
{$enriched}
|
||||
|
||||
Return this JSON structure:
|
||||
{
|
||||
"what_we_found": "plain-language summary (2-4 sentences)",
|
||||
"key_facts": ["fact 1", "fact 2"],
|
||||
"what_we_found": "{$depthInstructions['what_we_found']}",
|
||||
"key_facts": ["{$depthInstructions['key_facts']}"],
|
||||
"dates": ["date or event phrase"],
|
||||
"parties": ["party or role"],
|
||||
"legal_references_detected": ["statute, article, or case name"],
|
||||
|
||||
Reference in New Issue
Block a user