Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d798bfb
fix: import Union in main.py and correct pytest directory in Makefile
Mar 31, 2026
6fd3496
feat(pdf): Map Boolean Checkbox and Radio States & Fix main.py NameError
Mar 31, 2026
15122f6
Merge branch 'upstream/main' into fix/startup-and-tests
Dotify71 May 15, 2026
9feeb78
feat(pdf): enforce strict boolean typing for checkbox/radio fields
Dotify71 May 15, 2026
6977124
Merge upstream/main and resolve conflicts
Dotify71 May 24, 2026
a10663d
fix: add strict boolean schema validation and retry loop
Dotify71 May 26, 2026
c525c9b
Merge branch 'main' into fix/startup-and-tests
Dotify71 Jun 13, 2026
b27e5b7
refactor: replace Union with modern syntax and remove unused method call
Dotify71 Jul 4, 2026
0a959b0
fix: remove trailing whitespace in main.py
Dotify71 Jul 4, 2026
19b16c2
chore: fix f-string lint error
Dotify71 Jul 13, 2026
f4a21eb
fix: resolve ruff linter errors
Dotify71 Jul 28, 2026
7ebb951
fix: resolve ruff lint errors (I001 and SIM102)
Dotify71 Jul 30, 2026
fd57583
feat: :sparkles: first implementation of the benchmark, including fro…
marcvergees Aug 1, 2026
91fd496
fix: :bug: fixing test passing with empty structure of everything
marcvergees Aug 3, 2026
4927d9a
style: :lipstick: adding notes for guys
marcvergees Aug 3, 2026
73a382c
feat: add large-model reference evaluator
vharkins1 Aug 12, 2026
684ebfa
ics201 & 202
marcvergees Aug 13, 2026
fe000b1
ics203
marcvergees Aug 13, 2026
d9f0499
ics204
marcvergees Aug 13, 2026
a3ab05a
ics205 & ics205a
marcvergees Aug 13, 2026
2f24ff8
ics 206 & ics 213
marcvergees Aug 13, 2026
559030d
ics207 & ics 208
marcvergees Aug 13, 2026
2a6cd2b
ICS dataset generation markdown
marcvergees Aug 13, 2026
ce908a5
Merge pull request #663 from fireform-core/659-dataset-creations
vharkins1 Aug 13, 2026
2dd9e3a
refactor: :recycle: linting errors
marcvergees Aug 13, 2026
157e01a
linter errors 2
marcvergees Aug 13, 2026
86ade1b
Merge pull request #662 from fireform-core/612-feat-benchmark-module-…
marcvergees Aug 13, 2026
cb25b47
feat: :sparkles: add ics201-208 & 213 pdfs
marcvergees Aug 14, 2026
13806d2
refactor: :recycle: delete reference_benchmarks
marcvergees Aug 14, 2026
2378c26
feat: :sparkles: implementation of pdfs in the runner
marcvergees Aug 14, 2026
57d3d3b
Merge pull request #668 from fireform-core/667-add-pdfs-to-benchmark
marcvergees Aug 14, 2026
d71e765
Merge development and resolve conflicts
Dotify71 Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Run Pipeline Benchmark

on:
pull_request:
branches: [ main, development ]

jobs:
benchmark:
runs-on: ubuntu-latest

services:
ollama:
image: ollama/ollama:latest
ports:
- 11434:11434

steps:
- name: Checkout PR Branch
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest

- name: Run PR Branch Benchmark
run: |
pytest benchmark/test_benchmark.py -v
mv benchmark/benchmark_report.json branch_report.json

- name: Checkout Target Branch
uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
clean: false

- name: Run Target Branch Benchmark
run: |
pytest benchmark/test_benchmark.py -v
mv benchmark/benchmark_report.json target_report.json

- name: Compare Benchmarks
id: compare
run: |
python benchmark/compare_benchmarks.py branch_report.json target_report.json > comparison.md
cat comparison.md

- name: Comment PR with results
uses: thollander/actions-comment-pull-request@v3
with:
filePath: comparison.md
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ frontend/release/

# Local Claude Code instructions
CLAUDE.md

*temp/
*.env*
*.env*
.aider*
14 changes: 11 additions & 3 deletions alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config, pool

from sqlmodel import SQLModel

from alembic import context
from app.core.config import DATABASE_URL
from app.models import Extraction, Form, FormSubmission, Incident, Input, Job, Report, Template # noqa: F401
from app.models import ( # noqa: F401
Extraction,
Form,
FormSubmission,
Incident,
Input,
Job,
Report,
Template,
)

config = context.config

Expand Down
3 changes: 2 additions & 1 deletion alembic/versions/001_initial_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
"""
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa
import sqlmodel

from alembic import op

revision: str = "001"
down_revision: str | None = None
branch_labels: str | Sequence[str] | None = None
Expand Down
3 changes: 2 additions & 1 deletion alembic/versions/002_v1_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa
import sqlmodel

from alembic import op

revision: str = "002"
down_revision: str | None = "001"
branch_labels: str | Sequence[str] | None = None
Expand Down
4 changes: 3 additions & 1 deletion app/api/deps.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from app.db.database import get_session
from fastapi import Header, Request

from app.core.config import FIREFORM_API_KEY
from app.core.errors.base import AppError
from app.db.database import get_session


def get_db():
yield from get_session()
Expand Down
4 changes: 2 additions & 2 deletions app/api/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from . import templates, forms
from . import forms, templates

__all__ = ["templates", "forms"]
__all__ = ["forms", "templates"]
22 changes: 14 additions & 8 deletions app/api/routes/forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from datetime import datetime, timedelta, timezone
from pathlib import Path

import requests
from fastapi import APIRouter, Depends, File, UploadFile, Query
from fastapi import APIRouter, Depends, File, Query, UploadFile
from sqlmodel import Session, select

from app.api.deps import get_db, verify_api_key
Expand All @@ -11,12 +12,17 @@
ModelsResponse,
TranscriptionResponse,
)
from app.core.config import OLLAMA_HOST, OLLAMA_MODEL, BASE_DIR, RETENTION_PERIOD_DAYS
from app.services.whisper import call_whisper_asr
from app.core.config import BASE_DIR, OLLAMA_HOST, OLLAMA_MODEL, RETENTION_PERIOD_DAYS
from app.core.errors.base import AppError
from app.db.repositories import create_form, get_template, get_form_submission, delete_form_submission
from app.db.repositories import (
create_form,
delete_form_submission,
get_form_submission,
get_template,
)
from app.models import FormSubmission, Template
from app.services.controller import Controller
from app.services.whisper import call_whisper_asr

PROJECT_ROOT = BASE_DIR

Expand Down Expand Up @@ -175,8 +181,9 @@ def get_submissions(db: Session = Depends(get_db)):

@router.get("/submissions/analytics")
def get_submissions_analytics(db: Session = Depends(get_db)):
from collections import Counter
import re
from collections import Counter

from sqlmodel import select

statement = select(FormSubmission, Template.name).join(
Expand All @@ -194,9 +201,8 @@ def get_submissions_analytics(db: Session = Depends(get_db)):
"the", "and", "a", "of", "to", "in", "is", "that", "it", "was", "for", "on",
"as", "with", "by", "at", "an", "be", "this", "are", "from", "or", "have",
"has", "had", "but", "not", "he", "she", "they", "we", "i", "you", "my", "his",
"her", "their", "our", "me", "him", "them", "us", "about", "there", "their",
"were", "been", "would", "could", "should", "will", "can", "no", "yes", "any",
"so", "very", "patient", "presents", "with", "reported", "history", "shows",
"her", "their", "our", "me", "him", "them", "us", "about", "there", "were", "been", "would", "could", "should", "will", "can", "no", "yes", "any",
"so", "very", "patient", "presents", "reported", "history", "shows",
"left", "right", "pain", "due", "after", "before", "emergency", "department",
"medical", "clinical"
}
Expand Down
3 changes: 2 additions & 1 deletion app/api/routes/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
INPUT_POLL_INTERVAL_SECONDS,
)
from app.core.errors.base import AppError
from app.db.repositories import create_input, get_input as repo_get_input
from app.db.repositories import create_input
from app.db.repositories import get_input as repo_get_input
from app.services.input import InputService
from app.services.whisper import check_whisper_available

Expand Down
16 changes: 10 additions & 6 deletions app/api/routes/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@

from fastapi import APIRouter, Depends, File, Form, HTTPException, Query, UploadFile
from fastapi.responses import FileResponse
from sqlmodel import Session
from sqlmodel import Session, select

from app.api.deps import get_db, verify_api_key
from app.api.schemas.templates import (
MakeFillableRequest,
MakeFillableResponse,
TemplateCreate,
TemplateResponse,
TemplateUploadResponse,
MakeFillableRequest,
MakeFillableResponse,
)
from app.core.config import BASE_DIR, DEFAULT_TEMPLATE_DIR
from app.db.repositories import create_template, list_templates, get_template, delete_template
from app.models import Template, FormSubmission, Job
from app.db.repositories import (
create_template,
delete_template,
get_template,
list_templates,
)
from app.models import FormSubmission, Job, Template
from app.services.controller import Controller
from sqlmodel import select

router = APIRouter(prefix="/templates", tags=["templates"])
PROJECT_ROOT = BASE_DIR
Expand Down
1 change: 1 addition & 0 deletions app/api/schemas/templates.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pydantic import BaseModel


class TemplateCreate(BaseModel):
name: str
pdf_path: str
Expand Down
3 changes: 2 additions & 1 deletion app/core/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

# Optional Celery Beat schedule — runs purge_old_submissions once a day.
# Enable by running: celery -A app.core.celery beat
from celery.schedules import crontab # noqa: E402
from celery.schedules import crontab

celery_app.conf.beat_schedule = {
"daily-submission-purge": {
"task": "purge_old_submissions",
Expand Down
2 changes: 1 addition & 1 deletion app/db/init_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import logging
from pathlib import Path

from alembic import command
from alembic.config import Config
from sqlmodel import Session, select

from alembic import command
from app.core.config import DEFAULT_TEMPLATE_DIR
from app.db.database import engine
from app.models import FormSubmission, Template # noqa: F401
Expand Down
3 changes: 2 additions & 1 deletion app/db/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from sqlmodel import Session, select

from app.models import Template, FormSubmission, Job, Input
from app.models import FormSubmission, Input, Job, Template


# Templates
def create_template(session: Session, template: Template) -> Template:
Expand Down
10 changes: 5 additions & 5 deletions app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
)

__all__ = [
"Template",
"FormSubmission",
"Job",
"Input",
"Extraction",
"Incident",
"Form",
"FormSubmission",
"Incident",
"Input",
"Job",
"Report",
"Template",
]
6 changes: 3 additions & 3 deletions app/models/models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import uuid as uuid_mod
from uuid import UUID, uuid4
from datetime import date, datetime, timezone
from uuid import UUID, uuid4

from sqlalchemy import Column, JSON
from sqlmodel import SQLModel, Field
from sqlalchemy import JSON, Column
from sqlmodel import Field, SQLModel
from sqlmodel.sql.sqltypes import AutoString

from app.api.schemas.enums import (
Expand Down
4 changes: 2 additions & 2 deletions app/services/controller.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from app.services.file_manipulator import FileManipulator
from app.services.external_apis_coordinator import ExternalAPIsCoordinator
from app.services.file_manipulator import FileManipulator


class Controller:
def __init__(self):
self.file_manipulator = FileManipulator()
self.external_apis_coordinator = ExternalAPIsCoordinator()

def fill_form(self, user_input: str, fields: list, pdf_form_path: str, model: str = None):
def fill_form(self, user_input: str, fields: list, pdf_form_path: str, model: str | None = None):
return self.file_manipulator.fill_form(user_input, fields, pdf_form_path, model=model)

def prepare_fillable(self, pdf_path: str):
Expand Down
1 change: 0 additions & 1 deletion app/services/external_apis/weather_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import openmeteo_requests

import pandas as pd
import requests_cache
from retry_requests import retry
Expand Down
2 changes: 1 addition & 1 deletion app/services/external_apis/zipcode_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from geopy.exc import GeocoderServiceError, GeocoderTimedOut
from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut, GeocoderServiceError

from app.core.logging import get_logger

Expand Down
3 changes: 2 additions & 1 deletion app/services/external_apis_coordinator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from app.services.external_apis.zipcode_api import ZipCodeAPI
from app.services.external_apis.weather_api import WeatherAPI
from app.services.external_apis.zipcode_api import ZipCodeAPI


class ExternalAPIsCoordinator:
def __init__(self):
Expand Down
3 changes: 2 additions & 1 deletion app/services/file_manipulator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os

from app.core.logging import get_logger
from app.services.filler import Filler
from app.services.llm import LLM
from app.core.logging import get_logger

logger = get_logger(__name__)

Expand Down
Loading