Files
Eric Allam c06005b353 feat(webapp,sdk): in-dashboard AI agent (#4018)
## Summary

Adds an in-dashboard AI agent: a chat panel, reachable from any
environment
page, that answers questions about your runs, errors, tasks, and
analytics,
diagnoses why a run failed, charts your data, reads your connected
repo's
source, and answers product and how-to questions. It is gated behind the
`hasDashboardAgentAccess` feature flag (global or per-org, default off),
so
this PR ships disabled: the launcher is hidden unless the flag is
enabled.

## Design

The agent runs as a standalone `chat.agent` Trigger task in its own
internal
package, with no access to the webapp database, Prisma, or ClickHouse.
It reads
the user's data over the public API, acting as the user via a
short-lived
delegated user-actor token minted server-side each turn (never in the
browser),
building on
[#3997](https://github.com/triggerdotdev/trigger.dev/pull/3997). The
error and analytics tools use
[#4005](https://github.com/triggerdotdev/trigger.dev/pull/4005)
and the TRQL query API.

The first turn of a new chat streams from a warm webapp route (Head
Start) while
the durable agent boots in parallel. Structured answers (a run-failure
diagnosis
card, a live chart) render through a small typed view catalog rather
than
arbitrary markup. A knowledge lane forwards product and how-to questions
to the
support assistant.

Conversation history lives in a separate Drizzle-backed store on its own
Postgres schema, kept as a display read-model so it can never corrupt
the
agent's model context.

The SDK changes add an `apiClient` option to
`chat.createStartSessionAction` and
`chat.headStart`, and keep the Head Start tool-approval tail intact
across a
custom `prepareMessages` hook so prompt caching and Head Start compose.
2026-06-24 19:04:28 +01:00

1.6 KiB

@internal/dashboard-agent

The in-dashboard agent, built on chat.agent and deployed as its own Trigger project. This is the launch-week dogfood: we run our own product on the primitive we ship.

Why a separate package (not inside apps/webapp)

The agent has no access to the main database, ClickHouse, or webapp internals — it reads everything via the API. Living in a standalone package that doesn't depend on the webapp makes that firewall structural: the package physically cannot import webapp server code. It also keeps the webapp a pure Remix app instead of a dual Remix-app-and-Trigger-project, and gives the agent a small, fast, independently deployable + testable build context.

It writes conversation state to its own datastore via @internal/dashboard-agent-db (the same package the webapp reads from for the History tab). It never touches Prisma.

Deploy / dev

This is a Trigger project with its own trigger.config.ts. The project ref is read from TRIGGER_DASHBOARD_AGENT_PROJECT_REF (never hardcoded — public repo).

cd internal-packages/dashboard-agent
TRIGGER_DASHBOARD_AGENT_PROJECT_REF=<your-project> pnpm run dev      # trigger dev
TRIGGER_DASHBOARD_AGENT_PROJECT_REF=<your-project> pnpm run deploy   # trigger deploy

Runtime env the deployed task needs: DASHBOARD_AGENT_DATABASE_URL (the agent datastore) and OBJECT_STORE_* (chat.agent's built-in conversation snapshot).

Consumed by the webapp

The webapp imports only the task type for transport type-safety:

import type { dashboardAgent } from "@internal/dashboard-agent";

Never a value import (see src/index.ts).