You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: AI prompt management dashboard and enhanced span inspectors (#3244)
- Full prompt management UI: list, detail, override, and version
management for AI prompts defined with `prompts.define()`
- Rich AI span inspectors for all AI SDK operations with token usage,
messages, and prompt context
- Real-time generation tracking with live polling and filtering
## Prompt management
Define prompts in your code with `prompts.define()`, then manage
versions and overrides from the dashboard without redeploying:
```typescript
import { task, prompts } from "@trigger.dev/sdk";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
const supportPrompt = prompts.define({
id: "customer-support",
model: "gpt-4o",
variables: z.object({
customerName: z.string(),
plan: z.string(),
issue: z.string(),
}),
content: `You are a support agent for Acme SaaS.
Customer: {{customerName}} ({{plan}} plan)
Issue: {{issue}}
Respond with empathy and precision.`,
});
export const supportTask = task({
id: "handle-support",
run: async (payload) => {
const resolved = await supportPrompt.resolve({
customerName: payload.name,
plan: payload.plan,
issue: payload.issue,
});
const result = await generateText({
model: openai(resolved.model ?? "gpt-4o"),
system: resolved.text,
prompt: payload.issue,
...resolved.toAISDKTelemetry(),
});
return { response: result.text };
},
});
```
The prompts list page shows each prompt with its current version, model,
override status, and a usage sparkline over the last 24 hours.
From the prompt detail page you can:
- **Create overrides** to change the prompt template or model without
redeploying. Overrides take priority over the deployed version when
`prompt.resolve()` is called.
- **Promote** any code-deployed version to be the current version
- **Browse generations** across all versions with infinite scroll and
live polling for new results
- **Filter** by version, model, operation type, and provider
- **View metrics** (total generations, avg tokens, avg cost, latency)
broken down by version
## AI span inspectors
Every AI SDK operation now gets a custom inspector in the run trace
view:
- **`ai.generateText` / `ai.streamText`** — Shows model, token usage,
cost, the full message thread (system prompt, user message, assistant
response), and linked prompt details
- **`ai.generateObject` / `ai.streamObject`** — Same as above plus the
JSON schema and structured output
- **`ai.toolCall`** — Shows tool name, call ID, and input arguments
- **`ai.embed`** — Shows model and the text being embedded
For generation spans linked to a prompt, a "Prompt" tab shows the prompt
metadata, the input variables passed to `resolve()`, and the template
content from the prompt version.
All AI span inspectors include a compact timestamp and duration header.
## Other improvements
- Resizable panel sizes now persist across page refreshes (patched
`@window-splitter/state` to fix snapshot restoration)
- Run page panels also persist their sizes
- Fixed `<div>` inside `<p>` DOM nesting warnings in span titles and
chat messages
- Added Operations and Providers filters to the AI metrics dashboard
## Screenshots
<img width="3680" height="2392" alt="CleanShot 2026-03-21 at 10 14
17@2x"
src="https://github.com/user-attachments/assets/f3e59989-a2fa-4990-a9d0-3cacda431868"
/>
<img width="3680" height="2392" alt="CleanShot 2026-03-21 at 10 15
37@2x"
src="https://github.com/user-attachments/assets/2f2d02df-2d2b-44fb-ac6f-9153f6a6c387"
/>
<img width="3680" height="2392" alt="CleanShot 2026-03-21 at 10 15
54@2x"
src="https://github.com/user-attachments/assets/baa161e0-ef91-4fa4-a55f-986b71cccdf0"
/>
Define and manage AI prompts with `prompts.define()`. Create typesafe prompt templates with variables, resolve them at runtime, and manage versions and overrides from the dashboard without redeploying.
Copy file name to clipboardExpand all lines: CLAUDE.md
+19Lines changed: 19 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,25 @@ pnpm run dev --filter webapp # Run webapp (http://localhost:3030)
18
18
pnpm run dev --filter trigger.dev --filter "@trigger.dev/*"# Watch CLI and packages
19
19
```
20
20
21
+
### Verifying Changes
22
+
23
+
The verification command depends on where the change lives:
24
+
25
+
-**Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.
26
+
-**Public packages** (`packages/*`): Use `build`.
27
+
28
+
```bash
29
+
# Apps and internal packages — use typecheck
30
+
pnpm run typecheck --filter webapp # ~1-2 minutes
31
+
pnpm run typecheck --filter @internal/run-engine
32
+
33
+
# Public packages — use build
34
+
pnpm run build --filter @trigger.dev/sdk
35
+
pnpm run build --filter @trigger.dev/core
36
+
```
37
+
38
+
Only run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
39
+
21
40
## Testing
22
41
23
42
We use vitest exclusively. **Never mock anything** - use testcontainers instead.
Copy file name to clipboardExpand all lines: apps/webapp/CLAUDE.md
+42Lines changed: 42 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,48 @@
2
2
3
3
Remix 2.1.0 app serving as the main API, dashboard, and orchestration engine. Uses an Express server (`server.ts`).
4
4
5
+
## Verifying Changes
6
+
7
+
**Never run `pnpm run build --filter webapp` to verify changes.** Building proves almost nothing about correctness. The webapp is an app, not a public package — use typecheck from the repo root:
8
+
9
+
```bash
10
+
pnpm run typecheck --filter webapp # ~1-2 minutes
11
+
```
12
+
13
+
Only run typecheck after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
14
+
15
+
Note: Public packages (`packages/*`) use `build` instead. See the root CLAUDE.md for details.
16
+
17
+
## Testing Dashboard Changes with Chrome DevTools MCP
18
+
19
+
Use the `chrome-devtools` MCP server to visually verify local dashboard changes. The webapp must be running (`pnpm run dev --filter webapp` from repo root).
2. mcp__chrome-devtools__click the "Continue with Email" link
27
+
3. mcp__chrome-devtools__fill the email field with "local@trigger.dev"
28
+
4. mcp__chrome-devtools__click "Send a magic link"
29
+
→ Auto-logs in and redirects to the dashboard (no email verification needed locally)
30
+
```
31
+
32
+
### Navigating and Verifying
33
+
34
+
-**take_snapshot**: Get an a11y tree of the page (text content, element UIDs for interaction). Prefer this over screenshots for understanding page structure.
35
+
-**take_screenshot**: Capture what the page looks like visually. Use to verify styling, layout, and visual changes.
36
+
-**navigate_page**: Go to specific URLs, e.g. `http://localhost:3030/orgs/references-bc08/projects/hello-world-SiWs/env/dev/runs`
37
+
-**click / fill**: Interact with elements using UIDs from `take_snapshot`.
38
+
-**evaluate_script**: Run JS in the browser console for debugging.
39
+
-**list_console_messages**: Check for console errors after navigating.
40
+
41
+
### Tips
42
+
43
+
- Snapshots can be very large on complex pages (200K+ chars). Use `take_screenshot` first to orient, then `take_snapshot` only when you need element UIDs to interact.
44
+
- The local seeded user email is `local@trigger.dev`.
0 commit comments