Triggers
When agents run. A config declares one trigger, a cron schedule, a react event, or an @ellipsis mention. Any agent also starts from the API and CLI.
A trigger decides when an agent runs. A config declares at most one: a cron schedule, a react event, or an @ellipsis mention. A config with no trigger is a manual agent, started only from the API and CLI.
A react trigger names one surface as a typed block under trigger and carries only that surface's filters. Six surfaces exist:
| Surface | Fires on |
|---|---|
pull_request | A pull request event: opened, pushed, merged, closed, review_submitted, commented. |
push | Commits pushed to a branch. |
issue | A GitHub issue opened, closed, or commented. |
linear_issue | A Linear issue opened. |
sentry | A Sentry issue_alert or metric_alert. |
slack_channel | A channel created in the connected Slack workspace. |
A react trigger sets exactly one surface block, and every enabled config whose block matches an event runs independently. pull_request, push, and issue are covered under Pull request; slack_channel is the whole of itself: no actions, no filters, an empty block.
trigger:
type: react
slack_channel: {}It fires when a channel is created in the connected Slack workspace, and each fire starts a fresh session that clones the config's repositories.
Cron
A cron trigger runs the agent on a schedule. The schedule registers when the config syncs from your default branch; each fire starts a fresh session with the config's system prompt as its whole instruction. There is no typed prompt, and a disabled agent's schedule does not fire.
ellipsis:
version: v1
name: Recent work summary
description: Summarizes the week's merged work every Monday morning
claude:
system: |
Summarize what merged across splitshift-web and splitshift-api in
the last week. Group the work into themes and name the author of
each change. Return the summary as Slack-ready markdown.
trigger:
type: cron
schedule: "0 9 * * 1"
sandbox:
repositories:
- name: splitshift-web
- name: splitshift-api
github:
permissions: read_only
budget:
session: 1.00Every Monday at 09:00 UTC this produces a session whose result is the week's summary, grouped by theme. The full worked version, including posting to Slack: Automate your daily standup.
schedule takes a standard five-field cron expression: minute hour day-of-month month day-of-week. All schedules run in UTC. You cannot restrict both day-of-month and day-of-week in one expression; leave one as *. AWS EventBridge Scheduler expressions pass through verbatim: cron(...), rate(...), or at(...), so schedule: "rate(6 hours)" is valid. An invalid expression fails config validation before anything is stored.
Mentions
Mention @ellipsis where work lives and Ellipsis answers there. This needs no config: a built-in responder answers every mention. A mention trigger replaces the built-in responder with your own agent, so you choose its repositories, model, and budget:
trigger:
type: mention
platforms: [github, slack, linear]platforms scopes where the agent answers; an empty list means every platform. If several enabled configs claim the same platform, the oldest answers.
| Platform | Where it answers |
|---|---|
github | Pull request and issue comments. |
slack | App mentions, direct messages, and thread replies. |
linear | Issue comments that lead with @ellipsis. |
A mention agent needs no system prompt: its response is built from the thread it was mentioned in. Every mention starts or continues a durable conversation on its surface, so follow-ups keep full context. The complete surface behavior, including the ... shorthand and GitHub autocomplete: Answer codebase questions from GitHub, Slack, and Linear.
Pull request
The pull_request surface reacts to events on pull requests. on lists which; the other fields narrow which pull requests qualify.
trigger:
type: react
pull_request:
on: [pushed]
repositories: [splitshift-api]
base: [default]
paths: ["migrations/**"]on takes any of opened, pushed, merged, closed, review_submitted, and commented. pushed fires on every head advance including the open, so on: [pushed] covers a pull request's whole life. Every filter defaults to "match everything":
| Field | Matches | Default |
|---|---|---|
repositories | Repositories to watch, by name, or {include: [...], exclude: [...]}. Independent of sandbox.repositories; the triggering repository is cloned into the sandbox regardless. | All repositories. |
base | The target branch: an exact name, a prefix ending in * (release/*), or default for the repository's default branch. | All branches. |
head | The source branch, same pattern forms. | All branches. |
draft | true for drafts only, false to exclude drafts. | Either. |
labels | Pull requests carrying any listed label. | All. |
paths | Changed-file globs over the pull request's files, any match qualifies. Include-only; ! patterns fail validation. | All. |
for | The author: users and bots each take true, false, or a list of logins, with an optional exclude. | users: true, bots: false, so bot-authored pull requests never trigger unless opted in. |
Each matching event starts a fresh session with the event as its input; react sessions are single-shot, not conversations. A worked example that rewrites the description on every push: Keep pull request descriptions up to date.
Two sibling GitHub surfaces share the same filter semantics. push is action-less (no on list) and fires on every push that matches; branch filters the pushed branch with the same pattern forms as base, paths covers the pushed range's changed files, and for gates the pusher. Each push starts a fresh session, not a conversation.
trigger:
type: react
push:
repositories: [splitshift-infra]
branch: [default]
paths: ["deploy/**"]issue reacts to GitHub issues with on actions opened, closed, and commented, filtered by repositories, labels, and for. Each event the agent reacts to starts a fresh session.
trigger:
type: react
issue:
on: [opened]
labels: [bug]Sentry
The sentry surface starts a diagnosis when an alert fires. Connect the Sentry integration first (Integrations in the dashboard).
trigger:
type: react
sentry:
on: [issue_alert, metric_alert]
projects: [splitshift-api]on takes issue_alert, metric_alert, or both. A metric alert starts a session when it goes critical; warning and resolved transitions do not. projects filters by Sentry project slug; an empty list (the default) reacts to alerts from every project in the connected Sentry organizations, which is rarely what you want.
Alert storms do not multiply into duplicate agents: a recurring Sentry issue reaches agents at most once every 6 hours, so a re-firing alert starts one investigation, not one per fire. The full worked agent, with the diagnosis it posts: Turn Sentry alerts into root-cause diagnoses.
Linear
The linear_issue surface starts an agent when a Linear issue is created. Connect the Linear integration first (Integrations in the dashboard).
trigger:
type: react
linear_issue:
on: [opened]opened is the only action. Each new issue starts a fresh session per matching agent, and for scopes which issue creators trigger it. The canonical use is an implementer: an agent that reads the issue, makes the change, and opens a pull request linked back to it. Follow-ups flow through mentions, not this trigger: a comment on the issue that leads with @ellipsis reaches the mention agent.
API and CLI
Any agent can be started directly, whatever its trigger, and a config with no trigger runs only this way. From the terminal:
agent session start --config agent_x9Kd3Fq2 --watchThe same over HTTP:
curl https://api.ellipsis.dev/v1/sessions \
-H "Authorization: Bearer $ELLIPSIS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"config_id": "agent_x9Kd3Fq2"}'Both accept a prompt appended after the config's system prompt, and a config_override_yaml that merges a partial config onto the saved one for this session alone. Sessions started this way record source: api or source: cli, so they stay distinguishable from cron and event sessions in history.
The full start, watch, stop, and replay surface: API sessions and CLI sessions. Putting an agent in a CI pipeline: Trigger agents from your own scripts and CI.
Configuration YAML
Every field in an Ellipsis agent YAML file, with types, defaults, and constraints. Includes the smallest deployable config and where invalid configs fail.
Lifecycle
Merge to the default branch to deploy an agent; pull requests preview config changes. Disable with enabled false, delete by removing the file, revive by re-adding it.