Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ba408d3
feat(trigger-chat-agent): chat agent that teaches Trigger.dev by drawing
D-K-P Aug 6, 2026
91256f4
docs: add trigger-chat-agent to the examples list
D-K-P Aug 6, 2026
8250c6e
style(trigger-chat-agent): apply the Launch Week charcoal/apple design
D-K-P Aug 6, 2026
d41b1e3
feat(trigger-chat-agent): teach with HTML lessons + next-step chips
D-K-P Aug 6, 2026
d4eb7b1
fix(trigger-chat-agent): harden the Lesson iframe against prompt-inje…
D-K-P Aug 6, 2026
0265e4e
feat(trigger-chat-agent): screen lessons with a fan-out before they r…
D-K-P Aug 6, 2026
a01ac5b
feat(trigger-chat-agent): quarantine untrusted docs-MCP output at the…
D-K-P Aug 6, 2026
0617559
fix(trigger-chat-agent): quarantine docs output via toModelOutput, no…
D-K-P Aug 6, 2026
f913b38
docs(trigger-chat-agent): inline .env vars in setup (no .env.example …
D-K-P Aug 6, 2026
1783fd3
feat(trigger-chat-agent): rebuild the chat shell in the Launch Week d…
D-K-P Aug 6, 2026
08eafee
feat(trigger-chat-agent): data-driven teaching component kit
D-K-P Aug 6, 2026
0e21d7a
refactor(trigger-chat-agent): drop HTML lessons for the data-driven kit
D-K-P Aug 6, 2026
fde1c23
style(trigger-chat-agent): use the real Trigger.dev code theme in Cod…
D-K-P Aug 6, 2026
23c15f0
fix(trigger-chat-agent): plain token streaming + offer a build prompt…
D-K-P Aug 6, 2026
911ba91
copy(trigger-chat-agent): update the empty-state subtitle
D-K-P Aug 6, 2026
6071485
fix(trigger-chat-agent): pointer cursor on clickable buttons
D-K-P Aug 6, 2026
9d384b5
fix(trigger-chat-agent): smoother entrance — drop filter blur, scroll…
D-K-P Aug 6, 2026
f1e984b
fix(trigger-chat-agent): offer topic choices as chips, not a grid of …
D-K-P Aug 6, 2026
f8e7674
fix(trigger-chat-agent): dock next-step chips so they survive turn fi…
D-K-P Aug 6, 2026
a240816
feat(trigger-chat-agent): optional chat history with a sidebar
D-K-P Aug 7, 2026
16c5550
fix(trigger-chat-agent): stop FlowGraph nodes overlapping
D-K-P Aug 7, 2026
5d2768a
feat(trigger-chat-agent): visible error states, and teach it its own …
D-K-P Aug 7, 2026
1efd287
fix(trigger-chat-agent): follow the stream, float the composer, stop …
D-K-P Aug 7, 2026
21b11ee
refactor(trigger-chat-agent): chat history from Sessions, no database
D-K-P Aug 11, 2026
3257ab3
fix(trigger-chat-agent): scope chats with session tags, filtered serv…
D-K-P Aug 11, 2026
b5c7d6a
refactor(trigger-chat-agent): drop the sidebar and chat history
D-K-P Aug 11, 2026
df883f4
copy(trigger-chat-agent): point the disclaimer at the doc citations
D-K-P Aug 11, 2026
fc83924
docs(trigger-chat-agent): rewrite README, drop AI tells, note gen_ai …
D-K-P Aug 11, 2026
6027633
fix(trigger-chat-agent): correct StatCard name in prompt component re…
D-K-P Aug 11, 2026
5acbc34
chore(trigger-chat-agent): drop internal design-notes file
D-K-P Aug 11, 2026
f31b070
docs: reword trigger-chat-agent row in the examples table
D-K-P Aug 11, 2026
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ For information on how to run each project, see the README in each directory.
| [Claude changelog generator](/changelog-generator) | Generate changelogs from a GitHub repository using the [Claude Agent SDK](https://docs.claude.com/en/docs/agent-sdk/overview) with Trigger.dev |
| [Claude agent GitHub wiki](/claude-agent-github-wiki) | AI-powered repository analyzer that lets you ask questions about any public GitHub repository using Anthropic's [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), with real-time streaming via [Trigger.dev Realtime](https://trigger.dev/docs/realtime/overview) |
| [ClickHouse chat agent](/clickhouse-chat-agent) | A [Trigger.dev AI Chat](https://trigger.dev/docs/ai-chat/overview) agent that answers questions about your [ClickHouse](https://clickhouse.com/cloud) data with generative UI — [shadcn](https://ui.shadcn.com) charts, tables and stat cards rendered from [json-render](https://json-render.dev) specs instead of walls of text |
| [Trigger.dev chat agent](/trigger-chat-agent) | A [Trigger.dev AI Chat](https://trigger.dev/docs/ai-chat/overview) agent that teaches you Trigger.dev by drawing: interactive [React Flow](https://reactflow.dev) diagrams, quizzes and cards rendered from [json-render](https://json-render.dev) specs, grounded on the live docs via an [MCP](https://modelcontextprotocol.io) server |
| [Company enrichment tool](/smart-spreadsheet) | AI-powered company enrichment tool. Enter a company name or URL, get verified data with source links. Uses [Supabase](https://supabase.com), [AI SDK](https://sdk.vercel.ai/docs/introduction), [Trigger.dev](https://trigger.dev) and [Exa](https://exa.ai) |
| [Deep research agent using the AI SDK](/vercel-ai-sdk-deep-research-agent/) | An intelligent deep research agent using the Vercel [AI SDK](https://sdk.vercel.ai/docs/introduction) and Trigger.dev |
| [Monorepos](/monorepos) | Examples of using Trigger.dev in monorepo setups with [Turborepo](https://turbo.build/) and [Prisma](https://www.prisma.io/) |
Expand Down
18 changes: 18 additions & 0 deletions trigger-chat-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Your Trigger.dev project ref (from the project settings page in the dashboard)
TRIGGER_PROJECT_REF=proj_xxxxxxxxxxxxxxxxxxxxxxxx

# Your Trigger.dev secret key (API keys page in the dashboard). Used by the
# Next.js server actions to create chat sessions and mint session tokens.
TRIGGER_SECRET_KEY=tr_dev_xxxxxxxxxxxxxxxxxxxxxxxx

# Only needed if you're not using cloud.trigger.dev (e.g. self-hosting):
# TRIGGER_API_URL=https://your-trigger-instance.example.com
# NEXT_PUBLIC_TRIGGER_API_URL=https://your-trigger-instance.example.com

# Set these two in the Trigger.dev dashboard (Environment Variables page) so they
# are available in both dev and deployed runs. Uncomment to override locally:
#
# ClickHouse HTTPS endpoint with credentials embedded:
# CLICKHOUSE_URL=https://default:YOUR_PASSWORD@YOUR_SERVICE.clickhouse.cloud:8443
#
# ANTHROPIC_API_KEY=sk-ant-...
6 changes: 6 additions & 0 deletions trigger-chat-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
.env

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Ignore all local environment files.

Line 2 does not ignore .env.local, .env.development.local, or .env.production.local. A developer can commit TRIGGER_SECRET_KEY or other credentials when using a standard local environment filename.

Proposed fix
-.env
+.env*
+!.env.example
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.env
.env*
!.env.example
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@trigger-chat-agent/.gitignore` at line 2, Update the ignore rules in
.gitignore to cover all local environment variants, including .env.local,
.env.development.local, and .env.production.local, while retaining the existing
.env rule.

.trigger
.next
next-env.d.ts
*.tsbuildinfo
70 changes: 70 additions & 0 deletions trigger-chat-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Trigger.dev chat agent: a tutor that teaches by drawing

A [Trigger.dev chat agent](https://trigger.dev/docs/ai-chat/overview) that **teaches you Trigger.dev** by *drawing*. Instead of dumping paragraphs, it composes interactive components. Ask "how does a fan-out with retries work?" and you get an **interactive node-graph** of the flow. Ask it to teach you retries and you get a short explainer, a **quiz**, and a gotcha **callout**. Every turn ends with next-step chips so the learning keeps flowing.

The agent decides how best to teach. It writes a sentence or two, then calls a `renderVisualization` tool with a [json-render](https://json-render.dev) spec, and the Next.js chat UI renders it live with [React Flow](https://reactflow.dev) and a kit of [shadcn/ui](https://ui.shadcn.com)-based teaching components. The model supplies *data*, not markup, so a card is a handful of tokens and always looks right. Every fact it states is grounded on the live docs through a documentation [MCP server](https://modelcontextprotocol.io), so it doesn't invent API surface.

The teaching method (mission-first, one tangible win per turn, knowledge then a retrieval quiz, everything grounded in trusted sources) is adapted from [Matt Pocock's "teach" skill](https://www.aihero.dev/learn-anything-with-my-teach-skill) ([source](https://github.com/mattpocock/skills/tree/main/skills/productivity/teach)), reworked from a local-filesystem workspace into an in-chat experience.

## How it works

**The agent** (`src/trigger/trigger-chat-agent.ts`) is a single `chat.agent()` call. Trigger.dev handles the chat session, turn loop, streaming and resumability. Its system prompt is a versioned [AI Prompt](https://trigger.dev/docs/ai/prompts) (`prompts.define()` + `chat.prompt.set()`), so you can edit the teaching guidance, model or temperature from the dashboard without redeploying. Model calls emit spans that follow the OpenTelemetry [GenAI semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/), so any span with the standard `gen_ai` attributes gets cost data automatically: you get token, cost and latency observability in the dashboard, linked to the prompt version that produced each call, for free. It has two kinds of tools:

- **`renderVisualization`** takes a json-render UI spec composed from the component kit (FlowGraph, HeroCard, Quiz, Callout, Compare, Steps, Glossary, StatCard, CodeCard, DiagramCard, PromptCard). The spec is validated against the component catalog, and validation errors go back to the model so it can correct the spec and retry.
- **`suggestNext`** is called at the end of every turn with 2 to 4 next-step chips: a *deeper* step, a *sideways* related concept, a *practice* quiz, or fresh *topic* suggestions. The chip's label is sent verbatim as the next message when clicked, so the learning keeps flowing without the user having to think up the next question.
- **Docs MCP tools** are merged in from a documentation MCP server (default: the hosted [Context7](https://context7.com) server) so the agent looks up Trigger.dev APIs, config and behaviour instead of answering from memory. The tools are resolved per turn and declared on the agent config, so their calls survive Trigger.dev's cross-turn history re-conversion. Swap `DOCS_MCP_URL` to point the demo at any other product's docs MCP. Retrieved docs are **untrusted input** (a poisoned page is the upstream prompt-injection vector), so each tool's output is quarantined (`src/lib/quarantine.ts`): wrapped as data-not-instructions and flagged if it contains injection markers, before the model ever sees it.

**The shared catalog** (`src/lib/catalog.ts`) defines which components the model may use: `Card`, `Stack`, `Grid`, `Heading`, `Text`, `Badge` from [`@json-render/shadcn`](https://www.npmjs.com/package/@json-render/shadcn), plus a kit of custom teaching components. They're all **data-driven** (the model fills fields, the component renders), so there's no model-authored markup to sanitize and every card is cheap and consistent:

- **`FlowGraph`** (`src/components/flow-graph.tsx`) is the signature visual: a directed node-graph on [React Flow](https://reactflow.dev) + [dagre](https://github.com/dagrejs/dagre) styled like the Trigger.dev dashboard, with status dots, dashed retry edges, an animated topological reveal, and an optional timed status sequence.
- **`HeroCard`** and **`StatCard`** are the intro card and KPI card, ported from the Trigger.dev Launch Week designs.
- **`Quiz`** is a multiple-choice question with immediate feedback (retrieval practice). **`Callout`**, **`Compare`**, **`Steps`** and **`Glossary`** cover gotchas, "X vs Y", walkthroughs, and term/definition lists. **`CodeCard`**, **`DiagramCard`** and **`PromptCard`** round out the kit.

The same catalog generates the system-prompt component reference and validates tool calls, so the prompt and the renderer can't drift apart.

**The frontend** (`src/app`, `src/components`) is a Next.js app using [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) with [`useTriggerChatTransport`](https://trigger.dev/docs/ai-chat/frontend). The browser talks directly to Trigger.dev's durable streams, no API route needed. `renderVisualization` tool parts in the message stream are rendered with json-render's `<Renderer>` and the shadcn component registry (`src/lib/registry.tsx`).

## Setup

1. Create a project in the [Trigger.dev dashboard](https://cloud.trigger.dev) and copy its project ref and a dev secret key (API keys page).

2. Configure the environment:

```sh
cp .env.example .env
# paste your project ref and secret key into .env
```

3. In the dashboard, add environment variables (Environment Variables page) for the Dev environment (and Prod if you deploy):

- `ANTHROPIC_API_KEY`: the agent uses Claude via the AI SDK.
- `DOCS_MCP_URL` *(optional)*: the docs MCP server to ground answers on. Defaults to `https://mcp.context7.com/mcp`. Point it at another product's docs MCP to fork the demo to a different domain.

4. Install and run both processes (two terminals):

```sh
pnpm install
pnpm dev:trigger # the agent
pnpm dev # the Next.js app
```

5. Open [http://localhost:3000](http://localhost:3000) and start asking.


## Try asking

- "What is Trigger.dev, and how does it work?" gets a ground-up explainer.
- "Teach me retries properly" gets an explainer, a quiz, and a gotcha callout.
- "How does a fan-out with retries work?" draws an interactive FlowGraph.
- "How does a run survive a redeploy?" draws the checkpoints.
- "Suggest more topics" and it proposes a fresh set, grounded in the docs.

Then follow the next-step chips under each answer to keep going.

## Deploy

```sh
pnpm deploy:trigger
```

Make sure `ANTHROPIC_API_KEY` (and optionally `DOCS_MCP_URL`) are set for the Prod environment in the dashboard, and deploy the Next.js app anywhere with `TRIGGER_SECRET_KEY` (prod) set.
22 changes: 22 additions & 0 deletions trigger-chat-agent/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
5 changes: 5 additions & 0 deletions trigger-chat-agent/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {};

export default nextConfig;
46 changes: 46 additions & 0 deletions trigger-chat-agent/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "trigger-chat-agent",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"dev:trigger": "trigger dev",
"deploy:trigger": "trigger deploy"
},
"dependencies": {
"@ai-sdk/anthropic": "^3.0.0",
"@ai-sdk/mcp": "^1.0.66",
"@ai-sdk/react": "^3.0.0",
"@dagrejs/dagre": "^3.1.0",
"@json-render/core": "^0.19.0",
"@json-render/react": "^0.19.0",
"@json-render/shadcn": "^0.19.0",
"@trigger.dev/sdk": "^4.5.1",
"@xyflow/react": "^12.11.2",
"ai": "^6.0.0",
"clsx": "^2.1.1",
"lucide-react": "^0.564.0",
"motion": "^12.0.0",
"next": "16.1.1",
"prism-react-renderer": "^2.4.1",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"tailwind-merge": "^3.4.1",
"zod": "^4.3.6"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^22",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwind-scrollbar": "^4.0.2",
"tailwindcss": "^4",
"trigger.dev": "^4.5.1",
"tw-animate-css": "^1.4.0",
"typescript": "^5"
}
}
Loading