Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
523 changes: 523 additions & 0 deletions apps/docs/components/workflow-preview/academy-video-workflows.ts

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion apps/docs/content/docs/en/academy/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
"use-cases/slack-it-triage",
"use-cases/document-extraction",
"use-cases/monitoring-research",
"use-cases/sales-data-enrichment"
"use-cases/sales-data-enrichment",
"use-cases/telegram-personal-assistant",
"use-cases/scheduled-report-rollup",
"use-cases/whatsapp-storefront-bot"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: A pipeline that takes incoming documents, extracts the fields you c
import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import { AV_DOC_EXTRACTION_WORKFLOW } from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Document Intake & Extraction" className="mt-2" />

Expand Down Expand Up @@ -40,4 +42,16 @@ Turn a pile of unstructured documents, invoices, contracts, forms, into structur

A **file** comes in, an **Agent** block extracts the fields into a [structured output](/academy/agents/intro) so the shape is predictable, and a **Table** block writes the row. Run it across a batch and a folder of documents becomes a queryable table.

Here is the machine the video builds:

<WorkflowPreview workflow={AV_DOC_EXTRACTION_WORKFLOW} />

This composes [files](/academy/files/intro), [agents](/academy/agents/intro), and [tables](/academy/tables/intro).

## How it works

The **Gmail Email Trigger** polls the inbox and fires on each new email, with Include Attachments enabled so the invoice PDF arrives as part of the trigger's output. No one forwards anything; the inbox itself is the intake queue.

The **Extract** agent reads the attachment and its Response Format is what makes the whole machine reliable: it must return `vendor`, `amount`, and `due_date` as named fields, not a paragraph that mentions them. Structured output turns each field into a root-level reference, so the next block can write `<extract.vendor>` and `<extract.amount>` directly instead of parsing prose. That is the difference between a demo and a pipeline.

**Save Row** inserts those fields into the Invoices [table](/academy/tables/intro). Because the agent's output shape is fixed, the mapping from fields to columns never drifts, and every email that arrives becomes one more queryable row.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: A scheduled agent that watches sources you care about, researches w
import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import { AV_MORNING_WATCH_WORKFLOW } from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Monitoring & Automated Research" className="mt-2" />

Expand Down Expand Up @@ -40,4 +42,18 @@ Build a system that runs on a schedule, checks the sources you care about, resea

A **Schedule trigger** kicks the workflow off. An **Agent** block with search tools gathers and reads sources, synthesizes what changed, and a final step delivers it: a Slack message, or a saved report [file](/academy/files/intro).

Here is the machine the video builds:

<WorkflowPreview workflow={AV_MORNING_WATCH_WORKFLOW} />

This composes [workflows](/academy/workflows/intro), [agents](/academy/agents/intro), and [files](/academy/files/intro).

## How it works

The **Schedule** trigger fires every morning at 7:00, no message and no click. Scheduled workflows are the pattern for anything that should happen whether or not you remember it; the [triggers video](/academy/workflows/intro) covers how a trigger replaces the manual Start.

The **Research** agent carries the tools: Exa for search and Firecrawl for reading pages. The agent decides what to search for and which results to open, calling the tools as many times as the question needs. That loop, model decides, tool runs, model reads the result, is [tool calling](/academy/agents/intro), and it is what makes this a researcher instead of a summarizer of whatever one query returned.

The **Digest** agent is a separate block on purpose. Research and writing are different jobs: the first agent gathers with wide instructions, the second condenses with strict ones. Splitting them keeps each prompt short and each output predictable.

**Post** delivers the digest to #market-watch. Swap this one block to change where the report lands: an email, a saved [file](/academy/files/intro), a [table](/academy/tables/intro) row per day.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: A table-backed system that takes thin lead records, enriches them i
import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import { AV_LEAD_ENRICHMENT_WORKFLOW } from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Sales Data Management & Enrichment" className="mt-2" />

Expand Down Expand Up @@ -40,4 +42,16 @@ Run your sales pipeline as data. Start with thin lead records in a table, enrich

Leads live in a **table**. A **workflow column** runs per row: it enriches the record, an **Agent** block scores the fit, and the results are written straight back into the table. The table becomes both the queue and the record.

Here is the workflow behind the column:

<WorkflowPreview workflow={AV_LEAD_ENRICHMENT_WORKFLOW} />

This is [tables](/academy/tables/intro) and [agents](/academy/agents/intro) composed into a pipeline that operates at scale.

## How it works

Notice what the workflow is not: there is no loop, no batch logic, no list handling. It is a plain chain built for exactly one lead, because the multiplicity lives in the [table](/academy/tables/intro), not the workflow. The table's workflow column runs this chain once per row, and fifty leads means fifty parallel runs of the same three blocks.

The **Start** block declares the input: a company and a contact. When the table invokes the workflow, each row's cells fill these fields, so `<start.company>` inside the workflow always means this row's company.

The **Research** agent carries Exa and Firecrawl as [tools](/academy/agents/intro) and gathers what is public about the company: what it does, how big it is, what it runs on. The **Score** agent then reads the research and grades the fit. Its output flows back into the row's result columns, which is what turns the table from a list of names into a ranked queue your team can sort.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Scheduled Report Rollup
description: A weekly workflow that pulls Stripe and Sheets data, reconciles the numbers, records the result, and posts the digest to Slack before the meeting.
---

import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import { AV_REPORT_ROLLUP_WORKFLOW } from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Scheduled Report Rollup" className="mt-2" />

<div className="mt-8 grid grid-cols-1 items-start gap-10 lg:grid-cols-[1fr_300px]">
<div>

Let the Monday number assemble itself. A schedule fires each week, pulls the charges from Stripe and the tracking tab from Sheets, reconciles the two, computes the delta against last week, and posts the digest to Slack before anyone sits down for the meeting.

<WhatYouWillLearn
items={[
{ title: 'Run on a schedule', body: 'Trigger the rollup every Monday morning so the report is never late.' },
{ title: 'Reconcile two sources', body: 'Use a Function block to join Stripe and Sheets data and compute the delta.' },
{ title: 'Record and deliver', body: 'Write the result as a table row and post the digest to Slack.' },
]}
/>

</div>

<VideoChapters
chapters={[
{ title: 'The problem', time: '0:00' },
{ title: 'Schedule trigger', time: '0:35' },
{ title: 'Pull both sources', time: '1:10' },
{ title: 'Reconcile and compute', time: '2:00' },
{ title: 'Record and post', time: '2:50' },
]}
/>

</div>

## What you'll build

A **Schedule trigger** fires every Monday at 7:00. The workflow pulls charges from the **Stripe API** and reads the tracking tab with **Google Sheets**. A **Function** block reconciles the two sources and computes this week's number and the delta. A **Table** block inserts the row, so every week's result is queryable later, and a **Slack message** posts the digest to the channel. Every run is recorded in the [logs](/logs-debugging).

Here is the machine the video builds:

<WorkflowPreview workflow={AV_REPORT_ROLLUP_WORKFLOW} height={340} />

This composes [workflows](/academy/workflows/intro) and [tables](/academy/tables/intro): the foundations, composed.

## How it works

The **Schedule** trigger fires weekly, Monday at 7:00, and fans out to both sources at once: two edges leave the trigger, so **Stripe** lists the week's charges while **Sheets** reads the tracking tab in parallel. Neither source waits on the other.

The **Reconcile** function is where the two lanes meet. A [Function block](/academy/workflows/intro) runs plain code, which is the right tool here: matching charges to tracked rows and computing a delta is deterministic logic, not judgment, so no agent is involved and the result is the same every week.

**Record** inserts the reconciled numbers into the weekly_reports [table](/academy/tables/intro) before anything is posted. That ordering is deliberate: the table is the durable record, so every past week stays queryable even if the Slack message scrolls away. **Digest** then posts the summary to #finance, and Monday's report is waiting before anyone asks for it.
16 changes: 16 additions & 0 deletions apps/docs/content/docs/en/academy/use-cases/slack-it-triage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: An agent that watches a Slack channel, classifies incoming IT reque
import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import { AV_IT_TRIAGE_WORKFLOW } from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Slack IT Triage Bot" className="mt-2" />

Expand Down Expand Up @@ -40,4 +42,18 @@ Build an agent that lives in a Slack channel: it reads each incoming IT request,

A **Slack trigger** starts the workflow on each new message. An **Agent** block classifies the request and decides the path: a **knowledge-base search** drafts an answer for common questions, while anything it can't resolve is routed to a human or filed as a ticket. Every run is recorded in the [logs](/logs-debugging).

Here is the machine the video builds:

<WorkflowPreview workflow={AV_IT_TRIAGE_WORKFLOW} height={340} />

This pulls together [workflows](/academy/workflows/intro), [agents](/academy/agents/intro), and [knowledge bases](/academy/knowledge-bases/intro) into one system: the foundations, composed.

## How it works

The **IT Help Trigger** fires on every message posted in the channel, and it hands the workflow more than the text: the sender, the channel, and the message timestamp all arrive as outputs the later blocks can reference. That timestamp matters at the end.

The **Triage** agent classifies the request, and its Response Format is the lesson: instead of prose, it is forced to return a structured object with a `category` field that is either `answerable` or `escalate`. A structured decision is something the next block can branch on; free text is not. The [Agent block](/academy/agents/intro) page covers structured outputs in depth.

The **Answerable?** condition reads `<triage.category>` and picks the path. On the answerable side, the **Knowledge** block searches the IT Docs [knowledge base](/academy/knowledge-bases/intro) and returns the top 3 chunks, the **Answer** agent writes a reply grounded in those chunks, and the **Reply** block posts it back to Slack with the trigger's Thread TS, so the answer lands in the same thread as the question instead of as a new channel message.

Everything else takes the other branch: **Escalate** posts the request to #it-escalations, where a human picks it up. The bot never guesses on requests it was not built to answer.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Telegram Personal Assistant
description: An assistant you text like a friend, it reads your inbox, checks your calendar, researches on request, and sends a morning brief on its own.
---

import { VideoPlaceholder } from '@/components/ui/video-placeholder'
import { WhatYouWillLearn } from '@/components/ui/what-you-will-learn'
import { VideoChapters } from '@/components/ui/video-chapters'
import { WorkflowPreview } from '@/components/workflow-preview'
import {
AV_MORNING_BRIEF_WORKFLOW,
AV_TELEGRAM_ASSISTANT_WORKFLOW,
} from '@/components/workflow-preview/academy-video-workflows'

<VideoPlaceholder eyebrow="Use case" title="Telegram Personal Assistant" className="mt-2" />

<div className="mt-8 grid grid-cols-1 items-start gap-10 lg:grid-cols-[1fr_300px]">
<div>

Build an assistant you message like a friend. Each Telegram text, a question about your inbox, a calendar check, a quick research request, is routed to the right tools and answered in the same thread. A second trigger sends an unprompted brief every morning at 7:00.

<WhatYouWillLearn
items={[
{ title: 'Trigger from a message', body: 'Start a workflow from a Telegram text and reply in the same thread.' },
{ title: 'Route to the right tools', body: 'Use a Router so inbox, calendar, and research requests each take their own path.' },
{ title: 'Act without being asked', body: 'Add a schedule that assembles and sends a morning brief on its own.' },
]}
/>

</div>

<VideoChapters
chapters={[
{ title: 'The problem', time: '0:00' },
{ title: 'Telegram trigger', time: '0:35' },
{ title: 'Route the request', time: '1:15' },
{ title: 'Three agent lanes', time: '2:00' },
{ title: 'The morning brief', time: '3:00' },
]}
/>

</div>

## What you'll build

A **Telegram trigger** starts the workflow on each incoming message. A **Router** block reads the request and picks a lane: an **Agent** that reads Gmail, an **Agent** that checks Google Calendar, or an **Agent** that researches the web with Exa. Whichever lane runs, the answer goes back as a reply in the same Telegram thread. A second **Schedule trigger** fires daily at 7:00, a brief agent gathers the day's context, and a **Telegram send** delivers it before you ask. Every run is recorded in the [logs](/logs-debugging).

Here is the assistant the video builds:

<WorkflowPreview workflow={AV_TELEGRAM_ASSISTANT_WORKFLOW} height={380} />

This pulls together [workflows](/academy/workflows/intro) and [agents](/academy/agents/intro) into one system: the foundations, composed.

## How it works

The **Telegram Trigger** fires on each message you send the bot and carries the chat id, which is how the reply finds its way back to the same conversation.

The **Router** is the block that makes this an assistant instead of a chain: it reads the request and picks exactly one lane. "Did anything come in from the landlord?" goes to **Email**, "what's on Thursday?" goes to **Calendar**, and "find me a standing desk under $400" goes to **Research**. Unlike a Condition, which tests a value you name, a [Router](/academy/workflows/intro) uses a model to read intent, which is the right tool when the input is free-form language.

Each lane is a small [agent](/academy/agents/intro) with exactly the tools its job needs: Gmail for the email lane, Google Calendar for the calendar lane, Exa search for the research lane. Narrow agents with few tools are easier to steer than one agent with everything. Whichever lane runs, **Reply** sends the answer back to the trigger's chat id.

The assistant also speaks first. A second workflow, on a **Schedule** trigger at 7:00, runs a **Brief** agent that reads the inbox and the calendar, and **Send** delivers the morning summary before you ask:

<WorkflowPreview workflow={AV_MORNING_BRIEF_WORKFLOW} />
Loading
Loading