惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
Malwarebytes
Malwarebytes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
F
Future of Privacy Forum
C
Cisco Blogs
T
The Exploit Database - CXSecurity.com
A
Arctic Wolf
S
Securelist
K
Kaspersky official blog
S
Schneier on Security
T
ThreatConnect
T
Tenable Blog
Spread Privacy
Spread Privacy
T
True Tiger Recordings
AWS News Blog
AWS News Blog
F
Fox-IT International blog
量子位
T
Threatpost
V
Vulnerabilities – Threatpost
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
GbyAI
GbyAI
宝玉的分享
宝玉的分享
腾讯CDC
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
U
Unit 42
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
O
OpenAI News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
MyScale Blog
MyScale Blog
小众软件
小众软件
A
About on SuperTechFans
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
博客园 - 三生石上(FineUI控件)
美团技术团队
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog

DEV Community

What I’m Starting to Look for in Engineers An npm Downloads Comparison Chart in 300 Lines of Vanilla JS — Nice-Tick Math and API-Direct Fetch Transfer Fees, Metadata, and Soulbound Tokens: A Tour of Solana Token Extensions I got tired of re-explaining my codebase to ChatGPT — so I built a VS Code extension Revisiting My Phone AI After Gemma 4: The Upgrade I Didn't Know I Needed I built a privacy-first PDF merger in 7 hours — here's the stack and the lessons Google I/O 2026 made me ask an uncomfortable question: are we still coding, or are we managing builders? SSR with JavaScript: Escaping Node.js Clunkiness with AxonASP My CKA Exam-Day Experience: What Went Right, What Went Wrong, and Lessons Learned Gemma 4 Soft Tokens: The Rise and Fall of 16x16 Words ⚡👀 Two weeks ago, I built a private AI brain on my phone using Gemma 4. Yesterday, Google dropped a new variant that made everything I built feel like a beta test. 256M parameters. MoE architecture. Apache 2.0 license. I broke down what changed and why it mat I got tired of clicking through the Stripe dashboard, so I built a CLI Getting Data from Multiple Sources in Power BI: A Practical Guide to Modern Data Integration Google Is No Longer Just a Search Engine I built GemmaPod - A truly composable and portable AI agent solution powered by your local LLM Gemma 4 E4B caught three planted fabrications in 50 seconds — on a laptop, no cloud How to build an AI-powered content moderation pipeline for user comments Running Gemma 4 on a Modest Machine: Unsloth vs LM Studio vs llama.cpp vs Ollama AI Makes Building Cheap. Our Product Architectures Still Assume It’s Expensive. I built an in-browser Roku TV remote with ~80 lines of TypeScript. Here's how Roku's ECP API actually works The Direction of Blame babbled notes: a sound-to-music agent for people who could not make music before How I Built a Live SQL Workshop Where Students Can't Break Anything Rescuing a Stranded Protocol: Re-Skinning Legacy Code for the Trestle DeFi Flywheel SOLID Heuristics Reveal Incomplete Domain Knowledge — Nothing More AllasCode Intitute / FullAgenticStack: The Intent-Based Router Introducing LogicGrid — Multi-Agent AI Orchestration for .NET AI Prompt Injection, Drupal SQLi Exploitation, and Nmap for Hardening AI Agents & Python Workflows: Anthropic Skills, Jupyter Challenges, and Edge Deployment SQLite Optimization, PostgreSQL Async Queries, & DuckLake Dataframe Spec RTX 5080 Undervolt Benchmarks, CGO-Free CUDA API Binding, & AMD GPU Compatibility Fix Microsoft Burned Its 2026 AI Budget on Claude Code in Six Months. That's the Real Story. Why I Started Learning FastAPI in 2026 I Abandoned Ghost for Months — Then Came Back and Finally Finished It Building an Open MIT-Licensed Ephemeris Engine in C — JPL Moshier Ephemeris 4 Smart Ways to Manage Retries in Side Projects Securing Web APIs: A Practical Guide to Authentication & Authorization Methods Google I/O 2026: AI Built an OS in 12 Hours. I Spent Mine Sorting Screenshots. 🤦 Half a Day, Not a Week: One Nix Flake for Three Machines 🌱 Keep Feeding Your CI/CD — Or Watch It Die Gemma 4 vs GPT-4o vs Llama 3: What Actually Works Locally? Vessel Ops SSH in 2026: Why Every Developer Should Know It Cold Audit AI-Generated PRs Before You Merge Them (Swarm Orchestrator 10.3.0) App Store Optimization (ASO) I built a tool to visualize Django REST Framework architecture (URLs, Serializers, Models, and more) How I made my React site agent-ready in 100 lines AI Can Generate Interfaces on the Fly. But Users Still Need Orientation. AI-Assisted Content Workflow How We Learned That Most Resume Rejections Happen Before Humans See Your CV How I Prepared for CKA: Resources, Labs, and Strategy That Worked for Me Remix Mini PC: Moving the Whole Operating System Onto the eMMC Stop Flying Blind: We Built an LLM Evaluation Framework That Works Across 17+ Agent Frameworks The Misleading "User is not authorized to access connection" Error in AWS CodeBuild — and Why Your IAM Policy Looks Fine I Resurrected a Dead F1 Project and Accidentally Built a Race Intelligence OS Remix Mini PC: After a Year of Dead Ends, the eMMC Finally Talks Not All Games Are Equal: The Real Difference Between a Trap and a Tool How to add Peppol e-invoicing to your SaaS without making it your team's problem I Built a Hermes Agent to Tell Me Which Hackathons to Enter. It Told Me to Enter This One. The Five Hooks That Change How You Ship With Claude Code Powering Your Progress: Building Robust Solutions with Laravel I built a self-hosted CI/CD platform with persistent queue, encrypted secrets, and rollback UI — here's what I learned Antigravity 2.0 and the $1,000 OS: Why "Agent-First" Feels Like the Direction I've Been Building Toward Anyway I built an AI PR-triage agent in 30 lines of Markdown Core Web Vitals from 74 to 91: A Real Tax Practitioner Site Rebuild I Gave Gemma 4 150 Tools on Windows. Here's What Actually Happened. Beyond the Loop: Why Monolithic AI Agents Fail and How to Build a Microkernel Architecture The Hidden Tax of AI-Assisted Development (And How I Fixed It) I Ditched Cloud LLMs for Gemma 4 4B: A DevOps Engineer's 48-Hour Reality Check Building a Schema.org @graph That Validates on the First Try The "Lift and Shift" Trap: Why Your Integration Layer Needs More Than Just a Cloud Address All 7 OSI Layers Explained with Real-World Analogies Antigravity 2.0 in one day: the four shells and what each is good for Self-Hosting Google Fonts with size-adjust: Zero CLS Web Font Swap The Multi-Provider LLM Problem: Why “One API” Is Not Enough How I indexed 69,000 Claude Code skills (and what I learned doing it) RememberMe CareGrid: Local Gemma 4 for dementia memory and safety Google Is Killing Gemini CLI on June 18. Here Is What to Do Before Then Do Domínio ao Deploy: Hospedando Arquivos de Deep Links no Cloudflare Pages (Parte 7.1) Running Gemma 4 26B on an Old GTX 1080 with llama.cpp Devlog 1: I tried building an SNES game with the super FX chip Why Gemma 4 Feels Like an Important Moment for AI Developers✨ From Zero and Confused, This Is How I Started Learning to Code I Built a Local AI Gateway That Talks to Claude, ChatGPT, DeepSeek and Gemini — Without a Single API Key Bootstrapping with AI: Why Gemma 4 is the Micro-SaaS Founder’s Best Friend MyErp Architecture Series - #02 Cellular Architecture: Mapping Biology to Software Systems NodeJS vs Bun vs Go 🌍 RTL Arabic Style UI How Does an AI Agent Actually Buy Something? Google Just Published the Spec. Google I/O 2026 Is One Uncanny F.R.I.E.N.D.S Group Upgrade I Replaced 70MB Node.js Log Viewer with a 172KB Zig Binary The "MTTR Is All You Need" Trap The Quiet Revolution: How Firebase Became the First Agent-Native Backend at Google I/O 2026 I Built ResuMate! A 100% Private, Local AI Resume Optimizer with Google Gemma 4 Learning DirectX 12 - Part 2 Initialization Theory NeuralHats: I Put Edward de Bono’s Six Thinking Hats on Local LLMs Using Gemma 4 📝 Instant Auto Save Notes Engineering the "App-Like" Experience: A Deep Dive into PWA Architecture I built a local first AI CCTV assistant using Gemma 4 + Frigate CrowdShield AI — Smart Stadium Operating System & Crowd Intelligence Platform
Vitreus: Local-First Spreadsheet Intelligence with Gemma 4
divyaprakash · 2026-05-25 · via DEV Community

This is a submission for the Gemma 4 Challenge: Build with Gemma 4

TL;DR: Vitreus is a spreadsheet agent that lets you ask natural-language questions of CSV and XLSX workbooks, then uses Gemma 4 to return an auditable JSON action manifest. The manifest can highlight rows, write values, and add formulas; Vitreus then applies those changes to a CSV snapshot or a real .xlsx file with colors and formulas preserved.

I built it because spreadsheets are where a lot of real business logic lives: budgets, project trackers, sales forecasts, invoices, HR reviews, and messy exported reports. But the moment you ask an AI assistant to "just update the sheet," you run into a trust problem: what exactly did it change, and why?

Vitreus answers that by splitting the job in two:

  1. Gemma 4 reasons about the workbook.
  2. A deterministic driver applies only structured, reviewable actions.

The model never mutates the workbook directly.


What I Built

Vitreus is a local-first spreadsheet intelligence tool for developers, analysts, and teams who want AI help inside sensitive workbook workflows without giving the model unrestricted control.

The current project includes:

Capability Status Why it matters
CSV workbook snapshots Working Fast, portable test format for spreadsheet data
XLSX input and output Working Preserves cell values, formulas, and highlight colors
One-shot analyze --output flow Working No separate "generate JSON" and "apply JSON" steps
JSON action manifests Working Every model action is inspectable before execution
Local Gemma 4 via Ollama Supported Private local inference path
Google AI Studio backend Supported API-key path for users without local GPU access
Deterministic fallback planner Working CI and demos can run without a model
Chart/receipt image payload prep Working Foundation for multimodal spreadsheet workflows
Bash and Nushell command references Working Easy manual testing on Linux/Nushell systems

At a high level:

CSV/XLSX workbook
    |
    v
WorkbookSnapshot
    |
    v
compact JSON sheet context
    |
    v
Gemma 4 planner
    |
    v
JSON manifest: highlight / write_value / formula
    |
    v
InMemoryCalcDriver
    |
    v
CSV + sidecar JSON, or XLSX with colors/formulas

Enter fullscreen mode Exit fullscreen mode

This is not a chatbot bolted onto a spreadsheet. It is a small, testable agent pipeline where the model is responsible for reasoning and the application is responsible for safe execution.


Demo

Demo 1: Ask Gemma 4 to find budget problems

Input file: examples/sample_workbook.csv

It contains employee/project rows with columns like:

Name,Department,Q1_Target,Q1_Actual,Q2_Target,Q2_Actual,Score,Status,Budget,Spent,Notes
Ada Lovelace,Research,120000,128000,130000,135000,94,On Track,200000,184000,
Alan Turing,Security,90000,87000,95000,91000,72,Under Review,110000,135000,
...

Enter fullscreen mode Exit fullscreen mode

Command:

uv run vitreus analyze examples/sample_workbook.csv \
  "Highlight all rows where Spent exceeds Budget, and for each over-budget row write OVER BUDGET in the Notes column" \
  --backend google

Enter fullscreen mode Exit fullscreen mode

Actual output from the live API-key run:

{
  "model": {
    "primary": "gemma4:31b",
    "drafter": "gemma4:4b",
    "rationale": "Identified rows where Spent exceeds Budget: Alan Turing (Row 3) and Dennis Ritchie (Row 9). Applied highlights to these rows and updated the Notes column to 'OVER BUDGET'."
  },
  "actions": [
    {
      "type": "highlight",
      "range": "Sheet1!A3:K3",
      "color": "#f97316",
      "reason": "Spent (135000) exceeds Budget (110000)"
    },
    {
      "type": "write_value",
      "cell": "Sheet1!K3",
      "value": "OVER BUDGET",
      "reason": "Spent exceeds Budget"
    },
    {
      "type": "highlight",
      "range": "Sheet1!A9:K9",
      "color": "#f97316",
      "reason": "Spent (108000) exceeds Budget (90000)"
    },
    {
      "type": "write_value",
      "cell": "Sheet1!K9",
      "value": "OVER BUDGET",
      "reason": "Spent exceeds Budget"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

This is the core Vitreus pattern: Gemma 4 does the semantic reasoning, but the output is still machine-checkable.

Demo 2: One command, real XLSX output

CSV is useful, but CSV cannot store background colors or Excel formulas. So Vitreus supports one-shot XLSX export:

uv run vitreus analyze examples/sample_workbook.csv \
  "Highlight rows where Spent exceeds Budget in orange, write OVER BUDGET in the Notes column" \
  --backend google \
  --output /tmp/vitreus_result.xlsx

Enter fullscreen mode Exit fullscreen mode

The result is a real Excel workbook. Open it in LibreOffice Calc or Excel and the highlighted rows are actually colored.

Demo 3: XLSX in, XLSX out

I also created a larger workbook for testing:

examples/test_workbook.xlsx
├── Sales        25 data rows, quota and commission formulas
├── Expenses     24 data rows, annual budget/actual formulas
└── HR_Reviews   18 data rows, rating/bonus formulas

Enter fullscreen mode Exit fullscreen mode

Command:

uv run vitreus analyze examples/test_workbook.xlsx \
  "In the Expenses sheet, highlight rows where Annual_Actual exceeds Annual_Budget" \
  --backend google \
  --sheet Expenses \
  --output /tmp/vitreus_expenses_result.xlsx

Enter fullscreen mode Exit fullscreen mode

Recent smoke-test result:

{"applied": 1, "saved": "/tmp/vitreus_xlsx_test.xlsx", "errors": []}

Enter fullscreen mode Exit fullscreen mode


Code

https://github.com/divyaprakash0426/vitreus

Enter fullscreen mode Exit fullscreen mode

Important files:

File Responsibility
core/driver.py Workbook snapshots, CSV/XLSX loading, XLSX saving, manifest execution
core/reasoning.py Gemma 4 model policy, Ollama backend, Google AI Studio backend, manifest parsing
core/vision.py Image metadata and multimodal prompt payload preparation
interfaces/cli.py Typer CLI commands: models, analyze, apply-manifest, vision
examples/sample_workbook.csv Small CSV test dataset
examples/test_workbook.xlsx Larger multi-sheet XLSX test workbook
examples/test_commands.sh Bash demo/test command reference
examples/test_commands.nu Nushell demo/test command reference
tests/ 37 automated tests covering backends, CLI, driver, output, and vision

Try it:

git clone https://github.com/divyaprakash0426/vitreus.git
cd vitreus

uv sync --extra dev
uv run pytest -q
uv run vitreus models

Enter fullscreen mode Exit fullscreen mode

Run with Google AI Studio:

uv sync --extra integrations
export GEMINI_API_KEY="your_key_here"

uv run vitreus analyze examples/sample_workbook.csv \
  "Flag rows where Spent exceeds Budget and write OVER BUDGET in Notes" \
  --backend google

Enter fullscreen mode Exit fullscreen mode

Run locally with Ollama:

uv sync --extra integrations
ollama pull gemma4:31b

uv run vitreus analyze examples/sample_workbook.csv \
  "Summarise department-level spending risks" \
  --backend ollama

Enter fullscreen mode Exit fullscreen mode

Use the lighter local model:

uv run vitreus analyze examples/sample_workbook.csv \
  "Highlight rows that need review" \
  --backend ollama \
  --model gemma4:4b

Enter fullscreen mode Exit fullscreen mode


How I Used Gemma 4

Vitreus is designed around Gemma 4 31B Dense as the primary model.

Spreadsheet intelligence is a long-context reasoning task. A useful spreadsheet agent needs to:

  1. Read many rows without losing the column semantics.
  2. Understand user intent expressed in plain English.
  3. Compare related fields like Budget and Spent.
  4. Decide which cells or rows need attention.
  5. Generate valid spreadsheet references like Sheet1!A3:K3.
  6. Explain why each action is needed.
  7. Return strict JSON instead of prose.

That is why I chose the 31B Dense model as the default planner. It is the best fit for "read this workbook, understand the pattern, and produce a reliable action plan."

The project still supports smaller Gemma 4 models as a deliberate secondary path:

Model family Role in Vitreus Why
Gemma 4 31B Dense Primary planner Best fit for long-context workbook reasoning
Gemma 4 4B Drafter / edge assistant Lower latency for quick previews and constrained hardware
Gemma 4 26B MoE Future throughput path Useful when many independent workbook requests need efficient routing

The model policy is encoded directly in the project:

@dataclass(frozen=True)
class GemmaModelChoice:
    primary: str
    drafter: str
    rationale: str

    @classmethod
    def default(cls) -> "GemmaModelChoice":
        return cls(
            primary="gemma4:31b",
            drafter="gemma4:4b",
            rationale=(
                "Gemma 4 31B Dense is the default because Vitreus needs local, "
                "long-context workbook reasoning and stronger multimodal planning; "
                "Gemma 4 4B remains useful as a low-latency drafter on edge hardware."
            ),
        )

Enter fullscreen mode Exit fullscreen mode

The prompt requires JSON only:

You are Vitreus, a spreadsheet intelligence agent running gemma4:31b.
Analyze the spreadsheet data below and respond with ONLY a valid JSON manifest.

Task: Highlight rows where Spent exceeds Budget.

Required JSON response shape:
{
  "model": {"primary": "gemma4:31b", "drafter": "gemma4:4b", "rationale": "..."},
  "actions": [
    {
      "type": "highlight|write_value|formula",
      "range": "Sheet1!A1:B2",
      "cell": "Sheet1!C2",
      "value": "...",
      "formula": "=SUM(A1:A10)",
      "color": "#f97316",
      "reason": "why this action is needed"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

That contract is the heart of the project. Gemma 4 is not asked to "edit a spreadsheet." It is asked to produce a plan that Vitreus can inspect and execute.


How It Works Internally

1. WorkbookSnapshot: turn sheets into model context

Vitreus reads CSV and XLSX files into a simple in-memory representation:

@dataclass
class WorkbookSnapshot:
    sheets: dict[str, list[list[Any]]]

Enter fullscreen mode Exit fullscreen mode

The snapshot can load:

WorkbookSnapshot.from_csv("scores.csv")
WorkbookSnapshot.from_xlsx("workbook.xlsx", sheet_name="Expenses")
WorkbookSnapshot.from_file("workbook.xlsx", sheet_name="Sales")

Enter fullscreen mode Exit fullscreen mode

Then it exports the requested range as compact JSON:

[
  {"Name": "Alan Turing", "Budget": 110000, "Spent": 135000},
  {"Name": "Dennis Ritchie", "Budget": 90000, "Spent": 108000}
]

Enter fullscreen mode Exit fullscreen mode

This gives Gemma 4 useful semantic structure: headers become keys, rows become records, and the model does not have to infer everything from raw cell coordinates.

2. Backends: local-first, cloud-optional

Vitreus supports three execution modes:

Backend Command Use case
Fallback default CI, demos, no model required
Ollama --backend ollama Local Gemma 4 inference
Google AI Studio --backend google API-key run when local GPU is unavailable

The backends are small adapter classes:

class OllamaBackend:
    def call(self, prompt: str) -> str:
        from ollama import chat
        response = chat(model=self.model, messages=[{"role": "user", "content": prompt}])
        return response.message.content

class GoogleAIBackend:
    def call(self, prompt: str) -> str:
        from google import genai
        client = genai.Client(api_key=self.api_key)
        response = client.models.generate_content(model=self.model, contents=prompt)
        return response.text

Enter fullscreen mode Exit fullscreen mode

The lazy imports are intentional. The core package can be installed and tested without Ollama, Google GenAI, LibreOffice, or cloud credentials.

3. Manifest execution: structured actions only

The executor supports three action types:

{"type": "highlight", "range": "Sheet1!A3:K3", "color": "#f97316", "reason": "..."}
{"type": "write_value", "cell": "Sheet1!K3", "value": "OVER BUDGET"}
{"type": "formula", "cell": "Sheet1!J11", "formula": "=SUM(J2:J10)", "reason": "..."}

Enter fullscreen mode Exit fullscreen mode

Unsupported action types are rejected instead of silently ignored. This keeps the model inside a narrow, auditable capability boundary.

4. CSV vs XLSX: the boring detail that mattered

CSV cannot store background colors or formulas as spreadsheet formulas. Early testing made that painfully obvious: a manifest could say "highlight this row," but a CSV output could only store text.

So Vitreus handles both formats explicitly:

Output Behavior
.csv Saves values and writes highlights to <name>_highlights.json
.xlsx Saves values, formulas, and real cell background colors

That means users get a clear warning for CSV:

CSV format cannot store cell colors or formulas.
write_value changes are saved in result.csv
Highlight colors -> result_highlights.json
Tip: use --output result.xlsx to preserve everything in one file.

Enter fullscreen mode Exit fullscreen mode

And they get real spreadsheet formatting when they choose XLSX.


The Technical Problems That Shaped the Project

Problem 1: "AI changed my spreadsheet" is not good enough

If a spreadsheet agent directly mutates a workbook, the user has to trust a black box.

The fix was the manifest contract. Every action contains:

  • the action type,
  • the exact cell or range,
  • the value/formula/color,
  • and the reason.

That makes it possible to log, review, diff, test, or reject model output before execution.

Problem 2: Local-first should not mean "local-only"

My preferred path is Ollama with gemma4:31b, but not every developer has a GPU available. I hit this myself while testing away from my GPU profile.

So Vitreus supports both:

# Local
uv run vitreus analyze examples/sample_workbook.csv "..." --backend ollama

# API key
uv run vitreus analyze examples/sample_workbook.csv "..." --backend google

Enter fullscreen mode Exit fullscreen mode

The model interface stays the same. Only the backend changes.

Problem 3: Multi-sheet XLSX files are the real spreadsheet format

CSV was useful for early tests, but real workbooks have sheets, formulas, styles, and business structure.

The latest version added:

WorkbookSnapshot.from_xlsx(path, sheet_name="Expenses")
WorkbookSnapshot.from_xlsx(path, all_sheets=True)
WorkbookSnapshot.from_file(path, sheet_name="Sales")

Enter fullscreen mode Exit fullscreen mode

The CLI now accepts .xlsx as input:

uv run vitreus analyze examples/test_workbook.xlsx \
  "In the Sales sheet, highlight reps below quota" \
  --sheet Sales \
  --output /tmp/sales_review.xlsx

Enter fullscreen mode Exit fullscreen mode

Problem 4: Tests need to run without secret keys or local models

The project has 37 automated tests. They cover:

  • backend adapter construction,
  • CLI flags,
  • missing API key behavior,
  • manifest parsing,
  • CSV save behavior,
  • XLSX values,
  • XLSX formulas,
  • XLSX cell colors,
  • XLSX input loading,
  • and the multi-sheet test workbook shape.

The deterministic fallback planner is not a replacement for Gemma 4. It exists so the execution pipeline can be tested without depending on a network call or a local model.


Why This Is a Good Gemma 4 Use Case

Gemma 4 is doing real work here. It is not decorative.

The model is responsible for the part that is hard to encode as rules:

  • understanding workbook headers,
  • mapping natural-language requests to spreadsheet operations,
  • comparing values across columns,
  • deciding which rows need attention,
  • generating formulas,
  • and explaining each action.

The surrounding application does the parts software should do:

  • loading files,
  • constraining the action schema,
  • validating JSON,
  • applying known operations,
  • preserving output formats,
  • and keeping the workflow auditable.

That division is what makes the project useful. Gemma 4 supplies reasoning; Vitreus supplies guardrails.


Current Limitations

Vitreus is already useful for CSV/XLSX workflows, but there are areas I would keep improving:

Area Current state Next step
LibreOffice live control Adapter planned from blueprint Wire PyUNO to a running Calc socket
Multimodal receipts/charts Payload prep implemented Feed images into Gemma 4 multimodal backend
Multi-sheet reasoning Sheet-specific input works Add whole-workbook summarization
Formula safety Formula strings are written Add formula linting and policy controls
Review UI Terminal-first Add a small manifest review screen

The design intentionally keeps these as separable layers. The workbook reader, reasoning engine, and manifest executor can evolve independently.


What I Learned

The biggest lesson was that a good spreadsheet agent is less about "letting AI use Excel" and more about designing a trustworthy boundary between reasoning and execution.

Gemma 4 is capable enough to understand messy tabular context and produce useful spreadsheet plans. But the application still needs to say:

  • here is the allowed action vocabulary,
  • here is the exact JSON shape,
  • here is how output will be applied,
  • and here is what happens when a format cannot represent an action.

That is the difference between an impressive demo and a tool I would trust with a real workbook.


Acknowledgements

Built with:

  • Gemma 4 31B Dense as the primary reasoning model
  • Gemma 4 4B as the drafter/edge model path
  • Ollama for local model execution
  • Google AI Studio for API-key testing
  • Typer for the CLI
  • openpyxl for XLSX input/output
  • pytest for the test suite
  • LibreOffice Calc as the target spreadsheet environment