fix(precedents): Anthropic SDK fallback, format() crash, UI refresh
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m31s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m31s
Three fixes to the precedent library after the first end-to-end test on
403-17 surfaced runtime issues:
1. Anthropic SDK fallback in claude_session. The legal-ai Docker container
does not ship the `claude` CLI, so every halacha and metadata extraction
was failing with "Claude CLI not found." Module now tries the CLI first
(zero-cost local path) and falls back to the Anthropic SDK with
ANTHROPIC_API_KEY when the binary is absent. Default model is
claude-sonnet-4-6, overridable via CLAUDE_SDK_MODEL env. The system
message gets cache_control: ephemeral so multi-chunk runs reuse the
cached instruction prefix at ~10% read cost. Adds `anthropic` to
pyproject deps.
2. precedent_metadata_extractor crashed with KeyError because the JSON
example inside the prompt template contained literal { } characters
that str.format() interpreted as placeholders. Switched to f-string
concatenation; the prompt template no longer needs format() at all.
3. Library list query stays stale after upload because the upload
mutation's onSuccess fires when the POST returns task_id, not when
SSE reports completion. Added a second invalidate inside the SSE
watcher in PrecedentUploadSheet so the new row appears with up-to-date
chunk and halachot counts the moment processing finishes.
Halacha and metadata extractors now route the long static prompt through
the new `system=` parameter so the SDK path actually caches it; the CLI
path concatenates and behaves as before.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Upload, Loader2, CheckCircle2, AlertCircle } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription,
|
||||
} from "@/components/ui/sheet";
|
||||
@@ -14,7 +15,10 @@ import {
|
||||
Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { useUploadPrecedent, type PracticeArea, type SourceType } from "@/lib/api/precedent-library";
|
||||
import {
|
||||
useUploadPrecedent, libraryKeys,
|
||||
type PracticeArea, type SourceType,
|
||||
} from "@/lib/api/precedent-library";
|
||||
import { useProgress } from "@/lib/api/documents";
|
||||
import {
|
||||
PRACTICE_AREAS, PRECEDENT_LEVELS, SOURCE_TYPES,
|
||||
@@ -44,6 +48,7 @@ export function PrecedentUploadSheet({ open, onOpenChange }: Props) {
|
||||
const [taskId, setTaskId] = useState<string | null>(null);
|
||||
const upload = useUploadPrecedent();
|
||||
const progress = useProgress(taskId);
|
||||
const qc = useQueryClient();
|
||||
|
||||
// Reset form when the sheet closes — fields, file input, and any in-flight
|
||||
// task subscription. We accept the cascade-render warning because resetting
|
||||
@@ -60,17 +65,23 @@ export function PrecedentUploadSheet({ open, onOpenChange }: Props) {
|
||||
setHeadnote(""); setIsBinding(true); setTaskId(null);
|
||||
}, [open]);
|
||||
|
||||
// Auto-close on completion
|
||||
// Auto-close on completion + refresh library list/stats so the new
|
||||
// row appears with up-to-date counts (halachot, approved). The mutation's
|
||||
// onSuccess fires when POST returns the task_id; we need a second
|
||||
// invalidation when SSE reports terminal status, otherwise the table
|
||||
// shows stale data.
|
||||
useEffect(() => {
|
||||
if (progress?.status === "completed") {
|
||||
qc.invalidateQueries({ queryKey: libraryKeys.all });
|
||||
toast.success("הפסיקה הוכנסה לקורפוס. ההלכות ממתינות לאישור.");
|
||||
const t = window.setTimeout(() => onOpenChange(false), 1200);
|
||||
return () => window.clearTimeout(t);
|
||||
}
|
||||
if (progress?.status === "failed") {
|
||||
qc.invalidateQueries({ queryKey: libraryKeys.all });
|
||||
toast.error(`כשל בעיבוד: ${progress.error || "שגיאה לא ידועה"}`);
|
||||
}
|
||||
}, [progress, onOpenChange]);
|
||||
}, [progress, onOpenChange, qc]);
|
||||
|
||||
const onSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user