Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Example: Multi-Agent Email System

Alpha (v0.1). Breaking changes expected. Agent.delegate is wired as of v0.1.4. Agent.broadcast and @team routing are wired as of v0.1.6.

This first runnable workflow keeps synchronous return-value helpers as top-level tasks. For mailbox-specific coordination between live agents, use Agent.delegate, Agent.send, and Agent.broadcast as described in Agent Communication.

type Urgency  = low | medium | high | critical
type Category = question | request | info | complaint | spam

type TriageResult {
  urgency: Urgency
  category: Category
}

task triage_email(email: {body: str}) -> TriageResult {
  urgency  = Ai.classify(email.body, as: Urgency)  ?? Urgency.medium
  category = Ai.classify(email.body, as: Category) ?? Category.question
  {urgency: urgency, category: category}
}

task draft_reply(email: {body: str, from: str}, guidance: str? = none) -> str {
  Ai.draft("response to {email.body}",
    tone: "professional",
    guidance: guidance,
    max_length: 200
  ) ?? "(draft failed)"
}

task plan_followup(email: {subject: str}, urgency: Urgency) {
  when urgency {
    critical => Schedule.after(2.hours, () => { Io.notify("Follow up on: {email.subject}") })
    high     => Schedule.after(24.hours, () => { Io.notify("Check status: {email.subject}") })
    medium   => Schedule.after(3.days, () => { Io.notify("Pending reply: {email.subject}") })
    low      => { }
  }
}

agent InboxManager {
  @role "You coordinate the email handling team"

  task handle(email: {body: str, from: str, subject: str}) {
    result = triage_email(email) ?? {
      urgency: Urgency.medium,
      category: Category.question
    }

    when result.urgency {
      low => {
        when result.category {
          spam, info => Email.archive(email)
          _ => {
            reply = draft_reply(email) ?? "(could not draft)"
            if Io.confirm(reply) { Email.send(reply, to: email.from) }
          }
        }
      }
      medium => {
        reply = draft_reply(email) ?? "(could not draft)"
        if Io.confirm(reply) { Email.send(reply, to: email.from) }
        plan_followup(email, result.urgency)
      }
      high, critical => {
        summary = Ai.summarize(email.body, in: 2, unit: sentences) ?? "(no summary)"
        Io.notify("{result.urgency} {result.category} from {email.from}")
        Io.show(summary)
        guidance = Io.ask("How should I respond?")
        reply = draft_reply(email, guidance) ?? "(could not draft)"
        if Io.confirm(reply) { Email.send(reply, to: email.from) }
        plan_followup(email, result.urgency)
      }
    }
  }

  @on_start {
    Schedule.every(5.minutes, () => {
      for email in Email.fetch(unread: true) {
        self.handle(email)
      }
    })
  }
}

run(InboxManager)

Architecture

InboxManager (orchestrator agent)
  ├── triage_email(...)    — synchronous classifier helper
  ├── draft_reply(...)     — synchronous response helper
  └── plan_followup(...)   — synchronous scheduler helper

Use top-level tasks when the caller needs a return value immediately. Use agents with mailboxes when work should cross a live actor boundary. Agent.delegate(target, task, args) posts a named task event to the target agent’s mailbox. @team [...] tags a running agent with one or more team names for Agent.broadcast(team, data, event:).

agent Classifier {
  @team ["email"]
  on refresh(msg: str) { Io.show("Classifier refresh: {msg}") }
}

agent Coordinator {
  @on_start {
    Agent.run(Classifier)
    Agent.broadcast("email", "new batch", event: "refresh")
  }
}

Status

Multi-agent collaboration is available in v0.1 with in-process mailboxes. Agent.delegate, Agent.send, Agent.broadcast, and @team routing are wired. Current limits: delivery is in-process only, broadcast is non-blocking, and agents without a matching handler silently ignore the event.