Files
legal-ai/web-ui/src/app/settings/_components/blocks-tab.tsx
Chaim aad2de9205
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
feat(drafting): טיוטת-ביניים דטרמיניסטית — נעיצת Opus 4.8 + effort per-בלוק (#204)
מנגנון-הייצור (claude_session→claude -p) לא העביר model/effort: BLOCK_CONFIG
הגדיר temp+model per-בלוק שהיו מטא-דאטה-מת (block_writer.py:447 העביר רק
prompt/timeout/tools). הייצור רץ על מודל ברירת-המחדל של ה-CLI עם פרומפטים-חופשיים
→ מקור אי-העקביות בטיוטת-הביניים.

תיקון (עקביות-מבנית, WS5):
- נעיצת model="claude-opus-4-8" (GENERATION_MODEL) לכל בלוקי-ה-AI + effort per-בלוק
  שמועבר בפועל דרך claude_session.query → `claude -p --model --effort`.
  מפת-effort: ה=medium · ו=medium · ז=high · ח=medium · ט=high · יא=high · י=xhigh.
- ניסוח-פתיחה קבוע לבלוק-ה (תמיד "לפנינו ערר…", סוף ל-OR "עניינה של החלטה זו").
- מבנה-פנימי קבוע לבלוק-ה; סדר-בלוקים בייצוא כבר קבוע (_INTERIM_BLOCK_ORDER).
- הסרת שדות temp/model המתים מ-BLOCK_CONFIG; "temp" deprecated (Opus 4.7/4.8 דוחים
  temperature→400). decision_blocks.temperature נשמר=0 לתאימות-עמודה בלבד.
- timeout נגזר מ-effort (לא מפיצול sonnet/opus שכבר לא קיים).
- עדכון endpoint reference /api/settings/mcp/blocks + blocks-tab + McpBlock לחשוף effort.
- ספ: docs/block-schema.md §3 (effort מחליף temperature), docs/spec/06-export.md
  (דטרמיניזם-מבני של טיוטת-הביניים).

G2 (מקור-אמת יחיד) — אין מסלול-ייצור מקביל: write_interim_draft מתזמר את אותו
write_and_store_block→write_block של ההחלטה המלאה.
claude_session-local-only — הייצור נשאר דרך גשר-ה-CLI, לא SDK/קונטיינר.
INV-EX1 — סדר-ייצוא דטרמיניסטי נשמר; G11 — עקרונות-הכתיבה ל-12 הבלוקים נשמרים.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 11:18:56 +00:00

129 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { Layers, AlertCircle } from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { Badge } from "@/components/ui/badge";
import { useMcpBlocks, type McpBlock } from "@/lib/api/settings";
const GEN_TYPE_LABEL: Record<string, string> = {
"template-fill": "מילוי תבנית",
"paraphrase": "פרפרזה",
"reproduction": "שעתוק",
"guided-synthesis": "סינתזה מודרכת",
"rhetorical-construction": "בניה רטורית",
};
const GEN_TYPE_TONE: Record<string, string> = {
"template-fill": "text-ink-muted border-rule",
"paraphrase": "text-info border-info/40",
"reproduction": "text-info border-info/40",
"guided-synthesis": "text-warn border-warn/40",
"rhetorical-construction": "text-gold-deep border-gold/40",
};
function BlockRow({ block }: { block: McpBlock }) {
const isLLM = block.model !== "script";
return (
<div className="rounded-md border border-rule p-4 bg-rule-soft/20 hover:bg-rule-soft/40 transition-colors">
<div className="flex items-start gap-3">
<div className="flex-shrink-0 w-10 h-10 rounded-md bg-navy/5 border border-navy/20 flex items-center justify-center">
<span className="text-navy text-sm font-semibold tabular-nums">
{block.index}
</span>
</div>
<div className="flex-1 min-w-0 space-y-2">
<div className="flex items-center gap-2 flex-wrap">
<h3 className="text-navy font-medium">{block.title}</h3>
<code dir="ltr" className="font-mono text-[0.72rem] text-ink-muted">
{block.id}
</code>
</div>
<div className="flex items-center gap-2 flex-wrap">
<Badge
variant="outline"
className={`text-[0.7rem] ${GEN_TYPE_TONE[block.gen_type] ?? ""}`}
>
{GEN_TYPE_LABEL[block.gen_type] ?? block.gen_type}
</Badge>
<Badge variant="outline" className="text-[0.7rem] font-mono" dir="ltr">
{block.model}
</Badge>
{isLLM && block.effort !== null && (
<Badge variant="outline" className="text-[0.7rem]" dir="ltr">
effort&nbsp;<span className="tabular-nums">{block.effort}</span>
</Badge>
)}
{block.max_tokens !== null && (
<Badge variant="outline" className="text-[0.7rem]">
max&nbsp;<span className="tabular-nums">{block.max_tokens}</span>
</Badge>
)}
</div>
{(block.creac_role || block.jwm_purpose) && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-1 text-[0.78rem] text-ink-muted pt-1">
{block.creac_role && (
<div>
<span className="text-[0.7rem] uppercase tracking-wide me-1">
CREAC:
</span>
<span dir="ltr">{block.creac_role}</span>
</div>
)}
{block.jwm_purpose && (
<div>
<span className="text-[0.7rem] uppercase tracking-wide me-1">
JWM:
</span>
<span dir="ltr">{block.jwm_purpose}</span>
</div>
)}
</div>
)}
</div>
</div>
</div>
);
}
export function BlocksTab() {
const { data, isPending, error } = useMcpBlocks();
if (isPending) return <Skeleton className="h-96 w-full" />;
if (error) {
return (
<Card className="bg-surface border-danger/40">
<CardContent className="p-6 flex items-center gap-3 text-danger">
<AlertCircle className="w-5 h-5" />
<span>שגיאה בטעינת בלוקים: {error.message}</span>
</CardContent>
</Card>
);
}
if (!data) return null;
return (
<div className="space-y-4">
<Card className="bg-surface border-rule">
<CardContent className="px-6 py-5">
<div className="flex items-center gap-2 mb-4 text-ink-muted text-sm">
<Layers className="w-4 h-4" />
<span>
ארכיטקטורת 12 הבלוקים של החלטת ועדת ערר. מקור הסכימה:{" "}
<code dir="ltr" className="font-mono text-[0.78rem]">
docs/block-schema.md
</code>
.
</span>
</div>
<div className="space-y-3">
{data.blocks.map((b) => (
<BlockRow key={b.id} block={b} />
))}
</div>
</CardContent>
</Card>
</div>
);
}