This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 2 (Side Hustle).
What I Built
Update2Report takes the messy updates a small team posts in chat during the week, plus an optional task CSV, and turns them into a weekly report you can send to a client: a short summary, a printable HTML page, and an Excel workbook.
The person I built it for is the lead of a 5 to 20 person outsourcing or ops team. Every Friday they scroll back through stand-up messages, copy lines into a document, count what got done, and tidy the wording. That is about two hours of work that nobody enjoys and nobody bills for. I think that is a task someone would pay to stop doing.
The thing I cared about most was trust. A report that sends a client "5 docs written" when the team wrote 4 is worse than no report. So the model does the language work, and plain Python does the counting and checking.
Demo
Live demo: http://8.138.157.149
Paste updates like these (all fictional):
Alice: finished login page redesign, 2 bugs fixed, blocked on API spec.
Bob: migrated billing cron to new scheduler; load test pending.
Chen: wrote 5 onboarding docs; started FAQ, 40% done.
The generated summary kept the 2, the 5 and the 40%, and did not add any people, projects or numbers that were not in the input. You also get a statistics table with Project, Owner, Completed, In progress and Blockers.
A few things about the demo itself:
- There are buttons for cached sample inputs. They cost nothing and always work.
- Live generation has a per-IP hourly cap and a daily cap, and I can switch it off with one setting. When it is off, or when the model endpoint is unreachable, the page says cached samples still work instead of showing a stack trace.
- Please do not paste anything sensitive into a public demo.
Code
| title | Update2Report |
|---|---|
| emoji | 📋 |
| colorFrom | blue |
| colorTo | indigo |
| sdk | gradio |
| sdk_version | 5.50.0 |
| python_version | 3.11 |
| app_file | app.py |
| pinned | false |
| license | mit |
Update2Report
Turn messy team notes into a printable weekly HTML report and an Excel workbook. Open-weight models are the core of Update2Report—they extract structured tasks from unstructured updates and draft natural summaries, while deterministic Python code computes trusted statistics and cross-checks every number in the summary against ground truth. The public demo runs DeepSeek's open-weight DeepSeek-V4.1-Flash (MIT) through an OpenAI-compatible gateway, with OpenAI's open-weight gpt-oss-120b (Apache 2.0) as the fallback model; point LLM_BASE_URL at another provider or a local Ollama instance to use a different backend. All bundled Northwind Studio data is fictional.
Run locally
git clone https://github.com/jsonpang/update2report.git
cd update2report
python -m pip install -r requirements.txt
Copy-Item .env.example .env
# Edit .env with your own endpoint, key and model, then start:
python…MIT licensed. The Python package is in update2report/, the Gradio app is app.py, and there are 52 tests.
How I Built It
Stack. Python, Gradio for the UI, and an OpenAI-compatible client for the model. The model is DeepSeek's open-weight DeepSeek-V4.1-Flash, licensed under MIT, with OpenAI's open-weight gpt-oss-120b (Apache 2.0) as the fallback. The model connection is three environment variables, LLM_BASE_URL, LLM_API_KEY and LLM_MODEL, so swapping the model or the host means changing those and no code. The public demo has a few more settings of its own (rate limits and a switch to pause live generation). An optional LLM_FALLBACK_MODEL retries once on a second model if the first is rate-limited or down.
Split of work. The model does two jobs: pull structured tasks (project, owner, status, blockers) out of free text, and write the summary in either an internal or a client-facing tone. Everything that can be a fact is computed in code.
Checks around the model.
- Extraction validation. The extracted JSON is validated deterministically. If it is malformed, the model gets one correction attempt.
- Number preservation. Every number and percentage in the source must appear in the summary. If one is missing, the summary is regenerated once. If it is still missing, the report appends a "Numbers from source:" list, so a figure is never silently dropped.
- No invention. Any number in the summary, digits or words like "three", must exist in the source, and capitalized names in the summary (people, projects) must appear in the source too. Otherwise the draft is rejected and rewritten once with the reason attached. The name check is a simple word match, so it catches made-up names, not every wrong attribution.
- Statistics from code. The Project / Owner / Completed / In progress / Blockers table is computed in Python, not written by the model. If a CSV is supplied, chat items and CSV tasks are deduplicated by task name within each project, so the same task is not counted twice.
These checks do not prove that extraction is semantically perfect. They make sure the numbers a client sees match what the team wrote, and when something is off, the failure is visible.
AI assistance. I used AI coding assistants (Codex and Claude) while writing the code and tests. I reviewed and ran the results myself, and the design above is mine.
Why Does Open Innovation Matter?
Privacy is the main reason, and cost is second.
A weekly report contains client names, delivery status and sometimes complaints. A team lead may not be allowed to paste that into a hosted chatbot, and a client may not want them to. Because the model is open-weight and the app speaks to any OpenAI-compatible endpoint, you can point LLM_BASE_URL at a local Ollama server and the notes never leave your machine. With a closed model that option does not exist.
Cost is the other half. The task is small: a few thousand characters in, a few hundred out, once a week. A small open model on hardware you already own is enough, and there is no per-seat or per-token bill to explain to a client. I also did not have to build around one vendor's API, which matters for a tool I may want to sell or hand over.
Where it did not do better: a larger hosted model writes smoother prose. That is why the checks exist. I would rather have a slightly plainer summary with correct numbers.
My First User
I do not have a paying user yet. Before the deadline I plan to ask a few team leads to run it on a real week of their own notes, and I will update this post with what they say, including whether anyone would pay.
What's Next
- Test with local Ollama models of different sizes and record how often the number check has to fall back to the "Numbers from source" list.
- Support more input formats, such as exported chat logs.
- Offer a hosted version for people who do not want to run it themselves, and a self-hosted setup for people who care most about privacy.
Prize Categories
None that I am aware of fit, so I am not listing any.



Top comments (0)