Add full decision writing pipeline: classify, extract, brainstorm, write, QA, export
New services (11 files): - classifier.py: auto doc-type classification + party identification (Claude Haiku) - claims_extractor.py: claim extraction from pleadings (Claude Sonnet + regex) - references_extractor.py: plan/case-law/legislation detection (regex) - brainstorm.py: direction generation with 2-3 options (Claude Sonnet) - block_writer.py: 12-block decision writer (template + Claude Sonnet/Opus) - docx_exporter.py: DOCX export with David font, RTL, headings - qa_validator.py: 6 QA checks with export blocking on critical failure - learning_loop.py: draft vs final comparison + lesson extraction - metrics.py: KPIs dashboard per case and global - audit.py: action audit log - cli.py: standalone CLI with 11 commands Updated pipeline: extract → classify → chunk → embed → store → extract_references New MCP tools: 29 total (was 16) New DB tables: audit_log, decisions CRUD, claims CRUD Config: Infisical support, external service allowlist Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
"""Configuration loaded from central .env file."""
|
||||
"""Configuration loaded from Infisical or central .env file.
|
||||
|
||||
Priority: Infisical → environment variables → .env file
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -9,6 +12,23 @@ from dotenv import load_dotenv
|
||||
dotenv_path = os.environ.get("DOTENV_PATH", str(Path.home() / ".env"))
|
||||
load_dotenv(dotenv_path)
|
||||
|
||||
# Try loading from Infisical if configured
|
||||
INFISICAL_TOKEN = os.environ.get("INFISICAL_TOKEN", "")
|
||||
if INFISICAL_TOKEN:
|
||||
try:
|
||||
from infisical_sdk import InfisicalSDKClient
|
||||
_client = InfisicalSDKClient(token=INFISICAL_TOKEN)
|
||||
_secrets = _client.get_all_secrets(
|
||||
environment=os.environ.get("INFISICAL_ENV", "production"),
|
||||
project_id=os.environ.get("INFISICAL_PROJECT_ID", ""),
|
||||
)
|
||||
for s in _secrets:
|
||||
os.environ.setdefault(s.secret_key, s.secret_value)
|
||||
except ImportError:
|
||||
pass # Infisical SDK not installed — use .env
|
||||
except Exception:
|
||||
pass # Infisical unreachable — fall back to .env
|
||||
|
||||
# PostgreSQL
|
||||
POSTGRES_URL = os.environ.get(
|
||||
"POSTGRES_URL",
|
||||
@@ -38,3 +58,12 @@ TRAINING_DIR = DATA_DIR / "training"
|
||||
# Chunking parameters
|
||||
CHUNK_SIZE_TOKENS = 600
|
||||
CHUNK_OVERLAP_TOKENS = 100
|
||||
|
||||
# External service allowlist — case materials may ONLY be sent to these domains
|
||||
ALLOWED_EXTERNAL_SERVICES = {
|
||||
"api.anthropic.com", # Claude API (text generation, OCR)
|
||||
"api.voyageai.com", # Voyage AI (embeddings)
|
||||
}
|
||||
|
||||
# Audit
|
||||
AUDIT_ENABLED = os.environ.get("AUDIT_ENABLED", "true").lower() == "true"
|
||||
|
||||
Reference in New Issue
Block a user