Skip to content

feat(webapp): dashboard agent — Watch - #4525

Open
kathiekiwi wants to merge 81 commits into
feat/dashboard-agent-uifrom
feat/dashboard-agent-flows-watch
Open

feat(webapp): dashboard agent — Watch#4525
kathiekiwi wants to merge 81 commits into
feat/dashboard-agent-uifrom
feat/dashboard-agent-flows-watch

Conversation

@kathiekiwi

@kathiekiwi kathiekiwi commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #4529, which is stacked on #4418. Merge those first.

Watch is the agent noticing something later: you ask it to tell you when a condition holds, and it answers when it does — or when it can't any more.

What's inside

  • Watches — condition, cadence and window, evaluated by a cron; one identity per chat so a repeat ask doesn't create a second watch.
  • Delivery — in-chat card, email alert, and the investigation that runs when a watch fires.
  • Submissions — a durable ledger keyed by (chatId, clientRequestId), so a retried submission replays instead of duplicating.
  • Watch token — a dedicated delayed-execution credential, accepted only by the watch endpoints and re-checked against the user's live access on every tick.

How to review

GUIDEBOOK.md — local setup and a walkthrough of all 15 scenarios.

@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: de84db5

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

This PR includes changesets to release 27 packages
Name Type
@trigger.dev/core Patch
@trigger.dev/build Patch
trigger.dev Patch
@trigger.dev/python Patch
@trigger.dev/redis-worker Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@internal/cache Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/metrics-pipeline Patch
@trigger.dev/rbac Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/run-store Patch
@internal/schedule-engine Patch
@trigger.dev/sso Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/tsql Patch
@internal/dashboard-agent Patch
@internal/sdk-compat-tests Patch
@trigger.dev/react-hooks Patch
@trigger.dev/rsc Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer 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 Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6abb179d-e022-43e6-9c90-cf6ef1b1cfc4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Added watch creation and configuration for runs, queues, errors, and health reports. Added scheduled checks, lifecycle handling, wake notifications, automatic investigations, unread tracking, and cross-browser activity polling. Added email, Slack, and webhook alert delivery with subscription management. Added dashboard-agent tools, APIs, persistence, worker tasks, scenario tooling, documentation, and extensive unit and integration coverage.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the Watch feature and review guide but omits the required issue, checklist, testing, changelog, and screenshots sections. Complete the repository template by adding the issue reference, checklist, testing steps, changelog entry, and screenshots or an explicit not-applicable note.
Docstring Coverage ⚠️ Warning Docstring coverage is 64.71% 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 clearly identifies the main change: adding the dashboard agent Watch feature.
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.
✨ Finishing Touches 💡 1
📝 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-flows-watch

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.

@kathiekiwi
kathiekiwi marked this pull request as ready for review August 7, 2026 10:20
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@kathiekiwi
kathiekiwi changed the base branch from feat/dashboard-agent-flows to feat/dashboard-agent-ui August 7, 2026 12:43
@pkg-pr-new

pkg-pr-new Bot commented Aug 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

@trigger.dev/build

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

trigger.dev

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

@trigger.dev/core

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

@trigger.dev/python

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

@trigger.dev/react-hooks

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

@trigger.dev/redis-worker

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

@trigger.dev/rsc

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

@trigger.dev/schema-to-json

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

@trigger.dev/sdk

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

commit: e954d82

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Observability map

As of de84db5.

20/100 over 424 measured of 440 entry points (base 19, up 1)

What this PR changed

route base head now failing
/api/v1/dashboard-agent/watches/:watchId/check (suppressed: error-classification) new 50

FIX FIRST

  • /api/v1/projects/:projectRef/envvars (sensitive) - auth-boundary, request-context
  • /auth/sso (sensitive) - auth-boundary, request-context
  • /_app/orgs/:organizationSlug/settings/team (sensitive) - error-classification, auth-scope, request-context

AUDIT 3 of 50 sensitive mutations record an actor. 47 without one.
CONTEXT 21 of 424 entry points name a tenant on a failure path. 324 appear only here, 39 of them sensitive, in the JSON rather than the fix list.

What the score is made of
CHECKS
  error-classification  177 applicable, 101 pass,   0 sole, global without it 12
  auth-boundary          62 applicable,  57 pass,   0 sole, global without it 17
  auth-scope             19 applicable,  17 pass,   0 sole, global without it 20
  request-context       424 applicable,  21 pass, 225 sole, global without it 64
  audit-trail            50 applicable,   3 pass,   0 sole, not in the score

The score and findings here are report-only and never gate the merge. Separately, a required test suite keeps this tool's symbol and route lists in sync with the code they name, and can fail a pull request that renames or removes a symbol they reference, or that adds the first route with a segment they anticipate. Each failure names the list to edit. The rules and their reasons: internal-packages/observability-map/README.md.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@kathiekiwi
kathiekiwi force-pushed the feat/dashboard-agent-flows-watch branch from 712396b to e110e90 Compare August 8, 2026 12:05
@kathiekiwi
kathiekiwi force-pushed the feat/dashboard-agent-ui branch from bd4d4a0 to 887f5b6 Compare August 8, 2026 12:05
@kathiekiwi
kathiekiwi force-pushed the feat/dashboard-agent-flows-watch branch from c0f0058 to e7432a8 Compare August 8, 2026 14:30
@kathiekiwi
kathiekiwi force-pushed the feat/dashboard-agent-ui branch from 887f5b6 to 17a0f07 Compare August 8, 2026 14:30
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

coderabbitai[bot]

This comment was marked as resolved.

kathiekiwi and others added 21 commits August 9, 2026 14:51
…that isn't there

The queue's live row read collapsed every non-ok response into "no live row",
so a 401, a 429 or a 5xx reached the model as exists:false — the queue does not
exist. Only a 404 is evidence of absence now; anything else reports
exists:"unknown" with the status, and the prompt says unknown is never missing.
The wake poll's callback closed over `open` from the render that started it, so
once the panel opened the subtraction never applied. The panel's open state now
goes through a ref, like the visible chat already does, rather than adding
`open` to the effect's deps and restarting the poll on every open and close.
…watch

A watch can expire or be cancelled with nothing written back into the
transcript, so asking the summariser for "any watch that is running" preserved
an old confirmation as current state.
The guard compared a slice against its own start, so it could not fail. Move
the decision into takeNavigateIntent and drive it across two commits instead.
The unmount case repeated its neighbour and no query string can reach
unmountTeardown. Guard the pathname tracking that does decide it.
…token

pk_ is browser-shipped and environment-bound. Nothing routes it to the query
API today, so the cap costs no caller anything and the helper stops promising
the wrong thing.
The seeder and its `scenarios:watch` script were only ever a way to reproduce a
watch condition by hand. The guidebook now states the conditions themselves, so
there is nothing left for the kit to be the answer to.
…oduce it

The guidebook was a walkthrough of the scenario kit: a command, some clicks, and
the sentence that came back. It is now a reference of conditions, derived from
the checks rather than from the old prose, so a reader can predict an outcome
without running anything.

Corrects, among others: the queue Investigate rule (a zero or unset concurrency
limit is never saturation), the run-panel Investigate rule (it needs an error
block as well as a failed status), the claim that a backed-up queue never offers
an investigate chip (the page registry offers both), and the claim that every
wake is an LLM call (only attention outcomes and consented investigations are).
…lable checks

- 0003 catches the last_read_at backfill up on databases where 0002 already ran.
- The per-watch check endpoint records a look, not a check, when it read nothing.
- A suggested prompt is consumed once it is sent, not when it is clicked.
- Closing the panel settles the launcher dot instead of waiting for the poll.
- Say why the oldest-age reader's 50-key page cannot under-report.
- Suppress error-classification on the check route, with the reason on the record.
…een, and let an admin preview's watches alert

The launcher's work count is now taken with the chat the panel has on screen
left out — in the panel's own list and in the poll's server-side count alike —
instead of subtracting one afterwards, which under-counted whenever that chat
held nothing unseen and left a stale count on the closing edge.

The alert gate stopped deciding the admin preview differently from the agent's
own gate: `canAccessDashboardAgent` reads `admin` off the user row when the
caller has no session, so a watch an admin could create can still alert.

A `run_start` watch now offers the same Customize variants as the rest of its
family.
…it up

navigateIntentApplies documents startedPath: null as 'this tab never saw the turn start', but
the path was inferred from the turn going in flight - and a resumed turn goes in flight too, so
the tab stamped wherever it happened to be and the rule always matched. Stamp the path where a
turn is actually started instead, which leaves it null for a turn this tab only resumed.
@kathiekiwi
kathiekiwi force-pushed the feat/dashboard-agent-flows-watch branch from 004f088 to e954d82 Compare August 9, 2026 14:53

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 new potential issues.

Open in Devin Review

Comment thread apps/webapp/app/services/dashboardAgentWatches.server.ts
Comment thread apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx
Comment thread apps/webapp/app/services/dashboardAgentWatchChecks.server.ts
…ge context

A retry that adopts a watch which has already fired or expired now confirms
what the watch found instead of claiming it is still watching.

The queue page hands the agent the stored queue name, so a queue watch it
proposes validates instead of being rejected as a missing target.
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.

1 participant