Skip to content

Lesson 4: Taking Action

Your machine classifies emails and routes them. But “routed_to: notify_team” is just a label. Nobody actually gets notified. A task saying “create_task” does not create a task anywhere.

This lesson connects your machine to real systems: Microsoft Teams for notifications, Planner for tasks.

The ask from: Pattern

You have seen ask classify, using: "claude-haiku-4" which asks an AI to reason. There is another kind of ask:

ask notify, from: "@mashin/actions/microsoft/teams/send_message"
channel: "ops-alerts"
message: "Urgent email from " + input.sender + ": " + input.subject

ask...from: calls another machine instead of an AI model. @mashin/actions/microsoft/teams/send_message is a built-in machine that sends a Teams message. You give it a channel and a message. It handles the API call, authentication, retries, and error handling.

You do not write HTTP requests. You do not manage tokens. You describe what you want to happen.

The Full Triage Machine

Here is the classifier with real actions:

machine email_triage
accepts
subject as text, is required
sender as text, is required
body as text
responds with
routed_to as text
action_taken as text
implements
ask classify, using: "anthropic:claude-haiku-4"
with task "Classify this email.\n\nFrom: ${input.sender}\nSubject: ${input.subject}\nBody: ${input.body}"
returns
priority as text, is required, choices: ["urgent", "today", "later", "ignore"]
confidence as number, is required, range: [0.0, 1.0]
action as text, is required
reason as text
decide route
if classify.confidence < 0.7
run flow(flag_for_human)
else if classify.priority == "urgent"
run flow(notify_team)
else if classify.action == "create_task"
run flow(create_planner_task)
else
{routed_to: "inbox", action_taken: "none"}
flows
flow notify_team
ask send_alert, from: "@mashin/actions/microsoft/teams/send_message"
channel: "ops-alerts"
message: "Urgent: " + input.subject + " from " + input.sender + "\n" + classify.reason
{routed_to: "notify_team", action_taken: "Teams message sent to #ops-alerts"}
flow create_planner_task
ask create_task, from: "@mashin/actions/microsoft/planner/create_task"
title: input.subject
description: input.body
priority: classify.priority
assigned_to: input.sender
{routed_to: "create_task", action_taken: "Planner task created: " + input.subject}
flow flag_for_human
ask send_review, from: "@mashin/actions/microsoft/teams/send_message"
channel: "email-review"
message: "Needs review (confidence: " + classify.confidence + "): " + input.subject + " from " + input.sender
{routed_to: "human_review", action_taken: "Flagged in #email-review"}

What is New

ask...from: calls a built-in effect machine. Three different ones:

  • @mashin/actions/microsoft/teams/send_message sends a Teams message
  • @mashin/actions/microsoft/planner/create_task creates a Planner task
  • Both handle authentication, retries, and error handling automatically

flows organize related steps. flow notify_team contains the steps that run when an email is urgent. flow create_planner_task handles the task creation path. The decide step uses run flow(name) to jump to the right flow.

You will learn more about flows in the next lesson. For now, think of them as named groups of steps.

Permissions

Notice something: this machine now sends messages and creates tasks. Those are real actions with real consequences. mashin tracks every one:

  • The execution trace shows which effect machines were called, with what arguments
  • The governance record logs every external action
  • If Teams is down, the error is captured with the full context

You did not add this tracking. It is automatic. Every ask from: call goes through the governed execution pipeline.

What is Available

The standard library has effect machines for common systems:

CategoryExamples
MicrosoftTeams messages, Planner tasks, Outlook email
GoogleGmail, Calendar, Drive
HTTPGET, POST, PUT, DELETE to any API
FilesRead, write, list
DatabaseQuery, insert, update

To see what your account has connected:

/credentials

To see all available effect machines:

ask Koda: what integrations can I use?

Run It

/run email_triage

Give it “URGENT: Client unhappy” from a client email. Watch the Teams message appear in #ops-alerts.

Give it “Can you review this document?” from a colleague. Watch the Planner task get created.

Check the trace:

/timeline [run_id]

You will see:

[1] classify ask 420ms $0.0003 claude-haiku-4
[2] route decide 0ms $0.0000
[3] send_alert ask 850ms $0.0000 @mashin/actions/microsoft/teams/send_message

The Teams call took 850ms and cost nothing (it is not an AI call). The whole triage took about 1.3 seconds.

What Comes Next

You have a working email triage that classifies, routes, and acts. Next lesson: composing this into a clean multi-step flow and understanding how steps pass data to each other.

Next: Composition →