feat(webapp): dashboard agent — chat, reports, Investigate, Watch - #4418
feat(webapp): dashboard agent — chat, reports, Investigate, Watch#4418kathiekiwi wants to merge 387 commits into
Conversation
… the docs button A card's watch button now sends a visible request the agent answers with schedule_watch — the transcript shows what was asked, the agent confirms, and the email-alert offer applies. Docs footer entries render as the docs button whatever shape their link arrived in; cited references keep a link via a status-page fallback.
…tions state the lifetime The chat's watch list now includes fired/expired watches (chips still filter to active), so a wake banner can tell good news from bad instead of falling back to the neutral wording. The agent's watch confirmation must now always say it fires once and exactly when it gives up.
…ved slot Every chat row keeps the leading slot so titles align; watching spins like thinking (the hover title says which) and the short status text stays on hover.
…n through The endpoints require chatId (the same chat-scoped floor watch creation uses); the tools sent none and every call died as a 400.
…umber in one column The throughput label now sits vertically centered against its value+breakdown stack, and 842/830 start on the same vertical as +12/min and the other rows' values; sub labels follow their numbers.
…s, UI map, hands-on walkthrough
…aks plainly One conversational message with the watch's note, a lime CTA, and the same skeleton as the billing-limit email; the fielded fact sheet is gone and the unsubscribe link keeps its wiring with footer styling.
…d to mid-column, number in the value column
'Watch update — all clear / needs your attention', toned by kind; the identity moves to the details line and the subject follows suit.
…with starred scenarios
🦋 Changeset detectedLatest commit: 4ff8859 The changes in this PR will be included in the next version bump. This PR includes changesets to release 27 packages
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 |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds a Dashboard Agent feature set. It introduces a contracts package for shared schemas (view blocks, intents, page context, watches, trigger:// URIs), a dedicated database package for chats, investigations, and watches, and core agent tool/prompt logic. It adds a watch-tick lifecycle with checks, alerts (email, Slack, webhook), and unsubscribe flows. It adds API routes for watches, alerts, queue metrics, and run diagnostics. It redesigns the chat panel UI with investigation, report, and watch cards, suggested prompts, and unread-wake notifications. It adds a Storybook demo gallery with screenshot tooling, seed scripts, and removes "Docs" links from page headers across the webapp. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
…t button; URLs are links The prompt now treats earlier turns' pages as history — deictic questions re-read the current page every turn, and page explanations end with a matching docs link. The report's contact action falls back to the contact page as a real external button instead of an ask round-trip, and answers that point at a URL carry it as a link.
…ress line, wake toast opens its chat as an agent Callout - navigate intents and navigate_to outputs resolve trigger:// URIs server-side and navigate in place; same-origin citation buttons navigate instead of opening a new tab. - The transcript autoscrolls on send and follows streaming near the bottom; a store-order stable merge stops messages landing mid-chat after a page change (server-side single-read follow-up noted). - The generic Working line yields to a tool-specific one. - The wake toast is the new agent Callout variant (chat icon) and opens the exact chat that woke.
…nside the label column
An in-flight tool call now shows a compact pill (per-tool phrase + spinner, watch-chip visual language) instead of raw streaming JSON — covering render_view and get_report, the biggest offenders. Completed and error states render as before; gallery in-flight examples reworked and a pill line-up section added.
The answer is the prose and the cards, never the input/output plumbing: a landed call disappears (the pill was its only trace), and only a FAILED call keeps its error row. Gallery example reworked accordingly.
Wakes are wake-shaped (banner renders), no prose points at tool rows that no longer render, footer-era phrasing removed, the four-wake variation matrix became one coherent story, and tests now enforce all of it (wake ids parse via the real WakeBanner, removed-UI phrases are banned).
Offering to fetch what a tool can fetch now is banned; 'how do I check X' about the user's project gets both the how-to and the actual check; only genuinely unreachable steps (their infra, their code, external pages) go to the user, clearly separated.
…flows # Conflicts: # .changeset/report-health.md # .server-changes/agent-detail-metrics-layout.md # .server-changes/paginate-concurrency-keys-table.md # .server-changes/queue-metrics-dashboard.md # apps/webapp/app/components/dashboard-agent/AgentChart.tsx # apps/webapp/app/components/metrics/MiniLineChart.tsx # apps/webapp/app/components/query/QueryEditor.tsx # apps/webapp/app/env.server.ts # apps/webapp/app/hooks/useMetricResourceQuery.ts # apps/webapp/app/presenters/v3/QueueListPresenter.server.ts # apps/webapp/app/presenters/v3/QueueMetricsPresenter.server.ts # apps/webapp/app/presenters/v3/RunQueueMetricsPresenter.server.ts # apps/webapp/app/presenters/v3/reports/health/health-data.ts # apps/webapp/app/presenters/v3/reports/health/health-messages.ts # apps/webapp/app/presenters/v3/reports/health/health.ts # apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/ExamplesContent.tsx # apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/TableSchemaContent.tsx # apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx # apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues_.$queueParam/route.tsx # apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.standard.$taskParam/route.tsx # apps/webapp/app/routes/api.v1.query.schema.ts # apps/webapp/app/routes/resources.metric.tsx # apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query.ai-generate.tsx # apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx # apps/webapp/app/routes/resources.queues.concurrency-keys.ts # apps/webapp/app/services/queryService.server.ts # apps/webapp/app/v3/querySchemas.ts # apps/webapp/app/v3/queueMetrics.server.ts # apps/webapp/test/reportHealth.test.ts # internal-packages/clickhouse/src/client/tsql.ts # internal-packages/run-engine/src/engine/systems/enqueueSystem.ts # internal-packages/tsql/src/query/schema.ts
@trigger.dev/build
trigger.dev
@trigger.dev/core
@trigger.dev/python
@trigger.dev/react-hooks
@trigger.dev/redis-worker
@trigger.dev/rsc
@trigger.dev/schema-to-json
@trigger.dev/sdk
commit: |
The table is append-only quality data with no reader, so the sweep now drops rows past the period in one bounded statement per run.
…and the judge Payloads, outputs, query rows and file contents are replaced by their shape before a turn reaches the judge, and the row now keeps the derived verdict only.
A per-org feature flag the agent checks before every judged turn, and a turn is judged only on an explicit yes.
The CI lane reads its own variable and defaults to every turn, so neither lane can change the other's rate.
The docs claimed every turn is judged; the sampled rate, the redaction rule, the code-mode skip, the opt-out and the retention period are now written down in one place.
…ponsibility tools.ts now only assembles ready adapters, in the same frozen key order: the HTTP/JWT client, result curation, the docs client, the source-read ledger, evidence canonicalisation, investigation persistence, and the api/navigation/ watch/alert tool groups each own their own module. A pure move. The prompt-prefix fingerprints are unchanged, which is what keeps the head-start and agent prefixes byte-identical.
…ion, batch and adapters watch-tick.ts keeps the two task definitions and the per-watch check; the wake delivery, the condition lifecycle, the group tick and the db/session/callback adapters each move to their own module. A pure move: watch-tick.ts re-exports everything it exported before.
dashboardAgentWatchChecks.ts keeps the dispatcher, the failure envelope and the previous-facts reader, and re-exports the run, queue, error and health families plus the shared reader contract. A pure move; every import path is unchanged.
The chip factory and slot vocabulary, the evergreen docs chips, the per-page slot table and the signal chips each get their own module; registry.ts is now the public face that re-exports them. A pure move.
…ive investigations and watches
…d a committed snapshot
…nd narrate the rest with Haiku
…tead of passing it to the judge
…ing it The batch took the 500 soonest-expiring watches of a group every tick, so a group larger than the cap could leave the rest unchecked until the first 500 expired. The group is now ordered least-recently-checked first, with a generated cadence_minutes column and an index so the due predicate no longer re-parses the spec JSON per tick.
…e watch The page load reported unread wakes only, so a fresh browser whose watch was created elsewhere and hasn't fired yet never started polling: the wake landed without a toast or a dot until a reload. The loader now returns the active-watch presence too, in one read per page load.
The message-size checks ran after the body had been read, so a request without a content-length was buffered and parsed in full before being refused. An ingress cap on the agent's paths now counts the bytes as they arrive, and the chat proxy reads its body with a ceiling instead of reading it whole first.
…ir a retried submit
…ts refusal record
An AI assistant in a side panel on every dashboard page, behind the dashboard-agent feature flag. It reads runs, errors, queues, deploys and health through the public API (read-only, delegated user token), answers with rich cards, and can keep watching things after the conversation ends.
What's inside
@internal/dashboard-agent-contracts(trigger:// URI grammar, intents, watch specs, block envelope), investigations + watches tables, head-start reliability fix, eval sample-rate gate.get_reportrenders the deterministic health report as a card (metric grid, sparklines, Next steps button row); stale telemetry is flagged and never trusted for advice.db:seed:agent-examples, with--heartbeat/--degrade/--recoverfor demos).How to review
GUIDEBOOK.md — 10-minute local setup and a hands-on walkthrough of every case.
Notes
canAccessDashboardAgent; no behavior change with the flag off.