DEV Community

Cover image for I thought AI agent task completion in email meant better drafts, but this excavation company’s 5% inbox proved me wrong
Lars Winstand
Lars Winstand

Posted on • Originally published at standardcompute.com

I thought AI agent task completion in email meant better drafts, but this excavation company’s 5% inbox proved me wrong

I went into a Reddit thread expecting the usual email automation story:

  • Gmail gets a new message
  • GPT-5 writes a decent reply
  • everyone calls it “AI automation”
  • the human still owns the real work

Instead, I found something much better.

In a thread on r/openclaw, an operator running an excavation company described an inbox setup where only about 5% of emails still needed unique personal action. Everything else got routed into operational states like REVIEW, ACTION, and WAITING.

That’s not “AI writes emails.”

That’s workflow delegation.

And I think most devs building AI email systems are aiming at the wrong target.

The real bottleneck in email isn’t writing

A polished draft is nice.

But most business inboxes do not fail because people can’t type fast enough.

They fail because every incoming message creates a decision:

  • should this be answered automatically?
  • should it become a task?
  • should it be escalated?
  • should it update a CRM?
  • should it go to dispatch?
  • should it wait on a follow-up?
  • should a human review it before anything happens?

If your automation stops at “saved draft,” the hard part is still manual.

That’s why the excavation-company setup stood out. The operator described a system with:

  • two Google Workspace inboxes
  • an OpenClaw agent with company and personal context
  • rules originally written for a VA
  • filtering for spam and routine messages
  • an ACTION folder for things the agent couldn’t fully resolve
  • a WAITING folder for sent messages that needed follow-up
  • a REVIEW path for the small set of emails needing unique human judgment

That architecture is more useful than most AI email demos I’ve seen.

Treat Gmail like a state machine, not a mailbox

If you’re building this kind of flow, Gmail’s API is actually better than most people realize.

A lot of teams still treat Gmail as a place to read text and maybe save drafts.

That leaves a lot of leverage on the table.

You can model inbox processing as state transitions.

For example:

  • INBOX -> REVIEW
  • INBOX -> ACTION
  • INBOX -> WAITING
  • INBOX -> SPAM
  • INBOX -> DISPATCH
  • INBOX -> BILLING

That gives you an operational queue instead of “unread but scary.”

Subscribe to inbox changes

Gmail supports push notifications with users.watch.

Example:

POST https://gmail.googleapis.com/gmail/v1/users/me/watch
{
  "topicName": "projects/myproject/topics/mytopic",
  "labelIds": ["INBOX"],
  "labelFilterBehavior": "INCLUDE"
}
Enter fullscreen mode Exit fullscreen mode

You get back a historyId and an expiration timestamp.

That expiration matters. Watches are renewable, which means your integration should behave like a service, not a one-time setup script.

Update labels as workflow state

Once you classify the message, update labels:

POST https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/{id}/modify
{
  "addLabelIds": ["Label_Action", "Label_Waiting"],
  "removeLabelIds": ["INBOX"]
}
Enter fullscreen mode Exit fullscreen mode

That is the core primitive.

Not draft generation.

State transition.

Google lets you add and remove a lot of labels in one call, which is enough for real-world triage systems.

Stop polling every hour if the inbox matters

The Reddit setup used hourly cron jobs, which is fair. Cron is simple and reliable.

But if you’re building always-on agents, polling is usually the wrong default.

Push-based intake is cleaner:

  1. Gmail users.watch publishes inbox changes to Cloud Pub/Sub
  2. Your webhook or subscriber receives the event
  3. You fetch the changed message or thread
  4. You classify intent, urgency, ownership, and next action
  5. You apply labels
  6. You trigger downstream systems
  7. You notify a human only when confidence is low or authority is required

That is what I’d call actual AI agent task completion.

Not “write a polite reply in Gmail.”

A practical architecture

Here’s the version I’d build today.

Components

  • Gmail API for intake and label updates
  • Cloud Pub/Sub for push events
  • OpenClaw, n8n, Make, or Zapier for orchestration
  • Slack / Asana / HubSpot / Salesforce / internal tools for downstream actions
  • an LLM for classification, summarization, and response generation

Flow

Gmail inbox change
  -> Pub/Sub event
  -> fetch message/thread
  -> classify: intent, urgency, owner, next step
  -> apply Gmail labels
  -> trigger downstream system
  -> optionally draft reply
  -> notify human if needed
Enter fullscreen mode Exit fullscreen mode

Example states

State Meaning
REVIEW Needs human judgment or approval
ACTION Needs action but no rule exists yet
WAITING Follow-up sent, waiting on response
SPAM Ignore or archive
BILLING Route to accounting workflow
DISPATCH Route to operations or field team
ESCALATE Time-sensitive or high-risk issue

That state model is where the leverage lives.

OpenClaw is interesting because it sits above the inbox

The thread that kicked this off was about OpenClaw, and I think the useful takeaway is this:

OpenClaw is not just an email drafting tool.

It’s an orchestration layer.

That matters because email automation gets much better when the agent has:

  • memory
  • business context
  • access to tools
  • rules for escalation
  • the ability to trigger downstream actions

One line from the thread stuck with me: the operator had a separate agent with full company and personal context reading the email accounts.

That’s exactly the difference between a toy demo and something operational.

If you drop GPT-5, Claude Opus 4.6, Grok, or any other model into an inbox with weak instructions and no business memory, it will absolutely make confident mistakes.

The model is not the system.

The system is:

  • context
  • state design
  • escalation rules
  • observability
  • downstream integrations

OpenClaw just happens to be one way to build that system.

If you’re getting started, the setup is refreshingly direct:

openclaw onboard
Enter fullscreen mode Exit fullscreen mode

That alone doesn’t solve email. But it points at the right abstraction: agent orchestration, not just draft generation.

Drafts are still useful. They’re just not the main event.

I’m not anti-draft.

There are plenty of workflows where wording is the bottleneck:

  • legal review
  • PR responses
  • enterprise sales follow-ups
  • sensitive support cases

In those cases, a strong draft from GPT-5 or Claude is already worth money.

But if you stop there, you’ve automated typing, not operations.

The better maturity model looks like this.

Stage 1: Draft assistance

Use ChatGPT, Claude, or Gemini to reduce writing time.

Stage 2: Classification

Add intent detection, urgency scoring, and labels.

Stage 3: Delegation

Turn messages into assignments, approvals, waiting states, and escalations.

Stage 4: Cross-system action

Update Slack, Asana, HubSpot, Salesforce, dispatch software, or internal databases automatically.

Most teams celebrate at stage 1.

The excavation-company setup was already operating closer to stage 3.

That’s why it’s interesting.

What breaks first in production: context

Every time.

The reason this setup worked is that the operator already had rules written for a VA.

That means someone had already done the hard work of defining:

  • what counts as routine
  • what needs escalation
  • what can wait
  • what requires owner judgment
  • what should be answered automatically

If you skip that design step, your system won’t just generate bad text.

It will misroute work.

That is much worse.

A bad draft gets edited.

A bad routing decision quietly loses money.

Examples:

  • a vendor request gets buried in WAITING
  • a customer issue never gets escalated
  • a quote request sits in REVIEW too long
  • a dispatch issue gets labeled like a normal conversation

That’s why I’d insist on these three things before shipping anything like this.

1) Design real states

Don’t use vague labels like:

  • misc
  • important
  • follow-up

Use labels that map to actual business actions:

  • REVIEW
  • ACTION
  • WAITING
  • BILLING
  • DISPATCH
  • ESCALATE

If a label doesn’t imply what happens next, it’s not a useful state.

2) Build explicit escalation rules

Low-confidence decisions need a human path immediately.

For example:

if confidence < 0.82:
  route: REVIEW
  notify: owner

if intent == "billing_dispute":
  route: ESCALATE
  notify: finance_lead

if intent == "field_schedule_change":
  route: DISPATCH
  notify: ops_channel
Enter fullscreen mode Exit fullscreen mode

You want deterministic handling for risky cases.

3) Log everything

Observability is not optional.

You need to know:

  • why a message was classified a certain way
  • what labels were applied
  • what downstream systems were touched
  • whether a human overrode the decision
  • which prompts, rules, or tools were involved

If your agent moves business-critical email, silent failure is unacceptable.

Minimal implementation sketch

Here’s a rough Node-style flow for a webhook consumer:

async function handleGmailEvent(event) {
  const message = await fetchChangedMessage(event.historyId)

  const classification = await classifyMessage({
    subject: message.subject,
    body: message.body,
    thread: message.thread,
    customerContext: await getCustomerContext(message),
    businessRules: await getBusinessRules()
  })

  if (classification.confidence < 0.82) {
    await applyLabels(message.id, ["REVIEW"], ["INBOX"])
    await notifySlack("owner-review", {
      messageId: message.id,
      reason: classification.reason,
      summary: classification.summary
    })
    return
  }

  switch (classification.route) {
    case "WAITING":
      await applyLabels(message.id, ["WAITING"], ["INBOX"])
      break
    case "ACTION":
      await applyLabels(message.id, ["ACTION"], ["INBOX"])
      await createTaskInAsana(classification.task)
      break
    case "DISPATCH":
      await applyLabels(message.id, ["DISPATCH"], ["INBOX"])
      await sendToDispatchSystem(classification.dispatchPayload)
      break
    default:
      await applyLabels(message.id, ["REVIEW"], ["INBOX"])
  }

  if (classification.replyDraft) {
    await saveDraftReply(message.threadId, classification.replyDraft)
  }
}
Enter fullscreen mode Exit fullscreen mode

That’s the pattern I wish more “AI email” products would show.

Not just:

const draft = await llm.generateReply(email)
Enter fullscreen mode Exit fullscreen mode

Where Standard Compute fits if you’re running this at scale

This kind of workflow gets expensive fast when you do it the naive way.

Not because one draft is expensive.

Because production email agents do more than drafting:

  • classify every inbound message
  • summarize threads
  • extract entities
  • check confidence
  • generate next steps
  • draft replies when needed
  • call multiple prompts across routing branches
  • run constantly

That’s exactly where per-token pricing becomes annoying.

Especially if you’re running agents 24/7 in n8n, Make, Zapier, OpenClaw, or your own workers.

You start optimizing around cost instead of around reliability.

That’s why I think flat-rate inference is a better fit for automation workloads than traditional token billing.

Standard Compute is built for this specific problem:

  • OpenAI API-compatible
  • works with existing SDKs and HTTP clients
  • flat monthly pricing instead of per-token billing
  • useful for always-on agents and automations
  • dynamic routing across models like GPT-5.4, Claude Opus 4.6, and Grok 4.20

If your email pipeline is doing real orchestration instead of one-off prompting, predictable cost matters a lot more than people admit.

The big takeaway

The most interesting part of that excavation-company story was not “AI writes good emails.”

We already know that.

The interesting part was that only about 5% of messages still needed unique human action.

That means the system was doing the thing most email automation misses:

  • classify
  • route
  • delegate
  • wait
  • escalate
  • notify

Drafting was just one output of the workflow.

Not the workflow itself.

If you’re building AI email systems, I think this is the better question:

“When a message arrives, what state should it enter, who owns it, what system should change, and what happens if nobody responds?”

That’s less flashy than “generate a reply.”

It’s also the question that gets you a real operational win.

Top comments (0)