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:
@@ -279,8 +279,9 @@ async def _extract_chunk(
|
||||
else HALACHA_EXTRACTION_PROMPT_PERSUASIVE
|
||||
)
|
||||
chunk_label = f" (חלק {chunk_index + 1}/{chunk_total})" if chunk_total > 1 else ""
|
||||
prompt = (
|
||||
f"{base_prompt}\n\n"
|
||||
# Pass the static instruction prompt as `system` so the SDK path can cache
|
||||
# it (5-min ephemeral). Only the per-chunk content varies via `prompt`.
|
||||
user_msg = (
|
||||
f"## הקלט\n"
|
||||
f"סוג קטע: {section_type}\n"
|
||||
f"{context}{chunk_label}\n\n"
|
||||
@@ -289,7 +290,7 @@ async def _extract_chunk(
|
||||
last_err: Exception | None = None
|
||||
for attempt in range(CHUNK_RETRY_ATTEMPTS + 1):
|
||||
try:
|
||||
result = await claude_session.query_json(prompt)
|
||||
result = await claude_session.query_json(user_msg, system=base_prompt)
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
logger.warning(
|
||||
|
||||
Reference in New Issue
Block a user