Skip to main content

Email Triage

v0.6.0 Verified

GAIA email triage agent — read, triage, organize, and reply to Gmail/Outlook locally

  • email
  • gmail
  • calendar
  • triage

Eval score

84.53 / 100

Aggregate benchmark score for the latest published version — the methodology and every sub-metric are in the scorecard.

Source ↗

Install

npm client + frozen sidecar · 41.5 MB
npm i @amd-gaia/agent-email

Ships as an npm client plus a frozen binary sidecar — npm is its only supported install path (there is no PyPI wheel). A local model must be running first: gaia init then lemonade-server serve.

About Email Triage

@amd-gaia/agent-email

npm version

Sorts your Gmail or Outlook (personal or work Microsoft 365) inbox into urgent / needs-reply / FYI, pulls out action items, and drafts replies — all running locally on your machine, so no email content ever leaves it.

You embed it in a JavaScript or TypeScript app. Every email is analyzed on-device by a local AI model (via AMD's Lemonade runtime); message content is never sent to a cloud service, and that's enforced when the agent starts up.

Using an AI coding assistant? This package ships a SKILL.md — load it into Claude Code (or similar) for a copy-paste integration playbook.

What it can do

  • Triage — sort each message into urgent, needs-reply, FYI, promotional, or personal; summarize a thread; and extract the action items and any phishing or spam signals.
  • Organize — archive, label, and move messages, one at a time or in batches.
  • Reply & send — draft context-aware replies (optionally in your own writing style, learned locally from your Sent mail) and send them — with attachments. Anything that leaves your mailbox asks for confirmation first.
  • Calendar — spot meeting requests, flag conflicts, RSVP, and create events from an email.
  • Track follow-ups — flag replies you're still waiting on past a window you choose (it points them out; it never nudges anyone for you).
  • Spot what's waiting on you — flag inbound mail that asks you directly for a reply, decision, or meeting time, with a sender, subject, and how long it's been sitting there. Requires a real back-and-forth already in that thread — a bare question mark, a convincing cold-outreach email, or having emailed the sender before in some unrelated thread never qualifies on its own.
  • Daily briefing — generate a morning inbox summary on a schedule, no prompt needed.
  • Plain-language requests — describe what you want done ("find today's urgent mail and archive the promotions") and the agent chains the steps itself, streaming progress; runs are cancellable mid-way.

Prerequisites

A local AI model has to be running before triage or drafting works:

  1. Install and start it with gaia init (downloads the default model) and lemonade-server serve.
  2. On a fresh machine the agent still starts, but triage won't return results until that local model is up. Call client.init() to check readiness.

You'll need about 8 GB of RAM for the default model, and one of: Windows x64, Linux x64, or macOS Apple Silicon.

Install

npm install @amd-gaia/agent-email
Behind a corporate proxy? If install fails with UNABLE_TO_GET_ISSUER_CERT, reinstall with NODE_OPTIONS=--use-system-ca npm install (Node ≥ 22).

Quick start

Triage one email — get back a category and a summary:

import { fetchBinary, startSidecar, shutdown } from "@amd-gaia/agent-email";

// Once, at build time: download and verify the agent for your platform.
const { binaryPath } = await fetchBinary({ outDir: "resources" });

// At startup: launch the local agent and hold onto the handle.
const sidecar = await startSidecar({ binaryPath, port: 8131 });

const res = await sidecar.client.triage({
  payload: {
    kind: "single",
    principal: { email: "me@example.com" },
    message: {
      message_id: "m1",
      from: { name: "Sarah Chen", email: "sarah@example.com" },
      subject: "Prod incident follow-up",
      body: "Please review the report and reply by Friday.",
    },
  },
});

console.log(res.result.category, res.result.summary);
// e.g. "NEEDS_RESPONSE  Sarah asks you to review the report and reply by Friday."

await shutdown(sidecar);

Or hand the agent a plain-language request and watch it work — query() streams typed progress events (status, tool_call, tool_result, …) and ends with the answer; cancelQuery() stops a run mid-way:

const runId = crypto.randomUUID(); // yours to mint — it's also the cancel handle
for await (const ev of sidecar.client.query({
  query: "Find today's urgent mail and archive the promotions.",
  run_id: runId,
  context: [],
})) {
  if (ev.type === "status") console.log(ev.message);
  // The agent can ask you something mid-run — answer it and the same stream
  // carries on. This is how it sets up mailbox access without sending you away.
  if (ev.type === "needs_input") {
    await sidecar.client.respondToQuery(runId, ev.request_id, await askUser(ev));
  }
  if (ev.type === "final") console.log(ev.answer); // last event
}

Triage classifies and drafts using only the local model — no mailbox connection needed. Reading or acting on a live inbox (search, send, archive, calendar) uses the Google or Microsoft connector (personal or work Microsoft 365) you set up in GAIA under Settings → Connectors — or, from 2.6, that the agent sets up with you, in the conversation: if it has no usable mailbox it works out which of the four problems it has and offers to fix that one, asking through needs_input rather than returning a command for you to go run (#2469). Connecting Google still requires your own OAuth client ID and secret; the agent says so up front. (Inside the full GAIA Agent UI daemon the connector token is forwarded to the agent by the daemon — sidecar contract 2.5, #2154; a standalone integrator using this package is unaffected and resolves the mailbox from the local GAIA connector store.)

Mail is required; calendar is requested but optional — consent asks for both up front so you're never prompted twice, but declining calendar (or connecting with an older, mail-only grant) still leaves you with a fully working triage/reply/send mailbox. Calendar tools fail loudly, naming the exact scope to add, only when you actually try to use one.

Want to try it without writing code? Run npx @amd-gaia/agent-email playground for a local page to test triage, drafting, and a live send.

Personal mailbox vs work mailbox

The package ships six built-in skills — short playbooks the agent can load into its own thinking — grouped into a personal set (inbox triage, newsletter digests, trip itineraries) and a work set (inbox triage, meeting scheduling, action items, escalation).

They are switched off in this release. Nothing is loaded at launch and a personal and a work mailbox get identical behaviour, because there is no eval evidence yet that the skills improve triage. The skill files stay in the package, inert, and the agent's full context window goes to your mail instead of to skill text.

Nothing for you to do or change: there is no set to pin, and passing --skill-set / GAIA_EMAIL_SKILL_SET fails at startup saying so rather than quietly doing nothing. Re-enabling is a change inside the agent, not in your integration. Full detail in SPEC.md.

How it works

Three pieces, all on your own machine — no cloud, no separate GAIA install:

  • Your app launches the agent and owns its lifetime.
  • The agent is a single self-contained program (~30–45 MB, no Python) that serves a small local API.
  • The local model does the actual thinking; the agent talks to it over your machine's local network only.

Full architecture, the complete API, authentication, and every endpoint are in SPEC.md.

How good is the triage?

Scores 84.53 / 100 on a labeled benchmark inbox — see the Scorecard tab (or SCORECARD.md) for the full breakdown, and the Evaluation tab for how it's measured.

Reference

License

Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.

SPDX-License-Identifier: MIT