Skip to content

feat(webapp,sdk): in-dashboard AI agent#4018

Merged
ericallam merged 29 commits into
mainfrom
feat/dashboard-agent-scaffold
Jun 24, 2026
Merged

feat(webapp,sdk): in-dashboard AI agent#4018
ericallam merged 29 commits into
mainfrom
feat/dashboard-agent-scaffold

Conversation

@ericallam

Copy link
Copy Markdown
Member

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. The
error and analytics tools use #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.

ericallam added 26 commits June 22, 2026 17:49
Range-scoped to ^18 so packages on react 19 (rsc) stay untouched.
Collapses the duplicate react copies that otherwise break hook-based
SDK components with an invalid hook call.
When set, the returned action runs under the given baseURL and access
token (via apiClientManager.runWithConfig) instead of the ambient SDK
config, so one server can start chat sessions in a different runtime
environment.
Adds an "Ask the agent" side panel on every environment page, backed by
a chat.agent task that runs as its own internal Trigger project with no
main-database or ClickHouse access. Conversations persist to a dedicated
Postgres schema via a small Drizzle store; the panel restores the last
open chat and resumes streaming without replay.

No tools yet: the agent answers from the model only. Tools, delegated
auth, and the data lane land in follow-ups.
Adds hasDashboardAgentAccess to the flag catalog, off by default via
DASHBOARD_AGENT_ENABLED. The panel renders only when the flag is on for
the org or the viewer is staff, and the resource route enforces the same
check so a non-flagged user cannot start sessions by calling it directly.
Controllable globally and per-org from the admin flags UI.
…+ caching

Drive the agent and title models from dashboard-managed prompts resolved
through an Anthropic provider registry (agent claude-sonnet-4-6, title
claude-haiku-4-5). Generate the chat title in the background after the
first turn with the cheaper model so it never blocks the response, writing
it only while the chat still has the default title. Add Anthropic prompt
caching: an ephemeral breakpoint on the system block plus a rolling
breakpoint on the last message.
The deploy-time prompt dedup hashed only the prompt text, so changing a
code prompt's model or config was silently skipped and the previous
version kept serving. Include model and config in the version-definition
hash so those changes create a new version.
Open the agent inside a ResizablePanelGroup (content + handle + agent
panel) using the shared Resizable primitive, so the panel drag-resizes
between 320 and 720px with the standard handle and keyboard support.
autosaveId persists the width across opens and reloads.
The project worker-by-tag endpoint now accepts a delegated user-actor
token the same way it accepts a personal access token, so a first-party
caller can list a project's deployed tasks on the user's behalf. It stays
identity-scoped, with no change to what the user can already do.
A caret range resolved a newer ai build than the SDK uses, pulling a
second copy of the AI SDK tool types and breaking type-checking against
the chat agent's tool set. Pinning the exact version dedupes them.
The dashboard agent can now read your projects, environments, runs, and
deployed tasks by calling the public API as you. Each turn mints a
short-lived, read-only delegated token on the server and hands it to the
agent through a same-origin proxy on the message-send path, so the token
is never exposed to the browser. The response stream stays pointed
directly at the realtime host. Tools: list_projects, list_environments,
get_run, list_tasks.
The dashboard agent can now list recent runs in the current environment
(filterable by status, task, and a time window of up to 30 days) and
fetch a run's execution trace to explain why it failed, retried, or was
slow.
chat.headStart now accepts an apiClient (base URL + access token), so the
head-start route can create the session and trigger the agent run against a
different project or environment than the warm server's ambient config.
Mirrors chat.createStartSessionAction; the run callback's LLM keys are
unaffected.
Pins ai (^6) and @ai-sdk/provider-utils (^4) via pnpm overrides so the AI SDK
tool types resolve to one instance across the app, the SDK, and internal
packages. Two provider-utils copies previously broke type-checking a shared
tool set across package boundaries. Also adds @ai-sdk/anthropic to the webapp
for the agent's first-turn route.
The first turn of a new dashboard agent chat now streams step 1 from the
webapp while the agent run boots in parallel, cutting first-token latency.
The warm route runs step 1 with schema-only tools (the tool execute fns stay
in the agent, never the webapp bundle) and mints a fresh read-only delegated
token server-side, injected into the run so the first turn's tool calls are
authed as the user without the token ever reaching the browser. Falls back to
the normal path when no Anthropic key is configured.
The dashboard agent can now read error groups as the signed-in user: list_errors lists distinct errors by fingerprint with occurrence counts and status, get_error returns the full detail for one, and list_runs can filter to the runs behind an error group. All read-only and scoped to the current environment.
…eMessages

A Head Start handover hands the first turn's pending tool call to the agent as a tool-approval round whose trailing tool message must reach the model untouched for the call to execute. A prepareMessages hook that rewrote the last message (for example the recommended prompt-caching breakpoint) dropped it, so the turn failed with "tool_use ids were found without tool_result". The agent now preserves that approval tail across prepareMessages, so caching and Head Start compose cleanly.
Drive the agent through real turns offline with mockChatAgent and MockLanguageModelV3: text streaming, tool execution, the prompt-cache breakpoint, the Head Start handover resume, and the read tools failing closed without a delegated token. The agent's datastore and model are now injectable via locals so the tests need no database or provider.
…answer quality

Vitest evals that exercise the agent against a real model with fixture
tools: a tool-selection set scored on expected tool choices, plus an
LLM-as-judge case for answer quality. Runs behind its own config so it
stays out of the unit test run, and *.eval.ts files are kept out of the
task index.
After each turn the agent enqueues a decoupled, idempotency-keyed task
that judges the turn (grounding, whether the question was answered,
intent, outcome) and flags product signal (capability gaps, docs gaps,
support opportunities, feature requests), then writes one row. The judge
runs out of band so it never blocks or bills the agent run. Adds the
chat_turn_evals table and migration to @internal/dashboard-agent-db.
…mode

When a project has a connected GitHub repo, the in-dashboard agent can now read
its source to ground answers. It pulls the repo at the tracked commit onto its
own filesystem and exposes read-only list, read, and grep tools, so it can
explain a run or error against the actual task code, citing file and line.

The webapp resolves a short-lived signed archive URL server-side and injects it
per turn, so the GitHub token never reaches the agent. With no connected repo
the agent stays in its usual assistant mode.
…deployed from

The agent code tools now take an optional runId. When investigating a specific
run, the agent reads the exact source that run version was deployed from instead
of the latest commit, so the explanation matches the code that actually ran.

A new endpoint maps the run to its deployment commit and resolves a signed
archive URL for it server-side (the GitHub token stays on the server); the agent
downloads and reads that commit. Runs with no deployed version fall back to the
tracked branch head.
The dashboard agent now answers "why did this run fail?" with a structured
failure card (summary, category, likely cause, confidence, evidence, impact,
next steps, and action buttons) instead of plain prose.

The card is the first block in a small view catalog: the agent emits a
render_view tool call constrained to a fixed set of blocks, and the dashboard
renders it through a component registry. Only known block types render, so the
agent can never produce arbitrary markup. New blocks plug in by adding a schema
member plus a registry entry.
…iew block

The dashboard agent can now answer analytics questions with data and charts.
Two read-only query tools let it discover the TRQL schema and run queries
against the current environment, and a new "chart" block in the view catalog
renders a line or bar chart.

The chart block carries the TRQL query rather than rows: the panel runs it
through the dashboard's existing query execution and chart components, so the
chart is live and matches the Query page. Queries run as the user over the
public query API (read:query), so the agent still reaches no data directly.
… questions

The dashboard agent can now answer "how does Trigger.dev work?" questions (docs,
concepts, features, how-tos) by asking the Trigger.dev support assistant, instead
of guessing or limiting itself to the user's own data.

The ask_support tool forwards the question to a service-to-service ask endpoint
(the support assistant composes the answer) and returns it. It carries no user
data and uses a shared secret server-side only, so nothing reaches the browser.
AgentChat's .in/append and .out SSE calls built their headers by hand and
omitted x-trigger-branch, so a chat.agent deployed to a preview branch returned
401 "x-trigger-branch header required for preview env" the moment a message was
appended. sessions.start already sends the branch via the API client; these two
raw fetches now do too, from the same apiClientManager.branchName.
Resolve dashboard agent access in the env layout loader (global env override,
then admins, then the global or per-org feature flag, default off) and pass it
to the launcher. The button previously read only the per-org flag on the
client, so enabling the agent globally granted server access but left the
button hidden for non-admins. The launcher now matches the server check.
@changeset-bot

changeset-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 13ec864

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 28 packages
Name Type
@trigger.dev/sdk Patch
@trigger.dev/python Patch
@internal/dashboard-agent Patch
@internal/sdk-compat-tests Patch
@trigger.dev/build Patch
@trigger.dev/core Patch
@trigger.dev/plugins Patch
@trigger.dev/react-hooks Patch
@trigger.dev/redis-worker Patch
@trigger.dev/rsc Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer Patch
@trigger.dev/rbac Patch
@trigger.dev/sso Patch
trigger.dev Patch
@internal/cache Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/run-store Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/tsql Patch
@internal/zod-worker Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d21036e3-b3a3-4967-ab28-e9753cf82040

📥 Commits

Reviewing files that changed from the base of the PR and between 8a37eda and 13ec864.

📒 Files selected for processing (5)
  • apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
  • apps/webapp/app/services/dashboardAgentHeadStart.server.ts
  • internal-packages/dashboard-agent-db/src/queries.ts
  • packages/trigger-sdk/src/v3/chat-server.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/webapp/app/services/dashboardAgentHeadStart.server.ts
  • packages/trigger-sdk/src/v3/chat-server.ts
  • apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx
  • internal-packages/dashboard-agent-db/src/queries.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (32)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (9, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (4, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (6, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (12, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (10, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (8, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (2, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (7, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (5, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (11, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (3, 12)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (1, 12)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (4, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (5, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (9, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (10, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (7, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (8, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 10)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 10)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (3, 3)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (1, 3)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (2, 3)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp
  • GitHub Check: 🛡️ E2E Auth Tests (full)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Build and publish previews
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Import from @trigger.dev/sdk when writing Trigger.dev tasks. Never use @trigger.dev/sdk/v3 or deprecated client.defineJob

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

**/*.{ts,tsx,js,jsx}: Prefer static imports over dynamic imports. Only use dynamic import() when circular dependencies cannot be resolved, code splitting is needed for performance, or the module must be loaded conditionally at runtime
Import subpaths only from packages/core (@trigger.dev/core), never import from the root

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: Access environment variables through the env export of env.server.ts instead of directly accessing process.env
Use subpath exports from @trigger.dev/core package instead of importing from the root @trigger.dev/core path

Use named constants for sentinel/placeholder values (e.g. const UNSET_VALUE = '__unset__') instead of raw string literals scattered across comparisons

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
**/*.{js,ts,tsx,jsx,css,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier for code formatting and run pnpm run format before committing

Files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
🧠 Learnings (10)
📚 Learning: 2026-03-22T13:26:12.060Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3244
File: apps/webapp/app/components/code/TextEditor.tsx:81-86
Timestamp: 2026-03-22T13:26:12.060Z
Learning: In the triggerdotdev/trigger.dev codebase, do not flag `navigator.clipboard.writeText(...)` calls for `missing-await`/`unhandled-promise` issues. These clipboard writes are intentionally invoked without `await` and without `catch` handlers across the project; keep that behavior consistent when reviewing TypeScript/TSX files (e.g., usages like in `apps/webapp/app/components/code/TextEditor.tsx`).

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-03-22T19:24:14.403Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 3187
File: apps/webapp/app/v3/services/alerts/deliverErrorGroupAlert.server.ts:200-204
Timestamp: 2026-03-22T19:24:14.403Z
Learning: In the triggerdotdev/trigger.dev codebase, webhook URLs are not expected to contain embedded credentials/secrets (e.g., fields like `ProjectAlertWebhookProperties` should only hold credential-free webhook endpoints). During code review, if you see logging or inclusion of raw webhook URLs in error messages, do not automatically treat it as a credential-leak/secrets-in-logs issue by default—first verify the URL does not contain embedded credentials (for example, no username/password in the URL, no obvious secret/token query params or fragments). If the URL is credential-free per this project’s conventions, allow the logging.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-05-18T08:21:27.694Z
Learnt from: d-cs
Repo: triggerdotdev/trigger.dev PR: 3632
File: apps/webapp/sentry.server.ts:4-21
Timestamp: 2026-05-18T08:21:27.694Z
Learning: When handling Prisma error P1001 ("Can't reach database server") in TypeScript, don’t assume a single error shape. Prisma can surface P1001 via two different error classes/fields: `PrismaClientKnownRequestError` exposes it as `err.code === "P1001"` (common during mid-query connection drops), while `PrismaClientInitializationError` exposes it as `err.errorCode === "P1001"` (common on client startup failure). Therefore, predicates should use `err.code === "P1001" || err.errorCode === "P1001"`. Do not flag `err.code === "P1001"` as “unreachable/never matches,” as it is expected in production.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-05-18T08:21:27.694Z
Learnt from: d-cs
Repo: triggerdotdev/trigger.dev PR: 3632
File: apps/webapp/sentry.server.ts:4-21
Timestamp: 2026-05-18T08:21:27.694Z
Learning: When handling Prisma errors for P1001 ("Can't reach database server"), do not assume it only appears under a single property name. Prisma may surface P1001 via either `PrismaClientKnownRequestError` (`err.code === "P1001"`, e.g., mid-query connection drops) or `PrismaClientInitializationError` (`err.errorCode === "P1001"`, e.g., client startup connection failure). To reliably detect the condition, check `err.code === "P1001" || err.errorCode === "P1001"`, and avoid review rules that would incorrectly flag `err.code === "P1001"` as unreachable/never-matching.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-06-13T19:53:13.759Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3937
File: packages/trigger-sdk/skills/realtime-and-frontend/SKILL.md:258-260
Timestamp: 2026-06-13T19:53:13.759Z
Learning: When reviewing code that uses `trigger.dev/react-hooks`’s `useRealtimeRun`, preserve the call signature where the first argument is the full realtime handle object (not `handle.id`). This is intentional to maintain type-safety and is consistent with the official docs; do not suggest changing the first argument from the handle object to `handle.id`.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-06-17T17:13:49.929Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 3948
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.bulk-actions.$bulkActionParam/route.tsx:48-62
Timestamp: 2026-06-17T17:13:49.929Z
Learning: In triggerdotdev/trigger.dev, within `dashboardLoader`/`dashboardAction` (or similar context resolver code) whenever you resolve an organization ID from an organization slug for RBAC/enterprise authorization scope, always read from the primary Prisma client (`prisma`), not `$replica`. Using `$replica` can hit replica-lag and cause the RBAC lookup/authorization to run without the correct org scope (bypassing intended role enforcement). Implement the slug→org lookup with `prisma.organization.findFirst(...)` (or equivalent primary-client query) and add an inline comment documenting why the primary client is required (replica lag could lead to unscoped RBAC checks).

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-06-23T13:04:21.413Z
Learnt from: carderne
Repo: triggerdotdev/trigger.dev PR: 4023
File: apps/webapp/app/services/upsertBranch.server.ts:14-18
Timestamp: 2026-06-23T13:04:21.413Z
Learning: In TypeScript, it’s valid to `import { type X }` and then use `typeof X` in a type-only position, e.g. `type Alias = z.infer<typeof X>`. The `type` modifier suppresses the runtime import, but the type checker still has the full exported type so `z.infer<typeof X>` can resolve correctly. In code reviews, don’t flag this as a TypeScript compile error as long as `typeof X` is used in a type context (e.g., with `z.infer`, `type` aliases, generics), not as a runtime value.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-05-12T21:04:05.815Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3542
File: apps/webapp/app/components/sessions/v1/SessionStatus.tsx:1-3
Timestamp: 2026-05-12T21:04:05.815Z
Learning: In this Remix + TypeScript codebase, do not flag a server/client boundary violation when a file imports only types from a module matching `*.server`.

Specifically, it’s safe to import types using `import type { Foo } from "*.server"` or `import { type Foo } from "*.server"` because TypeScript erases type-only imports at compile time and they emit no JavaScript, so they won’t cross the Remix server/client bundle boundary.

Only raise the boundary concern for value imports (e.g., `import { Foo }` without `type`, or `import Foo`), since those produce JavaScript output.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-06-04T18:16:35.386Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 3836
File: apps/supervisor/src/backpressure/backpressureMonitor.ts:3-5
Timestamp: 2026-06-04T18:16:35.386Z
Learning: When reviewing TypeScript in this repo, apply the rule “prefer type aliases over interfaces” only to data/object shapes and union/intersection type modeling. If an interface is being used as a behavioral contract for collaborators to implement (e.g., method-shape interfaces that define required behavior, such as `BackpressureLogger` / `BackpressureSignalSource` in `apps/supervisor/src/backpressure/backpressureMonitor.ts`), keep it as an `interface` and do not flag it as a type-alias-vs-interface violation.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
📚 Learning: 2026-06-09T17:58:04.699Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 3879
File: apps/webapp/app/models/vercelIntegration.server.ts:619-630
Timestamp: 2026-06-09T17:58:04.699Z
Learning: In this codebase, outbound raw `fetch` calls should typically rely on Node/undici’s default request timeout (about ~300s) rather than adding a per-call `AbortController` + `setTimeout` wrapper inside individual functions (e.g. in files like `apps/webapp/app/models/vercelIntegration.server.ts`). During code review, do not flag the absence of a per-call timeout on a single `fetch` as an issue; if per-call timeouts are needed, they should be implemented via a codebase-wide convention (e.g., a shared fetch wrapper or documented pattern) rather than ad-hoc per-function changes.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts
🔇 Additional comments (1)
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.ts (1)

189-189: LGTM!

Also applies to: 218-218


Walkthrough

This PR adds a dashboard agent feature across the webapp, a dedicated Drizzle datastore package, and a Trigger task package. It introduces new routes for chat loading, message proxying, repo snapshot lookup, and user-actor token flow, plus UI components for chat, history, draft, diagnosis cards, charts, and view rendering. It also adds dashboard-agent access gating and environment configuration. Separately, the SDK updates add preview-branch header forwarding, preserve head-start approval tails through prepareMessages, and add apiClient scoping for start-session and head-start flows.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing the required template sections like Closes, checklist, Testing, Changelog, and Screenshots. Add the required template sections, including Closes #issue, checklist items, testing steps, changelog, and screenshots placeholders.
Docstring Coverage ⚠️ Warning Docstring coverage is 58.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly summarizes the main change: adding an in-dashboard AI agent across webapp and SDK.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dashboard-agent-scaffold

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

Self-hosted containers now apply the trigger_dashboard_agent schema migrations
on startup, alongside the Prisma and ClickHouse migrations, via a small runtime
migrator (drizzle-orm over the committed SQL, no drizzle-kit in the image). A new
SKIP_DASHBOARD_AGENT_MIGRATIONS flag lets deployments that apply migrations out of
band opt out.
coderabbitai[bot]

This comment was marked as resolved.

The dashboard agent now creates chat sessions server-side: the server
generates the chat id and owns the chat record (bound to the user and org),
and only issues a session token for a chat the requesting user owns. A new
chat opens in a draft composer; the first message creates the session via
chat.startHeadStart, so the client never chooses the id.

Also hardens the repo-read tools with collision-resistant workspace keys and
a realpath guard against symlink escapes.
@ericallam ericallam force-pushed the feat/dashboard-agent-scaffold branch from 0d6821e to 8a37eda Compare June 24, 2026 15:48
@pkg-pr-new

pkg-pr-new Bot commented Jun 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@trigger.dev/build

npm i https://pkg.pr.new/@trigger.dev/build@13ec864

trigger.dev

npm i https://pkg.pr.new/trigger.dev@13ec864

@trigger.dev/core

npm i https://pkg.pr.new/@trigger.dev/core@13ec864

@trigger.dev/python

npm i https://pkg.pr.new/@trigger.dev/python@13ec864

@trigger.dev/react-hooks

npm i https://pkg.pr.new/@trigger.dev/react-hooks@13ec864

@trigger.dev/redis-worker

npm i https://pkg.pr.new/@trigger.dev/redis-worker@13ec864

@trigger.dev/rsc

npm i https://pkg.pr.new/@trigger.dev/rsc@13ec864

@trigger.dev/schema-to-json

npm i https://pkg.pr.new/@trigger.dev/schema-to-json@13ec864

@trigger.dev/sdk

npm i https://pkg.pr.new/@trigger.dev/sdk@13ec864

commit: 13ec864

@ericallam ericallam marked this pull request as ready for review June 24, 2026 15:56
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

- Log head-start warm-step failures instead of swallowing them, so a failed
  first turn is visible in the server logs.
- Guard the new-chat create against stale responses so a slow create can't
  replace a chat the user just switched to.
- Scope the chat ownership check by organization, not just by user.
- Clear the head start idle timer on the warm-step failure path (it was only
  cleared on the success path).
@ericallam ericallam merged commit c06005b into main Jun 24, 2026
68 checks passed
@ericallam ericallam deleted the feat/dashboard-agent-scaffold branch June 24, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants