Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
AI Contract-Risk Analyzer — powered by a local-first LangGraph agent
Upload a contract → get every risky clause found, scored, and rewritten — without your data ever leaving the machine.查看完整 README ↗Upload a contract → every risky clause found, scored, and redlined — with an evidence trail, a branded PDF, and delivery to your own Drive & inbox. Run it fully offline on local models, or deploy it to the cloud — same pipeline, swappable providers.
ContractSentinel is an autonomous, AI-powered system that reads a legal contract and tells you where the risk is. A user uploads a PDF or DOCX; a fixed 7-node LangGraph pipeline splits it into clauses, retrieves supporting legal evidence for each one, validates which clauses are genuinely worth flagging, scores each Low / Medium / High with a written rationale, drafts a safer rewrite for the risky ones, and compiles a branded PDF report — delivered to the user's own Google Drive and emailed to them.
It behaves like a real multi-tenant SaaS — landing page, authentication, per-user data isolation, per-user Drive, live progress streaming, a metrics dashboard and report history — built spec-first with a strict review gate.
Two ways to run the exact same pipeline, chosen by a clean provider seam:
| Mode | Generation | Embeddings | Data | Privacy |
|---|---|---|---|---|
| 🏠 Local-first (default) | Qwen3:8b via Ollama | BGE-M3 via Ollama | SQLite | 💯 Contract text never leaves the machine |
| ☁️ Cloud deployment | Groq gpt-oss-120b | Cloudflare bge-m3 | Turso (libSQL) | Hosted demo on Render + Vercel |
The architecture, nodes, prompts, and tests are identical across both modes — only the provider adapters change. That seam is what lets a privacy-first local tool also ship as a live hosted demo without a rewrite.
| 🧠 Pipeline | 📚 Knowledge Base | 🧪 Tests | 🔒 Security | 📐 Process |
|---|---|---|---|---|
| 7 nodes · 2 edges fixed LangGraph | 1,400+ real clauses · 39 types (CUAD + Bonterms) | 1,231 backend · 264 frontend | 8 hardening layers | 66 spec-reviewed features |
| 🧠 Agentic pipeline | A fixed 7-node LangGraph state machine with exactly 2 conditional edges — ingest → split → retrieve → validate → score → redline → report. The shape is immutable by constitution; every feature is built around the graph. |
| 🔎 Corrective RAG (CRAG) | Per-clause retrieval over a local FAISS knowledge base of 1,400+ real contract clauses (Bonterms + CUAD, CC BY 4.0) across 39 clause types, with an automatic live web-search fallback when confidence drops below 0.73. |
| ✅ Self-RAG validation | Relevance / support checks discard false alarms; a recall floor protects genuinely high-risk clause types. Accuracy is measured by an offline harness reporting precision / recall / F1 per clause type, each with a 95% bootstrap confidence interval — best-effort-labeled, not lawyer-reviewed. |
| ✍️ Automatic redlining | High-risk clauses get a suggested safer rewrite plus a rationale. |
| 🔀 Pluggable providers | One seam swaps local Ollama ↔ Groq (generation) and Ollama ↔ Cloudflare Workers AI (embeddings) — no pipeline changes. |
| 🔒 Private by construction | In local mode, 100% on-device inference; uploaded contracts encrypted at rest (Fernet) in both modes. |
| 🛡️ Production-grade security | bcrypt + JWT auth, session hardening, rate-limiting + lockout, prompt-injection defense, security headers, upload magic-byte validation. |
| ♻️ Durable & resumable | Job store + LangGraph checkpointer — a killed job resumes from the last completed node; dropped DB connections self-heal with reconnect + retry. |
| 📡 Live progress | Watch the pipeline advance node-by-node over Server-Sent Events. |
| 📤 Real delivery | Branded PDF report pushed to the user's Google Drive + emailed via Gmail (MCP). |
| 🧪 Rigorously tested |
Contracts are among the most confidential documents a business handles. Sending them to a hosted LLM means the document leaves your control — often permanently.
In its default local mode, ContractSentinel runs every model on-device through Ollama:
These are kept as strictly separate model objects (the embedding model is never substituted for the generative one). No contract text, clause, or piece of evidence is sent to a third-party API. Uploaded files are additionally encrypted at rest with Fernet (AES-128-CBC + HMAC-SHA256).
Cloud mode is opt-in and explicit. The hosted demo flips two environment flags (LLM_PROVIDER=groq, EMBED_PROVIDER=cloudflare) to route generation and embeddings to managed APIs for a zero-GPU deployment. Everything else — the graph, prompts, validation, encryption-at-rest, and per-user isolation — is unchanged. You choose the trade-off; the code doesn't force it.
A LangGraph StateGraph with exactly 7 sequential nodes and exactly 2 conditional edges. This shape is fixed by the project constitution and treated as immutable — every feature is built around the graph, never by adding nodes.
flowchart TD
U([📄 Upload PDF / DOCX]) --> N1
N1["1 · IngestAgent<br/>parse · OCR fallback · decrypt-at-rest"] --> N2
N2["2 · ClauseSplitterAgent<br/>regex pre-pass → LLM boundaries + types"] --> N3
N3{"3 · CRAG Retrieval<br/>BGE-M3 + FAISS · confidence?"}
N3 -->|confidence 0.73 or higher| KB[(Local Legal KB<br/>1,400+ clauses)]
N3 -->|confidence below 0.73| WEB([🌐 Live web search])
KB --> N4
WEB --> N4
N4["4 · Self-RAG Validation<br/>ISREL / ISSUP + recall floor"] --> N5
N5["5 · RiskScoreAgent<br/>Low / Medium / High + rationale"] --> R{route_on_risk}
R -->|risky| N6["6 · RedlineAgent<br/>draft safer rewrite"]
R -->|clean| SK["6 · SkipRedline<br/>mark clean"]
N6 --> N7
SK --> N7
N7["7 · ReportAgent<br/>compile report + evidence trail"] --> END([✅ END])
END -.post-terminal.-> DEL[["📤 MCP Delivery<br/>Google Drive + Gmail"]]
style N1 fill:#0E9C92,stroke:#0B6F68,color:#fff
style N2 fill:#0E9C92,stroke:#0B6F68,color:#fff
style N4 fill:#0E9C92,stroke:#0B6F68,color:#fff
style N5 fill:#0E9C92,stroke:#0B6F68,color:#fff
style N6 fill:#F2A900,stroke:#B37C00,color:#fff
style N7 fill:#1E2761,stroke:#0E1A38,color:#fff
style N3 fill:#E4572E,stroke:#A5361A,color:#fff
style R fill:#E4572E,stroke:#A5361A,color:#fff
style DEL fill:#1E2761,stroke:#0E1A38,color:#fff
The two conditional edges (every other transition is a plain linear edge):
route_on_risk — RedlineAgent vs. SkipRedline.| # | Node | What it does |
|---|---|---|
| 1 | IngestAgent | Parses PDF/DOCX (PyMuPDF / python-docx), OCR fallback (Tesseract) for scans; decrypts the at-rest-encrypted upload to a temp file before parsing. |
| 2 | ClauseSplitterAgent | Regex pre-pass proposes clause boundaries; the LLM refines boundaries and assigns clause types; size-gated for large documents. |
| 3 | CRAG Retrieval | Embeds each clause (BGE-M3), searches a local FAISS legal KB, scores confidence; < 0.73 → live web fallback. Evidence merged per clause. |
| 4 | Self-RAG Validation | Relevance / ISREL / ISSUP checks discard weak flags; a recall floor protects genuinely high-risk clause types from being dropped. |
| 5 | RiskScoreAgent | Assigns Low / Medium / High with a written rationale (deterministic, temperature-pinned). |
| 6 | route_on_risk → Redline / Skip | Risky clauses get a safer rewrite; clean clauses are marked and skipped. |
| 7 | ReportAgent | Assembles the final report + full evidence trail; rendered to a branded PDF. |
Every clause that survives validation ends up scored:
🔴 HIGH — serious exposure, needs a rewrite · 🟡 MEDIUM — worth review/negotiation · 🟢 LOW — acceptable, standard wording
From upload to delivered report — durable, streamed, and resumable end-to-end.
sequenceDiagram
autonumber
actor User
participant FE as Next.js (Vercel)
participant API as FastAPI (Render)
participant WK as Pipeline Worker
participant G as LangGraph (7 nodes)
participant DB as Job Store (SQLite / Turso)
participant DEL as MCP Delivery
User->>FE: Upload PDF / DOCX
FE->>API: POST /api/jobs (JWT cookie)
API->>API: magic-byte check · encrypt-at-rest · enqueue
API-->>FE: 202 job_id
FE->>API: GET /api/jobs/{id}/events (SSE)
WK->>G: run pipeline
loop each node
G->>DB: checkpoint + progress
DB-->>API: node advanced
API-->>FE: SSE progress event
end
G->>DB: persist report + denormalized risk summary
G-->>DEL: deliver PDF → Google Drive + Gmail
FE->>API: GET /api/dashboard · /api/jobs
API->>DB: single SELECT (summary on the row — no per-report reads)
API-->>FE: metrics + history (sub-second)
Resilience built in: if the worker is killed mid-run, the LangGraph checkpointer resumes from the last completed node; if the database connection drops, the store reconnects and retries transparently.
The same backend image runs locally (all on-device) or on a free-tier cloud stack. In the hosted demo, the frontend is on Vercel, the API is a Docker service on Render, data lives in Turso (libSQL), and the model work is offloaded to Groq + Cloudflare Workers AI.
flowchart LR
subgraph Client
B([🌐 Browser])
end
subgraph Edge["Vercel"]
FE[Next.js Frontend]
end
subgraph Render["Render · Docker"]
API[FastAPI + LangGraph Worker]
end
subgraph Providers["Managed Providers (cloud mode)"]
GROQ[[Groq<br/>gpt-oss-120b]]
CF[[Cloudflare Workers AI<br/>bge-m3]]
TURSO[(Turso · libSQL)]
GOOG[[Google<br/>Drive + Gmail]]
end
subgraph Local["Local mode (alternative)"]
OLL[[Ollama<br/>Qwen3 + BGE-M3]]
SQL[(SQLite)]
end
B --> FE -->|/api proxy| API
API -->|generation| GROQ
API -->|embeddings| CF
API -->|jobs · users · reports| TURSO
API -->|delivery| GOOG
API -. swap via provider seam .-> OLL
API -. swap via provider seam .-> SQL
style FE fill:#000,color:#fff
style API fill:#0E9C92,color:#fff
style GROQ fill:#F55036,color:#fff
style CF fill:#F38020,color:#fff
style TURSO fill:#1E2761,color:#fff
style GOOG fill:#4285F4,color:#fff
style OLL fill:#333,color:#fff
A single configuration seam selects the generation and embedding backends. The BGE-M3 embedding space is identical across Ollama and Cloudflare, so the same FAISS index serves both.
| Capability | Env flag | Local option | Cloud option(s) |
|---|---|---|---|
| Generation | LLM_PROVIDER | ollama → Qwen3:8b | groq → openai/gpt-oss-120b |
| Embeddings | EMBED_PROVIDER | ollama → bge-m3 | cloudflare → @cf/baai/bge-m3 (or hf) |
| Data store | TURSO_DATABASE_URL | unset → SQLite file | set → Turso (libSQL over Hrana) |
Embedding and generative models are kept as separate seams (constitution §8) — the embedding model is never substituted for the generative one, in either mode.
ContractSentinel/
├── backend/
│ ├── app/
│ │ ├── graph/ # LangGraph StateGraph (builder.py, state.py) + the 7 nodes
│ │ │ └── nodes/ # ingest · splitter · crag · self-rag · risk · redline · report
│ │ ├── rag/ # embeddings, FAISS KB, web retriever, per-user learned KB
│ │ ├── llm/ # Ollama / Groq clients · embed clients · prompt-injection guard
│ │ ├── api/ # FastAPI app, routes, auth, rate-limit, SSE, dashboard aggregation
│ │ ├── runner/ # pipeline runner, job store, registry, worker, DB backend seam
│ │ ├── delivery/ # MCP Drive/Gmail, PDF/email rendering
│ │ ├── mcp_servers/ # MCP server integrations
│ │ ├── security/ # Fernet crypto seam
│ │ ├── models/ # Pydantic models
│ │ ├── db/ # store wiring
│ │ ├── blob_store.py # disk / Turso BLOB storage for reports & uploads
│ │ └── config.py # all named config constants + provider flags
│ ├── alembic/ # database migrations (0001 … 0011)
│ └── pyproject.toml
├── frontend/
│ └── src/
│ ├── app/ # Next.js routes (landing, login, upload, dashboard, reports, …)
│ ├── components/ # UI, charts, report workspace, dashboard, marketing, …
│ └── lib/api/ # provider seam (real ↔ mock)
├── specs/ # spec-driven workflow: constitution + 66 per-feature specs
├── eval/ # offline accuracy / variance evaluation harness
├── scripts/ # OAuth bootstrap, KB build, delivery/latency smoke tools
├── docs/ # deployment & operations docs
└── render.yaml # Render blueprint (cloud deployment)
ollama pull qwen3:8b
ollama pull bge-m3
💡 On a 6 GB GPU, Qwen3:8b runs at roughly a 70/30 GPU/CPU split — pre-warm it before a run.
scripts/.# 1. Clone
git clone <your-repo-url> ContractSentinel
cd ContractSentinel
# 2. Backend
cd backend
python -m venv .venv
.venv/Scripts/activate # Windows (source .venv/bin/activate on macOS/Linux)
pip install -e ".[dev,eval]"
# 3. Frontend
cd ../frontend
npm install
Backend (port 8000, from backend/):
# apply DB migrations (first run / after pulling)
.venv/Scripts/python.exe -m alembic upgrade head
# start the API (local HTTP dev → AUTH_COOKIE_SECURE=False; default True requires TLS)
AUTH_COOKIE_SECURE=False .venv/Scripts/python.exe -m uvicorn app.api.main:app --host 127.0.0.1 --port 8000
$env:AUTH_COOKIE_SECURE="False"
.venv\Scripts\python.exe -m uvicorn app.api.main:app --host 127.0.0.1 --port 8000
Frontend (port 3000, from frontend/):
npm run dev
frontend/.env.local must contain NEXT_PUBLIC_API_PROVIDER=real (proxies to :8000). Then open http://localhost:3000.
Cloud mode: set
LLM_PROVIDER=groq,EMBED_PROVIDER=cloudflare, andTURSO_DATABASE_URL(+ the matching API keys) — the deployment blueprint inrender.yamlwires this end-to-end.
# Backend (from backend/)
.venv/Scripts/python.exe -X utf8 -m pytest -q
# Frontend (from frontend/)
npm run test
1,231 backend tests · 264 frontend tests — all green. Built spec-first with TDD: tests are written and confirmed failing before implementation, and a failing test is fixed by fixing the code, never by weakening the test.
Security was developed as a dedicated hardening phase, not an afterthought:
session_epoch enables log-out-everywhere, ends other sessions on password change, invalidates on reset.user message; trusted instructions stay in a system message — across all generative LLM calls.X-Content-Type-Options, X-Frame-Options: DENY, a strict CSP, Referrer-Policy, COOP, Permissions-Policy (HSTS available, TLS-gated).%PDF, DOCX → ZIP).Hardened for a real, always-on deployment — not just a happy-path demo:
Every feature follows a strict spec-driven workflow defined in specs/000-constitution.md:
spec.md → plan.md → tasks.md → implementation
└────────── each GATED by a spec-reviewer review before advancing ──────────┘
spec.md and plan.md exist and are spec-reviewer-approved.main only when its full test suite passes.ContractSentinel is feature-complete and deployed. The entire stack — the agent pipeline, the API, durable persistence, the full Next.js frontend, security, delivery, and a live cloud deployment — is implemented, integrated, and tested end-to-end.
| Name | Role |
|---|---|
| Yash Joshi | Backend implementation, agent pipeline, cloud deployment |
| Bansi | Frontend implementation |
This project is currently developed for academic / educational purposes. No open-source license has been applied yet — all rights reserved by the authors. Please contact the team before reuse.
Built with LangGraph, FastAPI, and Next.js — under a strict spec-driven workflow.
⭐ If you find this project interesting, consider giving it a star.
| 1,231 backend + 264 frontend tests, built spec-first with TDD across 66 reviewed features. |