Skip to main content
The Microsoft Teams Webhook connector ships the delivery layer — once a bot decides to send a card, it knows how to deliver it. The complementary question is what makes the bot decide in the first place, without a human typing the request every time. That trigger layer is built on top of Genesis’s scheduler. The only fully-supported automatic-trigger path today is the Genesis scheduler (scheduler_tools.scheduler_action). The scheduler runs a fixed agent prompt on a cron / interval / one-shot schedule. The agent prompt contains both the detection logic (“query X, check for Y”) and the action (“if found, call teams_webhook_tools with SEND_ALERT”). Each fire is a normal LLM-driven thread turn — the agent picks up tools available to the running bot and posts the card via the same dispatch path documented in the setup guide.

Concrete example

Ask the bot to schedule the job in a conversation:
The scheduler persists the job, fires every 5 minutes, and records each run in scheduler_runs. Run history is queryable via scheduler_tools.scheduler_action(GET_HISTORY) or the /api/scheduler/prompt-jobs/history HTTP endpoint.

End-to-end proof

Validated against a real *.api.powerplatform.com webhook on a local Genesis stack: The interval trigger fired exactly on schedule; the agent’s output included {"job_result": "success"} which the scheduler parses to record the outcome.

Trigger design considerations

The actual task the agent performs every fire, not a description of the schedule itself.
  • ✅ “Query failed dbt runs in last 10 minutes; if any, send SEND_ALERT”
  • ❌ “Check for failures every 5 minutes” — this describes the schedule, not the work; the agent would just try to create another scheduler entry
Every fire is an LLM call. A 5-minute interval is ~288 fires/day; with a typical alert agent loop that’s a real cost line. Tune to detection-latency requirements:
  • 5-15 minutes is reasonable for most pipeline-failure use cases
  • 1-minute intervals are rarely warranted and have material cost impact
  • Daily/hourly scheduled reports cost effectively nothing
The scheduled prompt fires independently every interval. If the underlying failure is unchanged across intervals, the agent will keep alerting unless instructed otherwise. Common patterns:
  • Thread-history dedup: include “only alert on runs newer than the last alert in this thread” in the prompt — the bot uses thread history for state
  • Scratch-table dedup: write an alerted_at timestamp into a Snowflake / SQLite scratch table the agent reads at start
  • Accept duplicates as a feature: every fire is a “still broken” reminder, useful for incidents that should not be silently ignored
The bot must have teams_webhook_tools in its active context. Two options:
  • Bake it into the bot’s persona instructions (recommended) — no per-fire latency cost
  • Rely on first-call discovery — the agent will search the registry on each fire and add the tool group; works but adds ~7 seconds of cold-start latency (as the proof-of-concept table above shows)
If the LLM call inside the scheduled job fails (timeout, model error), the run is recorded with status: failed in scheduler_runs. There is no retry of the prompt itself. For operationally-critical alerting, monitor scheduler_runs for runs in failed state and surface those to an operator dashboard.

Worked starter: pipeline failure alerter

Pseudo-prompt for a dbt-failure alerter on a customer running dbt against Snowflake:
The starter is intentionally not a canned code asset — the customer’s dbt artifacts table name, environment, and dashboard URLs vary per deployment.

What does not work today

Customers sometimes expect these paths; they do not exist in Genesis right now.
Each row below has a known workaround — usually: “external system writes to a Snowflake table, the scheduled Genesis job polls that table.”
The practical implication: poll-based detection via the scheduler is the only first-class option today. External systems should land their state in a Snowflake table (or any data store Genesis can read), and let the scheduled Genesis job poll it. Inbound push from external systems would require future work on a generic webhook receiver — a deliberate scoping choice, not an oversight.