-
Notifications
You must be signed in to change notification settings - Fork 28
feat(trigger-chat-agent): AI chat agent that teaches Trigger.dev by drawing #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
D-K-P
wants to merge
31
commits into
main
Choose a base branch
from
add-trigger-chat-agent-example
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
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 91256f4
docs: add trigger-chat-agent to the examples list
D-K-P 8250c6e
style(trigger-chat-agent): apply the Launch Week charcoal/apple design
D-K-P d41b1e3
feat(trigger-chat-agent): teach with HTML lessons + next-step chips
D-K-P d4eb7b1
fix(trigger-chat-agent): harden the Lesson iframe against prompt-inje…
D-K-P 0265e4e
feat(trigger-chat-agent): screen lessons with a fan-out before they r…
D-K-P a01ac5b
feat(trigger-chat-agent): quarantine untrusted docs-MCP output at the…
D-K-P 0617559
fix(trigger-chat-agent): quarantine docs output via toModelOutput, no…
D-K-P f913b38
docs(trigger-chat-agent): inline .env vars in setup (no .env.example …
D-K-P 1783fd3
feat(trigger-chat-agent): rebuild the chat shell in the Launch Week d…
D-K-P 08eafee
feat(trigger-chat-agent): data-driven teaching component kit
D-K-P 0e21d7a
refactor(trigger-chat-agent): drop HTML lessons for the data-driven kit
D-K-P fde1c23
style(trigger-chat-agent): use the real Trigger.dev code theme in Cod…
D-K-P 23c15f0
fix(trigger-chat-agent): plain token streaming + offer a build prompt…
D-K-P 911ba91
copy(trigger-chat-agent): update the empty-state subtitle
D-K-P 6071485
fix(trigger-chat-agent): pointer cursor on clickable buttons
D-K-P 9d384b5
fix(trigger-chat-agent): smoother entrance — drop filter blur, scroll…
D-K-P f1e984b
fix(trigger-chat-agent): offer topic choices as chips, not a grid of …
D-K-P f8e7674
fix(trigger-chat-agent): dock next-step chips so they survive turn fi…
D-K-P a240816
feat(trigger-chat-agent): optional chat history with a sidebar
D-K-P 16c5550
fix(trigger-chat-agent): stop FlowGraph nodes overlapping
D-K-P 5d2768a
feat(trigger-chat-agent): visible error states, and teach it its own …
D-K-P 1efd287
fix(trigger-chat-agent): follow the stream, float the composer, stop …
D-K-P 21b11ee
refactor(trigger-chat-agent): chat history from Sessions, no database
D-K-P 3257ab3
fix(trigger-chat-agent): scope chats with session tags, filtered serv…
D-K-P b5c7d6a
refactor(trigger-chat-agent): drop the sidebar and chat history
D-K-P df883f4
copy(trigger-chat-agent): point the disclaimer at the doc citations
D-K-P fc83924
docs(trigger-chat-agent): rewrite README, drop AI tells, note gen_ai …
D-K-P 6027633
fix(trigger-chat-agent): correct StatCard name in prompt component re…
D-K-P 5acbc34
chore(trigger-chat-agent): drop internal design-notes file
D-K-P f31b070
docs: reword trigger-chat-agent row in the examples table
D-K-P File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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-... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| node_modules | ||
| .env | ||
| .trigger | ||
| .next | ||
| next-env.d.ts | ||
| *.tsbuildinfo | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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": {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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 commitTRIGGER_SECRET_KEYor other credentials when using a standard local environment filename.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents