Commit Graph

7815 Commits

Author SHA1 Message Date
Katia Bulatova 6b0484ef0b fix(webapp): merge the duplicated pause-button className from the queue-metrics merge
📦 Preview packages (pkg.pr.new) / Build and publish previews (push) Has been cancelled
2026-07-27 07:54:11 +00:00
Katia Bulatova 41bd30cb4b Merge branch 'feat/queue-metrics-and-health' into feat/light-theme
# Conflicts:
#	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
2026-07-27 07:49:21 +00:00
Katia Bulatova 76e3062b77 Merge remote-tracking branch 'origin/main' into feat/queue-metrics-and-health
# Conflicts:
#	apps/webapp/app/v3/services/worker/workerGroupTokenService.server.ts
2026-07-27 07:45:40 +00:00
Katia Bulatova 57ceb984af feat(webapp): new Dark theme is the default with a slight contrast bump
Missing or legacy preferences resolve to the pinned Dark theme (not
system-resolved, so nobody is surprised by light mode) and the default
contrast is 50. Classic remains the flag-off look.
2026-07-27 06:57:36 +00:00
Eric Allam d3906241a5 feat(webapp): read realtime run rows from the primary, not the replica (#4378)
🦋 Changesets PR / Create Release PR (push) Has been cancelled
🚀 Publish Trigger.dev Docker / 📣 Dispatch main image (push) Has been cancelled
🚀 Publish Trigger.dev Docker / typecheck (push) Failing after 2s
🚀 Publish Trigger.dev Docker / units (push) Failing after 2s
🚀 Publish Trigger.dev Docker / publish-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / publish-worker-v4 (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-supervisor (push) Has been skipped
## Summary

The realtime runs feed hydrates run rows from read replicas, which means
it needs a replica-lag gate to avoid serving a run's previous state
right after a write. Setting
`REALTIME_BACKEND_NATIVE_RUN_READS_FROM_PRIMARY=1` reads those rows from
each run store's primary instead, so there is no lag to gate against: no
probe, no wake delay, no stale-read retries. Off by default, so nothing
changes unless you set it.

## Design

The run stores already decide replica-vs-primary from the *brand* on the
read client they are handed: a branded replica keeps the read on the
owning store's replica, an unbranded writer escalates it to that store's
own primary. So this is a one-line choice at the hydrator, and it stays
correct across topologies. With the run-ops split on, each leg lands on
its own writer and the caller's client is never forwarded across
databases; with the split off, it is the single database's primary.

```ts
const runReader = new RunHydrator({
  readClient: runReadsFromPrimary ? prisma : $replica,
  runStore,
});
```

The same flag skips constructing the lag estimator, since probing a
replica the feed no longer reads would be measuring the wrong thing.

Independently, `AuroraReplicaLagSource` detected Aurora by letting
`aurora_replica_status()` fail, on the assumption that the app-level
catch made that free. It isn't: an unresolvable function is a query
error the driver reports to the error log on every sample, so a
non-Aurora replica produced a continuous stream of error events while
the estimator quietly fell through to its next candidate. It now
resolves the function with `to_regproc` and memoizes the answer, so the
unparseable call never reaches the wire.
2026-07-26 19:43:41 +01:00
James Ritchie a585deab55 Queue metrics & health: UI polish (TRI-12068) (#4354)
**Stacked on #4131** — targets `feat/queue-metrics-and-health`, not
`main`. GitHub will auto-retarget this to `main` once #4131 merges.
(Targeting `main` now would wrongly include all of #4131's own commits.)

UI polish for the Queue metrics & health pages (TRI-12068). 49 commits,
all under `apps/webapp/app/` — no engine/ClickHouse/package changes.

**Highlights**
- **Layout** — consolidated queue-detail header into one filter bar;
shared `MetricsLayout` spacing (2.5 scale); paused-queue banner
mirroring the environment-paused banner.
- **Charts** — inline legends under titles; threshold gradient coloring
(Env saturation orange only >100%; Concurrency orange only at/over the
limit); fullscreen legend spacing; result caching so tab switches don't
reload; brighter hover cursor + full x-axis labels.
- **Tables** — whole-row click via stretched link; custom Queues icon;
removed column sorting; Limit-cell spacing + hover-bright; "Limited by"
tooltip sizing.
- **Controls** — Pause moved into the filter bar (orange label +
accurate tooltip copy); restyled override-concurrency modal.
- **Copy** — plain-language pass; inline colour swatches; Throttled
reads "% of current period".

Also consolidated the three queue-metrics `.server-changes` notes into
one.

**Known follow-up (not in this PR):** the Concurrency-keys table is
capped at 50 keys (union of live Redis backlog + ClickHouse history, no
single cursor across both) and truncates silently — fine for most
queues, a real limit for high-cardinality per-tenant keys.

Verified locally against the `queue-metrics-demo` seed; `pnpm typecheck
--filter webapp` passes.
2026-07-24 16:18:44 +01:00
Matt Aitken be45cf9e61 fix(sdk): preserve partial assistant message on chat stream failure (#4348)
🚀 Publish Trigger.dev Docker / typecheck (push) Failing after 5s
🚀 Publish Trigger.dev Docker / units (push) Failing after 5s
🚀 Publish Trigger.dev Docker / publish-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / publish-worker-v4 (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-supervisor (push) Has been skipped
🦋 Changesets PR / Create Release PR (push) Has been cancelled
🚀 Publish Trigger.dev Docker / 📣 Dispatch main image (push) Has been cancelled
⚒️ Publish Worker (v4) / build (supervisor) (push) Has been cancelled
## Summary

When a `chat.agent` (or `chat.createSession`) turn's model stream fails
mid-response (e.g. a transport timeout like `UND_ERR_BODY_TIMEOUT`), the
assistant output that already streamed was dropped: `onTurnComplete`
fired with `responseMessage: undefined`, and the manual loop's
`turn.complete()` rethrew without keeping the partial. Apps that
register `hydrateMessages` are hit hardest, since boot-time tail-replay
recovery is off by design.

This preserves the streamed-so-far assistant output while still
reporting the turn as errored, so persistence and recovery keep it.

## Scope of behavior change

Only the **error path** changes. Successful turns are unaffected: the
same chunks stream to the client in the same order, and
backpressure/cancel behave as before. Everything here is a correctness
improvement on a turn that hit a source-stream failure.

## What it does

Follow-up to #4304 (`chat.pipeAndCapture`), extending the same
partial-recovery to the two loops that lacked it:

- **`chat.agent`**: taps the response stream (via a `TransformStream`,
so pass-through backpressure and cancel are preserved) to buffer chunks,
and on a source-stream failure reconstructs the partial (preferring the
`onFinish` message). It's surfaced on the error-path `onTurnComplete`
(`responseMessage`, `rawResponseMessage`, `uiMessages`, `newUIMessages`,
`newMessages`) and committed to the accumulator so the next turn and the
reboot snapshot keep it.
- **`chat.createSession` / `turn.complete()`**: the reconstructed
partial is accumulated (so `turn.uiMessages` reflects it and the caller
can persist after catching) before `turn.complete()` rethrows.

`onBeforeTurnComplete` stays skipped on the error path (it hands out a
writer for a stream that has already broken).

## Correctness properties (each covered by a regression test)

Each test below was confirmed to fail without its fix:

- The recovered partial reaches `onTurnComplete` and the next turn's
accumulated messages.
- An already-committed (possibly enriched) response is not overwritten
if a post-response hook then throws.
- Incomplete tool parts are cleaned from the recovered partial (text
kept), so the UI and model views agree and the next turn isn't poisoned.
- A prior turn's model-only compaction survives an errored turn (append
only the new tail, don't reconvert the full history).
- A reconstructed fragment that reuses an existing message id does not
clobber the complete message.
- Queued `chat.response` data parts are folded into the recovered
partial, matching the success path.
- `newMessages` (model delta) stays symmetric with `newUIMessages`.

## Tests

New `chat-agent-source-stream-error.test.ts` covers the cases above. The
full `@trigger.dev/sdk` unit suite passes and the package build is green
across all supported runtimes (Node 20 to 26, Bun, Deno, Cloudflare
Workers).
re2-prod-supervisor-dispatch-url
2026-07-24 14:20:20 +01:00
claude[bot] 109e245d56 feat(webapp): show the first and last characters of a new PAT (#4363) 2026-07-24 12:55:31 +01:00
nicktrn bf41c5d5fc feat(supervisor): configurable warm-start dispatch url (#4362)
Adds an optional `TRIGGER_WARM_START_DISPATCH_URL`. The warm-start
dispatch request uses it when set, otherwise falls back to
`TRIGGER_WARM_START_URL`, so the dispatch target can differ from the
default warm-start URL. No behavior change when unset.
2026-07-24 12:11:55 +01:00
Eric Allam 7188eecd83 perf(webapp): clamp list-endpoint page size to 100 (#4360)
## Summary

Several list endpoints accepted an unbounded page size (`perPage` /
`per_page` / `pageSize`). An unbounded page lets one request pull an
arbitrarily large result set and do a proportional amount of work, which
is a poor default for a shared API.

This clamps the page size to 100 on every list endpoint that was
uncapped, matching the existing cap on `api.v1.runs` and
`api.v1.sessions`. Clamping rather than rejecting keeps existing clients
working: a request for a larger page returns up to 100 items and offset
pagination continues from there.

## Endpoints capped

- `api.v1.schedules` (`perPage`)
- `api.v1.queues` (`perPage`)
- `resources.…versions` (`per_page`)
- `resources.…queues` (`per_page`)
- `admin.api.v1.…engine.report` (`per_page`)
- `admin.api.v1.llm-models` (`pageSize`)

Already capped, left as-is: `api.v1.runs`, `api.v1.sessions`,
`api.v1.deployments`.
2026-07-24 11:56:58 +01:00
Eric Allam 9c85e0ecdc perf(database): index BatchTaskRun on (runtimeEnvironmentId, createdAt, id) for the batches list (#4361)
## Summary

The batches list page orders by `createdAt DESC, id DESC` filtered by
environment and a created-at window, but the only supporting index on
`BatchTaskRun` was `(runtimeEnvironmentId, id)`. That index can't
satisfy the `createdAt` ordering, so on environments with a large number
of batches the query fell back to a full table scan and in-memory sort,
which could run long enough to hit the statement timeout.

## Fix

Adds `(runtimeEnvironmentId, createdAt DESC, id DESC)` on
`BatchTaskRun`. The query now reads straight from the index in order
with no sort step, returning a page with only a handful of heap fetches
instead of scanning the whole environment slice.

The migration uses `CREATE INDEX CONCURRENTLY IF NOT EXISTS`, so it
takes no table lock and is a no-op if the index already exists.
2026-07-24 11:52:34 +01:00
Katia Bulatova 33a5415ffa Merge branch 'feat/system-preference-theme' into feat/light-theme
📦 Preview packages (pkg.pr.new) / Build and publish previews (push) Has been cancelled
# Conflicts:
#	apps/webapp/app/routes/account._index/route.tsx
2026-07-23 21:59:53 +00:00
Katia Bulatova 62c3d4f4b6 revert(webapp): onboarding screenshots stay dark in every theme 2026-07-23 21:59:06 +00:00
Katia Bulatova 27172a1fd0 fix(webapp): error screen keeps the dark animation, text stays readable on light 2026-07-23 21:29:06 +00:00
Katia Bulatova 62f38ae420 feat(webapp): close the light-theme gaps from the final audit
📦 Preview packages (pkg.pr.new) / Build and publish previews (push) Has been cancelled
Error boundary backdrop, prompt override editor pane, AI filter error
popover and chart-zoom tooltip get light: styling; standalone white
spinners go blue; bulk-action onboarding, blank-state and queues-upgrade
screenshots ship light variants (lightness-inverted, optimized).
2026-07-23 21:20:24 +00:00
Katia Bulatova d52c68a15d feat(webapp): light blurred backdrop for the new-organization page
Light variants generated from the dark screenshots by inverting lightness
(hues survive, so the accent smudges stay true); optimized progressive
JPEGs at a fraction of the original size.
2026-07-23 21:05:56 +00:00
Katia Bulatova d8ce6d4af8 fix(webapp): logged-out pages stay on the branded Classic look 2026-07-23 21:00:32 +00:00
Katia Bulatova b8813ceac6 fix(webapp): hide the dark dashboard backdrop on the light theme
The new-org background is built from dark-dashboard screenshots (plus a
hardcoded near-black fill); the light theme falls back to a flat surface.
2026-07-23 21:00:09 +00:00
Katia Bulatova 48f75c5d8f feat(webapp): logged-out pages follow the OS appearance
Login, invites and other anonymous pages resolve the System preference
when the theme switcher flag is on; Classic stays the flag-off default.
The invites heading goes monochrome in System themes.
2026-07-23 20:50:05 +00:00
Katia Bulatova 8b64da96a8 Merge remote-tracking branch 'origin/main' into feat/light-theme
📦 Preview packages (pkg.pr.new) / Build and publish previews (push) Has been cancelled
2026-07-23 20:46:52 +00:00
Katia Bulatova 2fada02401 fix(webapp): stronger contrast slider thumb definition 2026-07-23 20:33:52 +00:00
Katia Bulatova 4719b7a5b7 fix(webapp): contrast slider thumb reuses the secondary button shadow 2026-07-23 20:32:52 +00:00
Katia Bulatova b41d0de533 fix(webapp): contrast slider thumb visible on the light track 2026-07-23 20:32:02 +00:00
Katia Bulatova c376521121 fix(webapp): pinned theme applies immediately after leaving system preference
React skips the data-theme write when its virtual DOM already matched the
SSR fallback while the inline script had flipped the real attribute; the
sync hook now writes pinned themes explicitly.
2026-07-23 20:30:57 +00:00
Katia Bulatova 447a6634e1 feat(webapp): contrast slider thumb matches the switch thumb 2026-07-23 20:29:46 +00:00
Katia Bulatova 1db252c434 feat(webapp): borderless solid thumb on the contrast slider 2026-07-23 20:17:30 +00:00
Katia Bulatova 3f3c24054d feat(webapp): borderless contrast slider thumb; release note covers the contrast slider 2026-07-23 20:16:53 +00:00
Katia Bulatova 7c548ea562 feat(webapp): quiet slider variant for the contrast setting 2026-07-23 19:31:29 +00:00
nicktrn 722e240e4d feat(supervisor): add prometheus metric for outbound http requests (#4350)
🚀 Publish Trigger.dev Docker / typecheck (push) Failing after 5s
🚀 Publish Trigger.dev Docker / publish-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / publish-worker-v4 (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-webapp (push) Has been skipped
🚀 Publish Trigger.dev Docker / scan-supervisor (push) Has been skipped
🚀 Publish Trigger.dev Docker / units (push) Failing after 6s
🦋 Changesets PR / Create Release PR (push) Has been cancelled
🚀 Publish Trigger.dev Docker / 📣 Dispatch main image (push) Has been cancelled
Adds Prometheus metrics so the supervisor's outbound HTTP calls are
observable - including client-side failures that previously only
surfaced as a log line.

- `supervisor_outbound_request_total{name, method, status, outcome}` -
counts every outbound request. `outcome` separates a transport failure
(`network_error`), an HTTP error response (`http_error`), a response
that failed schema validation (`invalid_response`), and success (`ok`).
- `supervisor_outbound_request_duration_seconds{name, outcome}` -
latency histogram. Leaner labels than the counter (no `status`) to avoid
bucket×label cardinality; buckets match the existing dequeue-latency
histogram since these calls share the same retrying HTTP client and
long-poll envelope.

Coverage:
- The warm-start request (a one-off `fetch`) - instrumented inline; the
response status code is now also included in the failure log (it was
previously dropped).
- All worker API client calls (`SupervisorHttpClient`: dequeue, run
attempt start/complete, heartbeats, snapshots, continue, suspend,
debug-log, connect) - routed through a single instrumented `request()`
helper that reports via an optional `onHttpRequestComplete` callback on
the client, which the supervisor wires into the counter + histogram.

Low cardinality by design: `name` is a **static per-endpoint label**
(e.g. `dequeue`, `start_run_attempt`), never the interpolated URL - so
no run/snapshot IDs land in labels, mirroring the templated `route`
labels on the inbound HTTP server.

Registered on the existing metrics registry, exposed on `/metrics` with
no new wiring. Internal-only change (no package release needed), so the
changelog note is a single `.server-changes` entry.
2026-07-23 18:18:58 +01:00
Katia Bulatova 17d1a7c07b fix(webapp): chips gain a currentColor ring with contrast instead of a washing filter 2026-07-23 17:14:14 +00:00
Katia Bulatova ae288da560 feat(webapp): tinted status chips respond to the contrast control
Shared contrast-chip marker on error/health/pill/source/connection chips
and subtle badges; a contrast+saturate filter driven by --theme-contrast
separates the tint and its colored text.
2026-07-23 17:13:13 +00:00
Katia Bulatova ffa3b52401 fix(webapp): light-mode contrast pushes foregrounds, not backgrounds
Whites can't get whiter: dimmed/faint text goes near-black, borders and
controls darken hard, deep surfaces dip slightly for panel separation.
2026-07-23 16:48:58 +00:00
Katia Bulatova fc2b65fa45 feat(webapp): contrast overlay covers the full monochrome scale
Backgrounds deepen (dark) or lift (light), surfaces and all border steps
strengthen, text weights increase - task names and dimmed labels now respond
visibly to the slider in both modes.
2026-07-23 16:46:05 +00:00
Katia Bulatova 06890660cd feat(webapp): interface contrast slider for the System themes
New contrast preference (0-100) stored in dashboard preferences, applied
as a --theme-contrast variable on <html>. The System theme blocks pull the
monochrome scale apart via color-mix - text toward the mode foreground,
borders a step up; contrast 0 stays byte-identical and Classic never reads
the variable. The account page shows the slider under Theme for non-Classic
themes with live preview.
2026-07-23 15:59:30 +00:00
Katia Bulatova ff1b3de510 feat(webapp): lighter grey chart reference series in System themes 2026-07-23 15:17:57 +00:00
Katia Bulatova 3e7d5e30c9 fix(webapp): transparent query toolbar background on light 2026-07-23 15:03:18 +00:00
Katia Bulatova 91f98a1391 fix(webapp): private connection chips match the default style; white label on blue timeline bars in light 2026-07-23 15:02:41 +00:00
Katia Bulatova 38ad17044f fix(webapp): query editor toolbar sits on white in the light theme 2026-07-23 14:44:48 +00:00
Katia Bulatova 9b6424e82e feat(webapp): prompt override Remove becomes an outlined secondary button 2026-07-23 14:44:06 +00:00
Katia Bulatova 7b03086db7 feat(webapp): centered add-connection button; secondary Remove on prompt override; select crash guard
Private connections list places Add Connection under the list; the prompt
override Remove becomes an outlined secondary next to the filled Edit; the
Select section probe no longer crashes on an empty filtered list.
2026-07-23 14:43:15 +00:00
Katia Bulatova 819420bec4 feat(webapp): quota source badges join the tinted chip style 2026-07-23 14:38:32 +00:00
Katia Bulatova 5bc364b55f feat(webapp): limits pills and source badges match the errors chip style 2026-07-23 14:35:09 +00:00
Katia Bulatova 44ab5b052e feat(webapp): queue health chips match the error status chip style and size 2026-07-23 14:27:49 +00:00
Katia Bulatova 80321c134f fix(webapp): filled buttons keep their fill on hover and darken
The variant's own hover background was replacing the token fill, reading
as transparent; the fill is now pinned on hover with a brightness dip.
2026-07-23 14:26:48 +00:00
Katia Bulatova 81b45cf157 feat(webapp): drop the timeline label shadow in System themes 2026-07-23 14:25:43 +00:00
Katia Bulatova a1b8310194 feat(webapp): all filled buttons use semantic accent tokens
Stepper +/- and prompt override controls join the bg-token + brightness
hover pattern; override chips reference bg-warning.
2026-07-23 14:23:58 +00:00
Katia Bulatova 632bc23594 feat(webapp): list chips settle on tinted background with colored text
Root-style badges and error status chips share the tint+color language;
text colors come from the unified accent set so they read in both System
modes.
2026-07-23 14:22:36 +00:00
Katia Bulatova db3ca4656b feat(webapp): live-block buttons follow the semantic accent tokens
bg-runs/bg-concurrency/bg-success/bg-warning instead of raw palette steps,
hover lightens via brightness so the fill always matches the unified accent
set.
2026-07-23 14:21:55 +00:00
Katia Bulatova c1ab98f8bc feat(webapp): error status chips use colored border with monochrome text in System themes 2026-07-23 14:20:14 +00:00
Katia Bulatova d22221cd4e fix(webapp): keep the billing banner button on the darker amber 2026-07-23 14:19:27 +00:00