Background Agents
Background agents are automations the agent sets up for you. Each one is a standing job — a prompt plus an optional schedule or event trigger — that runs on its own, without tying up your chat, and reports progress as it works. They're how Avi does anything recurring, long-running, deferred, or reactive.
Creating one
You don't build background agents by hand — you ask for them in chat:
- "Every morning at 7am, email me a summary of new GitHub issues."
- "Check if our homepage is up every 15 minutes; page me if not."
- "Research these five competitors in the background and write up what you find."
- "Whenever a PR comes in on my repo, triage it — if it needs my review, make a task for it."
- "Whenever my grandmother emails me, draft a warm reply."
- "Ask everyone on the team for their shirt size today, then nudge whoever hasn't replied each morning until they all have."
The agent decides whether to answer you right away or hand the work to a background agent, sets the schedule, and confirms. There's deliberately no form to fill in: describe what you want and when, and adjust it the same way ("make that weekly instead", "stop the issue digest").
Tool access
Every newly spawned background agent must declare config.tools, an array of runtime tool names. At run time, the agent receives only the intersection of that allowlist and the project's normally assembled toolset; system_agents-spawn, system_agents-schedule, and system_agents-stop are always removed even if named. An empty array creates a no-tools agent.
For compatibility, legacy agents with no config.tools key remain unrestricted. A present but malformed value fails closed to zero tools. Rescheduling can replace the allowlist with another array, while tools: null deletes the key and returns the agent to unrestricted access.
The Background Agents panel
Open the Background Agents tile in a project's right sidebar to see every agent in the project:
- Each agent shows its status, its schedule in plain language, and its latest activity.
- Open an agent to watch its current run live — a timeline of short progress lines ("beats") the agent emits as it works — plus the outcome and history of its recent runs, including errors.
- Controls live under each agent's ⋮ menu: Run once now (or Stop this run while one is executing), Stop agent (ends it for good; re-arm anytime in chat), and Delete. To change what an agent does or when, ask in chat.
Results also reach you the normal ways: anything an agent produces (notes, emails, messages) lands where it was sent, and its activity is folded into the project's Updates feed.
Statuses
Every agent shows exactly one of five statuses:
- Active — live: waiting on its schedule or feed trigger, or idle between runs.
- Running — a run is executing right now (you can watch it live).
- Succeeded — done for good. One-off agents succeed when their run does; a recurring agent succeeds when it decides its mission is complete ("watch for X, then report") or when you tell the assistant to mark it done.
- Failed — done, and something went wrong. Failed agents always show why: the run's error, five failed runs in a row, or a timeout (see lifetime below).
- Stopped — done because you chose to end it (the panel's Stop agent, or ask in chat). Not a failure — and reversible: ask the assistant to re-arm it and it picks back up with a fresh clock. (Hitting Run now on a stopped agent runs it once without reviving its schedule.)
When an agent reaches a verdict — Succeeded or Failed — that always lands in the project's Updates feed too, with the reason when something went wrong. You never have to open the panel to learn that a standing job finished or broke. (Stopping an agent yourself doesn't post one — that's your choice, not news.)
Lifetime
Background agents don't run unattended forever: each one lives at most 7 days from when it was created or last touched. Editing its schedule (ask in chat) or hitting Run now while it's active restarts the clock; if nobody touches it for 7 days, it ends as Failed with a timeout reason. This keeps forgotten agents from quietly consuming runs and credits. An expired agent isn't gone — ask the assistant to re-arm it, the same way you'd resume a stopped one.
Scheduling
Background agents support three kinds of schedule:
- Recurring at a time of day — "every morning at 9am", "Mondays at 8". Runs on a cron schedule in your local timezone, so it stays correct across daylight-saving changes.
- Recurring by interval — "every 2 hours". Minimum interval is one hour.
- One-time — "tonight at 11pm", "in three hours". Runs once, then the agent is done.
An agent with no schedule runs only when spawned or when you hit Run now.
Starting now and staying scheduled
A schedule doesn't have to mean waiting: a two-phase job — "message everyone today, then nudge stragglers each morning" — kicks off its first run immediately and stays on the recurring schedule (often with an event subscription too, so it reacts the moment each reply lands). Just describe the whole job; the agent arms all of it. And if an agent is sitting on its first tick when it should have started already, say so ("kick it off now") — it runs immediately without disturbing the schedule.
Feed subscriptions
Besides (or instead of) a schedule, an agent can subscribe to the project's Updates feed, so it runs the moment something newsworthy lands there — whatever the source (GitHub, email, Slack, AWS, an app):
- "Triage every PR on my repo" — runs whenever a pull-request update appears or gains activity in the feed, with that update's headline and latest activity as its input.
- "Whenever I hear from John Smith, draft a reply" — runs on any update linked to that contact, whether the message arrived by email, Slack, or anything else.
- "When anything new lands in the feed, summarize it to Slack" — runs on every new update.
Because the trigger is the curated feed — not raw source events — the agent reacts to the same deduped, living stories you see in the Updates sidebar. Subscriptions can be narrowed by source ("only GitHub activity"), by a specific thing ("only PRs from acme/api"), by person (a linked contact, across all their channels), or by headline keywords, and combined with a schedule (a daily digest that also reacts to PRs). Housekeeping changes that don't add news never wake an agent. If updates land while a run is in flight, they queue and run in order. A per-agent hourly run cap keeps a noisy feed from running away.
One thing to know: the feed is curated. An editor decides what's newsworthy enough to appear there, so something low-key — a brief personal note, a routine notification — may never become a feed update at all, and a feed-subscribed agent won't run for it. When the agent must catch a specific occurrence every time, it uses an event subscription instead.
Event subscriptions
An agent can also subscribe directly to the project's event log — the raw record of everything Avi ingests (every email, chat message, PR, ticket, task change, app event), before any curation:
- "Whenever my grandmother emails me, draft a reply" — runs on every inbound email from her contact, even a one-word hello.
- "When the wire confirmation arrives, notify the team" — runs on the matching event the moment it's ingested.
- "On every new support ticket, do a first-pass triage" — runs per ticket event, no editorial gate in between.
Event subscriptions match on the event's envelope — its type (like "inbound email" or "new task", with wildcards) and/or the people it's linked to — so they're exact and predictable: if the matching event lands, the agent runs; if it doesn't, nothing runs and nothing is spent. Use them whenever missing an occurrence isn't acceptable; use feed subscriptions when you want to react to the bigger, curated story. The same queueing and hourly run cap apply, and an agent's own activity can never re-trigger itself through the platform's internal events.
Relationship to Tasks
Tasks are to-do items — they track work, they don't run it. Background agents are the engine: when you ask for anything automated, the agent spawns one. (If you had scheduled tasks from before this split, they were converted to background agents automatically — the task remains as a to-do, and its schedule lives on in the Background Agents panel.)
Good uses
- Daily briefings ("every morning at 7am, email me a summary of new GitHub issues").
- Monitoring ("every 15 minutes, check if our homepage is up; page me if not").
- Reacting to activity ("triage every PR from my repo and make a task if it needs my review").
- Weekly reports.
- Ad-hoc "work on this in the background and come back with results" jobs.
- Anything you'd otherwise have to remember to ask for again.