Spaces:
Sleeping
Sleeping
Commit History
-
fix: use Gradio 5 messages format in agent chatbot
Fabio Antonini +1: Claude Sonnet 4.6_agent_respond was building history as [[user, bot], ...] tuples, but gr.Chatbot in Gradio 5 expects {role, content} dicts by default. Convert to messages format to match the RAG chatbot convention. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f290fe3 -
fix: render agent extracted images in Gradio via base64 data URIs
Fabio Antonini +1: Claude Sonnet 4.6The agent tool saves cropped signature images and references them with /api/agent/images/<name> URLs (a FastAPI route). In the Gradio app these URLs are unreachable, causing broken image icons in the chatbot. Fix: _fix_agent_image_urls() post-processes each streamed chunk in _agent_respond(), replacing /api/agent/images/<name> with an inline base64 data URI so the image renders directly in the Gradio Chatbot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9c1c14c -
feat: enable RAG and Agent on HF Spaces via OpenAI API key
Fabio Antonini +1: Claude Sonnet 4.6- Add _LLM_AVAILABLE flag (Ollama OR OpenAI key configured) - Add ⚙️ Configurazione LLM accordion to RAG and Agent tabs with password input, save button and status feedback - _apply_openai_key() sets OPENAI_API_KEY env var, switches RAG model to gpt-5.4-mini and embedding model to text-embedding-3-small - All interactive elements in tab 9/10 gated on _LLM_AVAILABLE instead of _OLLAMA_AVAILABLE; accordion auto-opens when no LLM is available - core/rag.py: fix set_embed_model() cache_dir fallback when backend.config is not available (Gradio standalone context) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>28a01c7
-
feat: Agente Documentale LangChain + OCR selector + stop + SQLite WAL
Fabio Antonini +1: Claude Sonnet 4.6- core/agent.py: LangChain agent con 10 tool forensi (OCR, NER, firma, grafologia, scrittore, datazione, layout, RAG), streaming SSE, stop via threading.Event, short-path workaround per path truncation LLM - core/document_layout.py: wrapper PaddleOCR lazy-loaded con call_vision_model streaming (timeout=(10,300), stream=True) - backend/routers/agent.py: endpoint POST /agent/chat (SSE), GET /agent/status, GET /agent/prompts; cancellazione via GeneratorExit → stop_event - frontend/src/pages/AgentPage.tsx: chat page stile ChatGPT con upload file, streaming SSE, badge azioni tool collassabili, Stop button (AbortController) - core/ocr.py: selettore modello OCR (easyocr/vlm/paddleocr/trocr), persistenza .env, _vlm_transcribe streaming, EasyOCR senza preprocessing - backend/routers/rag.py: GET/PUT /rag/ocr-model endpoints - frontend/src/components/layout/Sidebar.tsx: dropdown OCR model in sidebar - backend/database.py: SQLite WAL mode + busy_timeout=10000 via event listener - core/…e1f6f2b
-
feat: replace ultralytics/YOLOv8 with Conditional DETR (Apache 2.0)
Fabio Antonini +1: Claude Sonnet 4.6- core/signature.py: get_yolo() → get_detector() via transformers AutoImageProcessor + AutoModelForObjectDetection (tech4humans/conditional-detr-50-signature-detector) - requirements.txt: remove ultralytics>=8.0.0, albumentations>=1.3.0; add timm>=0.9.0 - core/pipeline.py, app/grapholab_demo.py: update UI strings YOLOv8 → Conditional DETR - notebooks: new 04_signature_detection_detr.ipynb; archive old yolo notebook - notebooks/01, 03: update references and links to Lab 04 Removes AGPL-3.0 dependency blocking commercial release. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4b50683
-
feat: extract AI logic into shared core/ package (Phase 0)
Fabio Antonini +1: Claude Sonnet 4.6- Add core/ package with 8 pure-Python AI modules: ner.py, ocr.py, graphology.py, writer.py, signature.py, rag.py, dating.py, pipeline.py - Refactor app/grapholab_demo.py into thin Gradio wrappers that delegate all processing to core/ - Add GraphoLab Core Quick Start cells to notebooks 02-07 (markdown explanation + importable code cell per notebook) - Update ROADMAP.md with architectural decisions and phase plan core/ is now shared by both the Gradio demo and the upcoming FastAPI backend (feature/backend). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bb6ffde -
Show unavailability banner in RAG tab when Ollama is not reachable
Fabio Antonini +1: Claude Sonnet 4.6Adds _OLLAMA_AVAILABLE startup check; on HF Spaces (no local Ollama) the tab shows a clear explanation with local setup instructions and disables interactive inputs instead of silently failing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6a85733
-
Improve PDF report: Unicode fixes, NER table, layout, tab rename
Fabio Antonini +1: Claude Sonnet 4.6- Fix UnicodeEncodeError: add _to_latin1() with explicit replacements for em-dash, curly quotes, checkmark, medals, warning emoji, ellipsis - Remove NFKD normalization (was corrupting valid latin-1 accented chars) - Fix NER table: convert markdown table rows to plain text instead of stripping - Fix section title overlap: increase ln() from 4 to 12 after colored header - Add fallback text for empty NER section - Rename tab "Pipeline Forense" to "Perizia Forense Automatica" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2cf3bef -
Add PDF report generation to Forensic Pipeline
Fabio Antonini +1: Claude Sonnet 4.6After the pipeline completes, a "Scarica Report PDF" button appears. _generate_pipeline_pdf() uses fpdf2 to build a professional multi-page forensic report with all 7 step outputs (text + embedded images) and the LLM narrative conclusion, plus a disclaimer footer. Unicode normalization via _to_latin1() handles em-dash and other characters outside latin-1 range required by fpdf2 core fonts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>21e9333 -
Add Step 7: LLM synthesis to Forensic Pipeline via Ollama
Fabio Antonini +1: Claude Sonnet 4.6After the 6 existing steps, the pipeline now calls _pipeline_llm_synthesis() which uses the same Ollama model already configured in the RAG tab to generate a professional narrative forensic report from all step outputs. Graceful fallback message shown when Ollama is not reachable (e.g. HF Spaces). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a579ad1 -
Fix model selector: separate generation model from embedding model
Fabio Antonini +1: Claude Sonnet 4.6Not all Ollama models support /api/embeddings. Introduced _embed_model (fixed, defaults to OLLAMA_MODEL) for embedding calls and kept _rag_model for generation only (user-selectable). This prevents embedding failures when the user picks a model that doesn't support embeddings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fada9ef -
Add Ollama model selector to Consulente Forense IA tab
Fabio Antonini +1: Claude Sonnet 4.6- Add _rag_model global (runtime-mutable, defaults to OLLAMA_MODEL) - Add _ollama_list_models() to fetch available models from /api/tags - Add set_rag_model() to update active model at runtime - Replace hardcoded OLLAMA_MODEL with _rag_model in embed/generate calls - Add Dropdown + refresh button UI above the chatbot - Show confirmation message on model change - Warn user about cache/embedding mismatch when switching models - Populate model list on tab load Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a7c4e38 -
Speed up RAG indexing with batch embedding via Ollama /api/embed
Fabio Antonini +1: Claude Sonnet 4.6Replace sequential per-chunk HTTP calls with a single batch call to Ollama's /api/embed endpoint (available since v0.1.26). Falls back automatically to sequential _ollama_embed calls on older Ollama versions. Applied to both startup synthetic embedding and document indexing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bb78915 -
Fix Gradio 6.x chatbot: normalize content field (str or list of parts)
Fabio Antonini +1: Claude Sonnet 4.6Gradio 6.x returns message content as a list of parts on subsequent calls. Added _content_str() helper to handle both str and multimodal list formats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a294b90 -
Fix Chatbot for Gradio 6.x: use messages format (role/content dicts)
Fabio Antonini +1: Claude Sonnet 4.6Gradio 6.x Chatbot only accepts flat list of {"role", "content"} dicts. Updated rag_chat and save_conversation_md accordingly. Also removed unsupported type="tuples" parameter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2765cc2 -
Fix Chatbot format: add type="tuples" for Gradio 5.x compatibility
Fabio Antonini +1: Claude Sonnet 4.6Gradio 5.x changed the default Chatbot format to messages (dicts). Explicitly set type="tuples" to keep the existing list-of-lists format. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ad2d0d3 -
Fix Chatbot init: remove show_copy_button (not supported in installed Gradio)
Fabio Antonini +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>64a1110 -
Transform Consulente Forense IA into multi-turn streaming chatbot
Fabio Antonini +1: Claude Sonnet 4.6- Replace single-turn rag_query with rag_chat generator (streaming via Ollama stream=True, token-by-token output) - Add conversation memory: last 6 exchanges passed as context to LLM - Add Clear button (resets chat + hides download file) - Add Save button (exports conversation as timestamped Markdown) - Refactor retrieval into _rag_retrieve helper for reuse - Add _stream_ollama helper for streaming token generation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a92a7a8 -
Add persistent RAG cache, document list UI, and improved retrieval
Fabio Antonini +1: Claude Sonnet 4.6- Save/load embeddings to data/rag_cache/*.npz (survive restarts) - Remove auto-scan of data/knowledge/ folder; upload-only via WebUI - Add document list (gr.Dataframe) and remove button (gr.Dropdown) - Fix np.load context manager on Windows to allow cache file deletion - Hybrid retrieval: always include user-doc chunks + synthetic chunks - Fix SKLEARN_NO_POLARS to avoid polars circular import on startup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>34d758e
-
Add document upload to RAG tab (rag_add_docs + Accordion UI)
Fabio Antonini +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fef4e33 -
Add RAG knowledge base tab (Consulente Forense IA) with Ollama/Llama3.2
Fabio Antonini +1: Claude Sonnet 4.6- New tab with Q&A on forensic graphology via local Ollama (llama3.2) - 8 hardcoded synthetic texts covering pressure, slant, spacing, margins, authentic/forged signatures, writing speed, and document dating - Loads user PDFs/DOCX from data/knowledge/ at startup (with OCR fallback for scanned pages via pymupdf + EasyOCR already in requirements) - Chunking (500 char, 50 overlap) + cosine similarity retrieval via numpy - Embedding via Ollama /api/embeddings; generation via /api/generate - Chunks marked ready immediately after loading; embedding runs in background so queries work as soon as first chunks are indexed - Friendly error message when Ollama is not running - Add pypdf, pymupdf, python-docx to requirements.txt - Add data/knowledge/ folder (.gitkeep); exclude user docs from git Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>637b9bc -
Show CPU warning in title only on HF Spaces (SPACE_ID env var)
Fabio Antonini +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9710ad8 -
Add open-set rejection to writer identification (unknown writer detection)
Fabio Antonini +1: Claude Sonnet 4.6When the query handwriting is too far from all training samples in scaled feature space, writer_identify() now flags it as unknown instead of misleadingly assigning probabilities among known writers. - Two new globals: _writer_X_scaled, _writer_dist_threshold - _get_writer_model(): after training, computes max intra-class nearest- neighbour distance and sets threshold = max_intra × 2.0 (auto-calibrated) - writer_identify(): projects query into scaled space, checks min distance; if > threshold → warning header, disclaimer rows, grey bar chart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d6aca92 -
Fix grapho_analyse: adaptive threshold + 800px cap to eliminate dark-background artifact
Fabio Antonini +1: Claude Sonnet 4.6Replace global Otsu (which classifies dark photo borders as ink) with adaptive threshold (blockSize=31, local contrast). Cap image to 800px first so adaptive threshold remains fast (O(pixels × blockSize)). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>10fe2a4 -
Improve forensic pipeline: generator streaming, grapho contrast fix, writer pre-warm
Fabio Antonini +1: Claude Sonnet 4.6- run_pipeline: convert to generator (yield per step) to prevent Gradio timeout on long sequential inference; adds gr.Progress step labels - grapho_analyse: normalise contrast (2–98th percentile) before Otsu to avoid dark photo backgrounds being classified as ink (black-circle bug) - _get_writer_model: thread-safe with double-checked lock; pre-warm at startup in background thread so pipeline step 4 is always instant Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1cfe929 -
Fix: remove unsupported description param from TabbedInterface
Fabio Antonini +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d7a5b10 -
Add Hugging Face Spaces configuration
Fabio Antonini +1: Claude Sonnet 4.6- README.md: add HF Spaces YAML frontmatter (sdk=gradio, app_file=app/grapholab_demo.py, license=apache-2.0) - packages.txt: system deps for OpenCV on Ubuntu (libgl1-mesa-glx, libglib2.0-0) - grapholab_demo.py: add CPU performance warning in TabbedInterface description for Spaces users No functional changes — local and Docker usage unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>671cd63 -
Fix estrazione date in tab Datazione Documenti
Fabio Antonini +1: Claude Sonnet 4.6- extract_dates(): filtra date di nascita rilevando "nata/nato/nascita" nel contesto precedente il match regex - dating_rank(): rimuove preprocessing HTR (distrugge testo tipografico), usa paragraph=False per catturare blocchi isolati, seleziona la data più recente (dates[-1]) invece della più vecchia - Aggiorna doc_contratto_2001.png e doc_testamento_2024.png (data più prominente e senza date ambigue nel corpo testo) - Aggiunge scripts/create_test_dated_docs.py per generare i 3 documenti di test con date in formato italiano Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>177fa16
-
aggiunta datazione
Fabio Antoninic703301 -
Update grapholab_demo.py
Fabio Antonini73f01ee
-
Switch HTR engine from TrOCR to EasyOCR for Italian support
Fabio Antonini +1: Claude Sonnet 4.6- Replace microsoft/trocr-large-handwritten with EasyOCR (it+en) in both the Gradio demo and notebook 02; EasyOCR has native Italian language models and avoids the English-decoder bias of TrOCR - Remove pyspellchecker post-processing (was introducing errors) - EasyOCR handles multi-line detection internally; custom _segment_lines helper no longer needed in the demo - Add easyocr>=1.7.0 to requirements.txt, remove pyspellchecker Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>cb6423e -
HTR done with trocr-large-handwritten
Fabio Antonini2e955a9
-
Improve writer identification: TTF fonts + real sample database
Fabio Antonini +1: Claude Sonnet 4.6Replace geometric line-drawing with actual handwriting TTF fonts (Ink Free, Lucida Handwriting, Segoe Print, Segoe Script, Comic Sans) for visually legible synthetic samples. Add writer_00–04 database with 41 samples each (IDs 0–39 + 99) so the SVM trains on real data instead of the synthetic fallback, raising top-1 confidence to ~90%. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9ad6499
-
Add plain-language descriptions and result guides for non-expert audience
Fabio Antonini +1: Claude Sonnet 4.6Each of the 6 Gradio tabs now has: - Expanded description: explains what the tool does in plain Italian, removes unexplained acronyms, adds "Quando usarlo" context - New article section: "Come leggere il risultato" with concrete interpretation guidance, and "Cosa questo strumento non fa" to set correct expectations for forensic use Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3f9d492 -
Improve signature verification tab: multi-reference + visual output
Fabio Antonini +1: Claude Sonnet 4.6- sig_verify() now accepts an optional second reference image; when provided, embeddings are averaged (L2-renormalised) to reduce natural signature variance, matching forensic best practice - Replaced misleading "Confidenza %" with a clear cosine distance / similarity report and threshold annotation - Added matplotlib figure output: signature panels side-by-side + colour-coded gauge bar showing cosine distance vs. threshold - Added CEDAR examples to sig_verify_tab (3 FALSA pairs with 2 refs, 1 AUTENTICA pair with 1 ref) so the demo works out of the box Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c792d93 -
Add Writer Identification tab and presentation generator
Fabio Antonini +1: Claude Sonnet 4.6- app/grapholab_demo.py: new Tab 5 "Identificazione Scrittore" with HOG + LBP + run-length features and SVM classifier; synthetic 5-writer fallback when no real samples are present; bar-chart probability output - data/samples/writer_examples/: pre-generated synthetic handwriting samples for the Gradio examples panel (one per writer style) - tools/generate_presentation.py: new script that generates the Italian PowerPoint presentation programmatically with matplotlib diagrams - docs/NOTEBOOKS_GUIDE.md, NOTEBOOKS_GUIDE_IT.md: updated Gradio demo table from 5 to 6 tabs, added Identificazione Scrittore row - .gitignore: exclude .claude/settings.json (local Claude Code settings) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7b1c987 -
Translate user interface text to Italian for handwritten text recognition and signature verification features
Fabio Antonini7b1107a -
Update grapholab_demo.py
Fabio Antonini2bc9b5b -
Add Named Entity Recognition feature and update HTR functionality
Fabio Antonini60e7815
-
signet.pth
Fabio Antonini1c61ac2 -
Update grapholab_demo.py
Fabio Antoninif18ec81 -
Update grapholab_demo.py
Fabio Antonini97f748b -
Tuning
Fabio Antoninibfabc2f
-
Grapholab first commit
Fabio Antonini6979863