Skip to content

feat(dashboard): show requests in flight on the activity page - #549

Merged
njbrake merged 5 commits into
mainfrom
feat/activity-in-flight-requests
Aug 10, 2026
Merged

feat(dashboard): show requests in flight on the activity page#549
njbrake merged 5 commits into
mainfrom
feat/activity-in-flight-requests

Conversation

@njbrake

@njbrake njbrake commented Aug 10, 2026

Copy link
Copy Markdown
Member

Description

The Activity page only showed settled usage, so a long-running provider request (a local model can take 30s+) was invisible. This adds a live "requests in flight" panel that names the requests the gateway is currently serving and how long each has been running.

In-flight requests are tracked by a per-worker in-memory registry, entered at the request harness points that already resolve provider/model (so a refused request never appears) and exited by ASGI cleanup middleware (so a streaming response stays listed until its body is consumed, and a dropped worker leaks nothing). The panel renders only while requests are running, is capped at the 50 longest-running, ticks elapsed time locally between polls, and the log below it refetches when a tracked request settles.

PR Type

  • New Feature
  • Bug Fix
  • Refactor
  • Documentation
  • Infrastructure / CI

Relevant issues

Fixes #526

Checklist

  • I understand the code I am submitting.
  • I have added or updated tests that cover my change (tests/unit, tests/integration).
  • I ran the Definition of Done checks locally (make lint, make typecheck, make test).
  • Documentation was updated where necessary.
  • If the API contract changed, I regenerated the OpenAPI spec (uv run python scripts/generate_openapi.py).

AI Usage

  • No AI was used.
  • AI was used for drafting/refactoring.
  • This is fully AI-generated.

AI Model/Tool used:

Claude

Any additional AI details you'd like to share:

  • I am an AI Agent filling out this form (check box if true)

🤖 Generated with Claude Code

Summary

  • Added live in-flight request tracking for provider, pipeline, pass-through, and search requests.
  • Added the master-key-protected GET /v1/usage/in-flight endpoint.
  • Added an Activity page panel for active requests with elapsed time, filtering, ordering, pagination, and error handling.
  • Added cleanup after completed, failed, and streamed requests.
  • Added documentation, Postman, dashboard, OpenAPI, and test coverage updates.

Benefits

  • Operators can identify long-running requests before they settle.
  • The Activity page refreshes completed requests when active requests finish.
  • Failed polling no longer leaves stale active rows visible.

Technical notes

  • Tracking is process-local and limited to the 50 longest-running requests.
  • Requests are tracked only after authorization, access, budget, and provider/model checks succeed.
  • The dashboard polls every two seconds and updates elapsed time between polls.

@njbrake njbrake added area/backend Backend service implementation area/dashboard Web admin dashboard (web/) labels Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The gateway now tracks active requests in a process-local registry, exposes them through GET /v1/usage/in-flight, and displays them as live Activity rows. Middleware removes entries after responses complete, including streams. Tests and generated dashboard assets are updated.

Changes

In-flight activity

Layer / File(s) Summary
Registry lifecycle and application wiring
src/gateway/inflight.py, src/gateway/main.py, src/gateway/AGENTS.md, tests/unit/test_inflight_registry.py
Adds request metadata records, ordered registry snapshots, request tracking helpers, middleware cleanup, application wiring, and unit coverage for lifecycle behavior.
Usage endpoint and dispatch registration
src/gateway/api/routes/usage.py, src/gateway/api/routes/_passthrough.py, src/gateway/api/routes/_pipeline.py, src/gateway/api/routes/search.py, tests/integration/test_in_flight_requests.py, tests/integration/test_search_endpoint.py, docs/public/otari.postman_collection.json, scripts/sdk_codegen/sdk-endpoints.txt
Adds the master-key-protected usage endpoint and registers pass-through, pipeline, and search requests after gateway admission checks. Integration tests cover ordering, metadata, cleanup, streaming, failures, and refusal points.
Activity dashboard live rows
web/src/api/types.ts, web/src/api/hooks.ts, web/src/pages/ActivityPage.tsx, web/src/pages/ActivityPage.test.tsx, docs/dashboard.md
Adds in-flight API types and polling. Activity renders filtered live rows above settled rows, excludes them from pagination and bulk actions, and refreshes settled data after completion.
Dashboard bundle regeneration
src/gateway/static/dashboard/assets/*, src/gateway/static/dashboard/index.html
Rebuilds dashboard bundles and asset references, including the new Activity page bundle and updated shared chunk imports.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • mozilla-ai/otari#507: Both changes modify ActivityPage and its tests around request activity display.
  • mozilla-ai/otari#449: Both changes cover gateway request lifecycle visibility and Activity handling.
  • mozilla-ai/otari#492: Both changes modify pipeline routing metadata used by in-flight request records.

Suggested reviewers: khaledosman

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title uses a valid scoped Conventional Commit prefix, clearly describes the dashboard change, uses imperative wording, and is under 70 characters.
Description check ✅ Passed The description includes the required sections, explains the change, links issue #526, records testing and documentation status, and declares AI usage.
Linked Issues check ✅ Passed The implementation satisfies issue #526 by showing active requests, including long-running requests, with lifecycle tracking and Activity page integration.
Out of Scope Changes check ✅ Passed The code, tests, documentation, API artifacts, and regenerated dashboard assets directly support the in-flight request feature.
✨ 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/activity-in-flight-requests
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/activity-in-flight-requests

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.

Track per-worker in-memory requests entered at the provider-resolving
harness points (so refused requests never appear) and exited by ASGI
cleanup middleware (so a streaming response stays listed until its body
is consumed, and a dropped worker leaks nothing). Surface them on the
Activity page as a live panel, capped at the 50 longest-running, that
ticks elapsed time between polls.

Regenerated the dashboard bundle, OpenAPI spec, and Postman collection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@njbrake
njbrake force-pushed the feat/activity-in-flight-requests branch from b781fc5 to f942ff3 Compare August 10, 2026 18:13
@njbrake
njbrake deployed to integration-tests August 10, 2026 18:13 — with GitHub Actions Active
Search passed through to the provider without registering, so a slow
search was the one surface invisible to the live in-flight view, and the
panel's claim that every served request is listed was not quite true.
Enter the request in the in-flight registry after every gate (tool
resolution, allowlist, budget) and before the provider call, tagged with
the same endpoint/model/provider the usage row carries. Covers both the
body-selected and path-selected forms.

Also rebuild the committed dashboard bundle from a clean dependency
install; the previously committed bundle was built from a stale
node_modules and failed the dashboard CI freshness check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@njbrake
njbrake deployed to integration-tests August 10, 2026 18:51 — with GitHub Actions Active
Requests still running now appear in the activity table itself, pinned above
the settled rows with the status "in progress" and, in place of a total time, a
wait that ticks up. When the request lands its row resolves in place into the
success or error row it became, which is the reading a separate panel above the
table could not give: the operator watched a request leave one list and,
seconds later, appear in another.

The synthetic row is shaped as a UsageEntry, so the table's columns, widths,
selection and detail machinery need no second code path; the outcome fields are
null, which the existing formatters already render as their own placeholder.
Ordered newest-first like the rest of the table (the endpoint still serves the
longest-running first, the order its cap applies in) so a request stays in the
slot it appeared in as it settles.

A live row is kept out of everything it is not part of: the paginator's count,
the bulk delete and reprice selection, and the request detail, none of which
exist for a request with no usage row yet. It is dropped from view rather than
shown misleadingly wherever the current view could not honestly include it: page
2 onward, a window ending in the past, and any filter on something the request
has not got yet (status, priced, tool, source, session). The identity filters do
apply, so they are matched client-side.

Also from review:

* Throttle the settled-request log refetch to once per 10 seconds, matching the
  log's own staleTime. The registry is per process, so a deployment running
  several otari processes behind a load balancer answers consecutive polls from
  different processes and a still-running request reads as settled on every one
  of them; unthrottled that refetched the log and its COUNT(*) every two seconds
  for as long as the gateway had any traffic at all.
* track_request now drops any id already on the scope before registering, so a
  second registration on one request cannot strand the first entry for the life
  of the process. No path reaches it twice today.
* Correct the docs: the panel covers completions, embeddings, images, audio and
  searches rather than literally every request (a batch runs provider-side after
  its submission returns), gateway_active_requests is per process, and
  multi-process deployments are several otari processes behind a load balancer,
  not uvicorn workers, which the CLI refuses.
* Name all three registration points in src/gateway/AGENTS.md, so a new dispatch
  scaffold is known to need its own track_request call.

Verified against a live gateway: a streaming request is listed mid-flight with
the right identity and a growing wait, its entry clears once the body is
consumed, an abandoned stream leaks nothing, a refused request is never listed,
and 58 concurrent requests report total=58 with the 50 longest-running
serialized in order.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@njbrake
njbrake deployed to integration-tests August 10, 2026 20:10 — with GitHub Actions Active
@njbrake
njbrake marked this pull request as ready for review August 10, 2026 20:10
Follow-up to an independent review of this branch. Five findings, one
functional and four where the prose asserted more than the code delivers.

The settled-request refetch throttle discarded a settle rather than deferring
it. Inside the 10 second window the effect returned early, but it had already
replaced the seen-id set, so the settled id was gone from both the ref and the
next poll and nothing re-detected it. Any two requests landing inside one window
left the second one's row missing from the log until an unrelated later settle
or a manual refresh, which is the ordinary case on a gateway with traffic and
defeats the behaviour the live rows exist for. A `settlePending` ref now carries
the settle to the first poll past the window. The effect also keys on
`dataUpdatedAt`, because an idle registry answers every poll with a structurally
identical empty payload that TanStack's structural sharing returns as the same
object, so keying on the payload alone stopped the effect firing once the last
request landed and a deferred settle would never have been reconsidered. The
multi-replica throttle test still passes: that case re-flags every poll either
way and still costs one refetch per interval.

The claim that a refused request never appears as in progress was wrong in five
places, including the user-facing guide and the bundled dashboard copy of it.
`prepare_gateway_tools` runs after the registration point, so a request refused
by an input guardrail, an unresolvable MCP id, or a bad tool declaration is
already listed, and a guardrail is an outbound call rather than a local check.
An unresolvable selector reaches the registration point too. Each site now says
which gates the claim covers, and that a later refusal does appear while its
check runs, which is the honest reading: the gateway is working on the request
by then.

`test_a_refused_request_is_never_registered` could not fail for the reason it
named. It asserted the registry was empty after the response, and cleanup is
unconditional, so that held whether or not anything had been recorded. It now
asserts on `InFlightRegistry.begin` call counts, which is what surfaced the
unresolvable-selector case above.

`gateway_active_requests` was offered as this panel's per-process count in the
guide and as a process-wide total in the endpoint docstring. It counts every
HTTP scope except `/metrics`, including the dashboard's own poll of this
endpoint, so an idle gateway with the Activity page open reports at least one
while the table shows nothing. Both sites now say it measures a different, larger
population.

The pulse dot on an in-progress row animated indefinitely without honouring
`prefers-reduced-motion`, which globals.css already respects for two other
animations.

Regenerated the OpenAPI spec and Postman collection for the endpoint docstring,
and the dashboard bundle for the page and guide changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@njbrake
njbrake deployed to integration-tests August 10, 2026 20:47 — with GitHub Actions Active

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/integration/test_in_flight_requests.py (1)

129-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider pinning the serialization cap in this test module.

The dashboard renders total - requests.length as "further requests are in flight", so the endpoint's cap is a contract the UI depends on. This test proves ordering, but nothing here proves that total exceeds len(requests) once the cap bites. A test that seeds more than the cap and asserts both the list length and the larger total would lock that behaviour down.

♻️ Sketch of the extra case
def test_the_response_caps_the_list_and_still_reports_the_true_total(
    client: TestClient, master_key_header: dict[str, str]
) -> None:
    registry = _registry(client)
    ids = [registry.begin(endpoint="/v1/chat/completions", model=f"m{i}") for i in range(60)]
    try:
        payload = client.get(IN_FLIGHT, headers=master_key_header).json()
    finally:
        for request_id in ids:
            registry.finish(request_id)

    assert payload["total"] == 60
    assert len(payload["requests"]) == 50
    # The cap keeps the longest-running, which is what the panel claims to show.
    assert [entry["model"] for entry in payload["requests"]] == [f"m{i}" for i in range(50)]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_in_flight_requests.py` around lines 129 - 142, Add a
test in the in-flight request test module that begins more requests than the
endpoint serialization cap, then asserts the response retains the true total
while limiting requests to the cap. Verify the returned models are the oldest
entries in order, and always finish all registered requests during cleanup.
web/src/pages/ActivityPage.test.tsx (1)

1542-1663: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Drive the polling tests with fake timers.

Call vi.useFakeTimers() per test and restore vi.useRealTimers() during cleanup. Advance the 2-second polling interval and 10-second throttle with await act(async () => vi.advanceTimersByTimeAsync(...)). Do not rely on waitFor to advance fake time. This makes TanStack Query polling and the Date.now() throttle deterministic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/pages/ActivityPage.test.tsx` around lines 1542 - 1663, Update the
three polling tests around “re-reads the log once a tracked request settles” to
call vi.useFakeTimers() and restore vi.useRealTimers() during cleanup. Replace
timing-dependent waitFor progression with await act(async () =>
vi.advanceTimersByTimeAsync(...)) for the 2-second polling interval and
10-second throttle, while retaining waitFor only for state assertions; ensure
TanStack Query polling and Date.now()-based throttling advance
deterministically.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/pages/ActivityPage.tsx`:
- Around line 1181-1184: Update the in-flight rows useMemo to return the empty
result whenever inFlight.isError is true, preventing stale successful data from
remaining visible after a failed poll. Add inFlight.isError to the memo
dependency array, and include the in-flight error in the existing ErrorBanner
chain so operators see the polling failure.

---

Nitpick comments:
In `@tests/integration/test_in_flight_requests.py`:
- Around line 129-142: Add a test in the in-flight request test module that
begins more requests than the endpoint serialization cap, then asserts the
response retains the true total while limiting requests to the cap. Verify the
returned models are the oldest entries in order, and always finish all
registered requests during cleanup.

In `@web/src/pages/ActivityPage.test.tsx`:
- Around line 1542-1663: Update the three polling tests around “re-reads the log
once a tracked request settles” to call vi.useFakeTimers() and restore
vi.useRealTimers() during cleanup. Replace timing-dependent waitFor progression
with await act(async () => vi.advanceTimersByTimeAsync(...)) for the 2-second
polling interval and 10-second throttle, while retaining waitFor only for state
assertions; ensure TanStack Query polling and Date.now()-based throttling
advance deterministically.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e2fd7a09-f20e-4089-8943-a05a5e2bd755

📥 Commits

Reviewing files that changed from the base of the PR and between f75e5b0 and 20944c6.

⛔ Files ignored due to path filters (1)
  • docs/public/openapi.json is excluded by !docs/public/openapi.json
📒 Files selected for processing (40)
  • docs/dashboard.md
  • docs/public/otari.postman_collection.json
  • scripts/sdk_codegen/sdk-endpoints.txt
  • src/gateway/AGENTS.md
  • src/gateway/api/routes/_passthrough.py
  • src/gateway/api/routes/_pipeline.py
  • src/gateway/api/routes/search.py
  • src/gateway/api/routes/usage.py
  • src/gateway/inflight.py
  • src/gateway/main.py
  • src/gateway/static/dashboard/assets/ActivityPage-BUTTJXqS.js
  • src/gateway/static/dashboard/assets/ActivityPage-DVvHOnJV.js
  • src/gateway/static/dashboard/assets/BudgetsPage-BRe5t28X.js
  • src/gateway/static/dashboard/assets/ConfirmDialog-Ql3FtMnI.js
  • src/gateway/static/dashboard/assets/DocsPage-Ci3s5_SN.js
  • src/gateway/static/dashboard/assets/KeysPage-Doebe-tT.js
  • src/gateway/static/dashboard/assets/ModelScopeControl-Dp3Sygm_.js
  • src/gateway/static/dashboard/assets/ModelsPage-CeOCF2a1.js
  • src/gateway/static/dashboard/assets/ModelsPage-Dus_If6B.js
  • src/gateway/static/dashboard/assets/OverviewPage-C5V0M17G.js
  • src/gateway/static/dashboard/assets/ProvidersPage-BGOpAogm.js
  • src/gateway/static/dashboard/assets/ProvidersPage-DcqFf570.js
  • src/gateway/static/dashboard/assets/RoutingPage-XwtlENNP.js
  • src/gateway/static/dashboard/assets/SettingsPage-BsU5fEB5.js
  • src/gateway/static/dashboard/assets/TablePagination-CbgAoqkJ.js
  • src/gateway/static/dashboard/assets/ToolsGuardrailsPage-CxXrvYsP.js
  • src/gateway/static/dashboard/assets/ToolsGuardrailsPage-D3KyltPY.js
  • src/gateway/static/dashboard/assets/UsagePage-DP3H5pdP.js
  • src/gateway/static/dashboard/assets/UsersPage-CgUvLTG9.js
  • src/gateway/static/dashboard/assets/index-94k-6miE.js
  • src/gateway/static/dashboard/assets/index-CI-EveRE.css
  • src/gateway/static/dashboard/assets/index-CyNKaqo6.js
  • src/gateway/static/dashboard/index.html
  • tests/integration/test_in_flight_requests.py
  • tests/integration/test_search_endpoint.py
  • tests/unit/test_inflight_registry.py
  • web/src/api/hooks.ts
  • web/src/api/types.ts
  • web/src/pages/ActivityPage.test.tsx
  • web/src/pages/ActivityPage.tsx
💤 Files with no reviewable changes (5)
  • src/gateway/static/dashboard/assets/ProvidersPage-BGOpAogm.js
  • src/gateway/static/dashboard/assets/ToolsGuardrailsPage-CxXrvYsP.js
  • src/gateway/static/dashboard/assets/ModelsPage-CeOCF2a1.js
  • src/gateway/static/dashboard/assets/index-94k-6miE.js
  • src/gateway/static/dashboard/assets/ActivityPage-DVvHOnJV.js

Comment thread web/src/pages/ActivityPage.tsx
@njbrake

njbrake commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

Note: posted by Claude at @njbrake's request. It is a bot trigger, nothing more.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

@njbrake I will review pull request #549.

⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Found by CodeRabbit on this branch, and reproduced: with the endpoint answering
503, an in-progress row stayed on screen and its wait climbed from 3s to 9s.

The rows were derived from `inFlight.data` alone, and TanStack keeps the last
successful payload after a failed refetch. So a gateway restart, an expired
session, or a network blip left the table asserting that work was still running
when it may have landed minutes ago, with the wait counting up against an anchor
that could no longer move. `useInFlightRequests` already refuses to cache that
state across mounts, with `staleTime: 0` and no placeholder data, for exactly this
reason; reaching it by another route defeats that.

The rows are now dropped when the query is in error, and the in-flight error joins
the page's error banner last, behind a failure to read the log itself, so a live
view that has gone quiet is distinguishable from a gateway that has rather than
showing as rows quietly disappearing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@njbrake
njbrake deployed to integration-tests August 10, 2026 22:07 — with GitHub Actions Active
@coderabbitai
coderabbitai Bot requested a review from khaledosman August 10, 2026 22:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
web/src/pages/ActivityPage.test.tsx (1)

1542-1693: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Consider fake timers for the throttle/failure tests to speed up the suite.

These three tests wait on real wall-clock time: up to 8s, 20s, and 25s inside waitFor, with per-test timeouts of 15s, 30s, and 45s. That is a lot of real time spent in CI for one describe block, and it also leaves a small flakiness window if CI is under load and the retry backoff or poll interval runs a bit slower than expected.

Using vi.useFakeTimers() with vi.advanceTimersByTimeAsync(...) would let these tests assert the same throttle and retry behavior deterministically, without actually waiting in real time. Not a blocker since the tests are correct as written, just a nice-to-have if the suite starts to feel slow.

Do you want a hand sketching the fake-timer version of one of these tests as a starting point?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/pages/ActivityPage.test.tsx` around lines 1542 - 1693, Speed up the
timing-sensitive tests “does not re-read the log on every poll when replicas
alternate,” “drops the live rows when the in-flight poll starts failing,” and
“still picks up a settle that the throttle deferred” by using vi.useFakeTimers
and vi.advanceTimersByTimeAsync. Preserve their existing throttle, polling,
failure, and deferred-settle assertions while avoiding long real-time waitFor
intervals; restore real timers after each test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@web/src/pages/ActivityPage.test.tsx`:
- Around line 1542-1693: Speed up the timing-sensitive tests “does not re-read
the log on every poll when replicas alternate,” “drops the live rows when the
in-flight poll starts failing,” and “still picks up a settle that the throttle
deferred” by using vi.useFakeTimers and vi.advanceTimersByTimeAsync. Preserve
their existing throttle, polling, failure, and deferred-settle assertions while
avoiding long real-time waitFor intervals; restore real timers after each test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d626c580-3664-423b-a697-63fb7ef170e1

📥 Commits

Reviewing files that changed from the base of the PR and between 20944c6 and 949e65f.

📒 Files selected for processing (19)
  • src/gateway/static/dashboard/assets/ActivityPage-DOJHPUQ4.js
  • src/gateway/static/dashboard/assets/BudgetsPage-CdiIH4HU.js
  • src/gateway/static/dashboard/assets/ConfirmDialog-hT_rddGe.js
  • src/gateway/static/dashboard/assets/DocsPage-C93UDDOQ.js
  • src/gateway/static/dashboard/assets/KeysPage-hJurDqS1.js
  • src/gateway/static/dashboard/assets/ModelScopeControl-BD06nruZ.js
  • src/gateway/static/dashboard/assets/ModelsPage-BoPl3AYj.js
  • src/gateway/static/dashboard/assets/OverviewPage-CA7PVlzB.js
  • src/gateway/static/dashboard/assets/ProvidersPage-sUbxKG6D.js
  • src/gateway/static/dashboard/assets/RoutingPage-B0PbG8Zg.js
  • src/gateway/static/dashboard/assets/SettingsPage-CjDCXBZG.js
  • src/gateway/static/dashboard/assets/TablePagination-CLVORqYy.js
  • src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Dv1tsNMm.js
  • src/gateway/static/dashboard/assets/UsagePage-BDaceVBD.js
  • src/gateway/static/dashboard/assets/UsersPage-DqeEPtPm.js
  • src/gateway/static/dashboard/assets/index-BM-zs2wX.js
  • src/gateway/static/dashboard/index.html
  • web/src/pages/ActivityPage.test.tsx
  • web/src/pages/ActivityPage.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/gateway/static/dashboard/index.html
  • web/src/pages/ActivityPage.tsx

@njbrake
njbrake merged commit 4600ae4 into main Aug 10, 2026
14 checks passed
@njbrake
njbrake deleted the feat/activity-in-flight-requests branch August 10, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/backend Backend service implementation area/dashboard Web admin dashboard (web/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard: activity pane should also show requests in flight

2 participants