Skip to content

feat(agents): add GAIA Inbox Zero Agent for LLM-powered email triage#916

Draft
antmikinka wants to merge 4 commits intoamd:mainfrom
antmikinka:worktree-draft-email-inbox-agent
Draft

feat(agents): add GAIA Inbox Zero Agent for LLM-powered email triage#916
antmikinka wants to merge 4 commits intoamd:mainfrom
antmikinka:worktree-draft-email-inbox-agent

Conversation

@antmikinka
Copy link
Copy Markdown
Collaborator

Summary

  • Introduces gaia-inbox-zero-agent — a production-ready email triage and inbox management agent built on the GAIA
    agent framework
  • Classifies real Gmail data (MBOX takeout files) into 5 priority categories: URGENT, NEEDS_RESPONSE, FYI,
    PROMOTIONAL, PERSONAL
  • Supports both Lemonade (local AMD NPU/GPU inference) and Anthropic Claude as LLM backends
  • Direct GAIA-equivalent of the OpenClaw inbox-zero-helper.yaml ClawFlow automation

What's Included

Component Description
agent/inbox_zero.py InboxZeroAgent — GAIA Agent subclass with email triage tools
agent/classifiers.py Heuristic + LLM email classification engine
agent/config.py Centralized configuration via env vars
data/email_loader.py Gmail MBOX takeout parser
cli/batch_classifier.py Standalone CLI for batch processing emails
schema/result_schema.py TaskResult / BatchMetrics dataclasses
automations/inbox-zero-helper.yaml OpenClaw ClawFlow definition
tests/ 4 test files covering all major components

Architecture

MBOX File → email_loader → batch_classifier → LLM API → Results JSON

InboxZeroAgent (GAIA)
Tools: fetch, classify, archive, group

Test Plan

  • pytest tests/ -v passes all 4 test files
  • Batch classifier CLI runs against a real MBOX file
  • Lemonade (local) provider classification works end-to-end
  • Anthropic provider classification works with ANTHROPIC_API_KEY set
  • InboxZeroAgent.process_in_batches() aggregates metrics correctly

Notes

  • Agent gracefully degrades if GAIA framework is not installed (standalone CLI still works)
  • All config via environment variables — see .env.example
  • Default model: Qwen3.5-35B-A3B-GGUF (AMD Ryzen AI optimized)

🤖 Generated with Claude Code

antmikinka and others added 2 commits April 27, 2026 14:11
Imports the complete gaia-inbox-zero-agent package including agent logic,
email classifiers, data loader, result schema, CLI batch classifier,
automation YAML, and full test suite for inbox zero email management.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@antmikinka antmikinka self-assigned this Apr 27, 2026
@antmikinka
Copy link
Copy Markdown
Collaborator Author

Still must update:

  • this to be similar to Openclaw Exmaple, where its not generating output per batch.
  • only classification of 20 emails ~ each batch

Copy link
Copy Markdown
Collaborator

@itomek itomek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! The classification logic and test scaffolding are reasonable, but as submitted this reads more like an out-of-tree project that optionally imports GAIA than a GAIA-native agent. A few things need to change before this can land.

Critical

  1. Silent ImportError fallback in gaia_inbox_zero/agent/inbox_zero.py:

    try:
        from gaia.agents.base.agent import Agent
        from gaia.agents.base.tools import tool
        ...
    except ImportError:
        Agent = object
        tool = lambda f: f
        ...

    This violates the "No Silent Fallbacks — Fail Loudly" rule in CLAUDE.md. If GAIA isn't installed, InboxZeroAgent becomes an empty object subclass and @tool is a no-op — the agent appears to construct fine but registers no tools and does nothing. Please make gaia a hard dependency in pyproject.toml and remove the stub branch.

  2. Out-of-tree package structure. GAIA agents belong under src/gaia/agents/<name>/ and register through src/gaia/agents/registry.py (preferably via a YAML manifest, with reusable tools opted in from KNOWN_TOOLS). This PR adds a parallel package at the repo root with its own pyproject.toml — it isn't discoverable by the registry, isn't invocable as gaia <subcommand>, and duplicates LLM-client wiring already present in src/gaia/llm/. Please move the package under src/gaia/agents/inbox_zero/ and register it.

Major

  1. Hardcoded Windows user path in gaia_inbox_zero/data/email_loader.py: r"C:\Users\antmi\Downloads\..." (also mirrored in .env.example). Not portable across machines or OSes. Default to None and raise an actionable error when MBOX_PATH is unset.

  2. No documentation updates. CLAUDE.md "Documentation Requirements" mandates a .mdx in docs/guides/ and an entry in docs/docs.json for every new feature. Neither is touched here.

  3. No CLI integration. Should register a gaia inbox-zero subcommand in src/gaia/cli.py (or a gaia-inbox-zero console_script in setup.py) instead of a private python -m gaia_inbox_zero.cli.batch_classifier entrypoint that's invisible to gaia -h.

  4. Reuses none of the GAIA LLM stack. The agent rolls its own provider switching for Lemonade vs. Anthropic instead of using gaia.llm.factory / lemonade_client.py / providers/claude.py. This bypasses model selection, retries, and error-translation conventions, and means future LLM-stack improvements won't apply here.

Minor

  1. ANTHROPIC_API_KEY defaults to "" in agent/config.py — produces confusing 401s deep in the request path instead of a clear "ANTHROPIC_API_KEY is not set" error at startup. Use os.environ.get("ANTHROPIC_API_KEY") and validate at agent init.

  2. Token counts in BatchMetrics are estimated as len(text) // 4. Both Anthropic and Lemonade responses expose real usage.input_tokens / usage.output_tokens — use those instead.

  3. Tests mock the GAIA base Agent ("requires the full GAIA package"). Once the package moves in-tree, drop the mock and exercise the real base class — otherwise the tests can't detect breakage in the integration they advertise.

  4. _validate_path() in email_loader.py resolves and existence-checks the path but doesn't constrain it to a sandbox. Either document the trust model or restrict to a configurable root.

Recommendation

Reshape into src/gaia/agents/inbox_zero/ (Python class or YAML manifest in registry.py), wire it through the existing LLM factory, add a gaia inbox-zero CLI subcommand, write a docs/guides/inbox-zero.mdx (and add it to docs/docs.json), drop the silent fallbacks, and replace the hardcoded path. Happy to re-review once those are in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants