Skip to content

Paginate Traces tab with step filter#560

Merged
abidlabs merged 2 commits into
mainfrom
traces-pagination
May 21, 2026
Merged

Paginate Traces tab with step filter#560
abidlabs merged 2 commits into
mainfrom
traces-pagination

Conversation

@abidlabs

@abidlabs abidlabs commented May 21, 2026

Copy link
Copy Markdown
Member

Continuing the work that @edbeeching started in #540, this PR implements:

  • Server-paginated Traces tab: get_traces gains step + limit/offset; new get_trace_steps returns per-step counts.
  • Traces.svelte adds a step dropdown and 50/page prev/next; existing search, sort, and expandable rows are preserved.
  • trackio.log() accepts list[Trace] so one step can carry a batch of rollouts.
  • Example: examples/traces/large-trace-batch.py logs 200 steps × 40 traces (8000 total) for performance testing.

Adds server-side step + limit/offset to get_traces, a new get_trace_steps
endpoint that returns per-step counts, and reworks the Traces tab to load
one page at a time with a step selector + prev/next navigation. Also
extends trackio.log() to accept a list of Trace objects so a single step
can carry a batch of rollouts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gradio-pr-bot

gradio-pr-bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

🪼 branch checks and previews

Name Status URL
🦄 Changes detected! Details

@gradio-pr-bot

Copy link
Copy Markdown
Contributor

🦄 change detected

This Pull Request includes changes to the following packages.

Package Version
trackio minor

  • Paginate Traces tab with step filter

‼️ Changeset not approved. Ensure the version bump is appropriate for all packages before approving.

  • Maintainers can approve the changeset by checking this checkbox.

Something isn't right?

  • Maintainers can change the version label to modify the version bump.
  • If the bot has failed to detect any changes, or if this pull request needs to update multiple packages to different versions or requires a more comprehensive changelog entry, maintainers can update the changelog file directly.

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

🪼 branch checks and previews

Name Status URL
Spaces ready! Spaces preview

Install Trackio from this PR (includes built frontend)

pip install "https://huggingface.co/buckets/trackio/trackio-wheels/resolve/e743a4b87070762366277953e5c202948bf1cdb6/trackio-0.25.1-py3-none-any.whl"

@abidlabs abidlabs requested review from Saba9 and znation May 21, 2026 00:17
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Copilot AI 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.

Pull request overview

This PR extends Trackio’s trace viewer to handle large trace volumes more efficiently by adding server-side pagination and step-based filtering, plus support for logging batched traces at a single step.

Changes:

  • Add step + limit/offset support to the traces backend API, and introduce a get_trace_steps endpoint for per-step counts.
  • Update the Traces UI to include a step dropdown and 50-per-page pagination while preserving search/sort/expandable rows.
  • Allow trackio.log() to accept list[Trace] values, and add an example script to generate large batched trace runs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
trackio/sqlite_storage.py Adds step filtering for get_traces and implements get_trace_steps aggregation.
trackio/server.py Exposes step in get_traces and registers new get_trace_steps API.
trackio/run.py Converts list[Trace] metric values into serializable dicts and queues media uploads.
trackio/frontend/src/pages/Traces.svelte Adds step filter UI, server pagination wiring, and pagination controls.
trackio/frontend/src/lib/staticApi.js Adds static-mode getTraceSteps and step filtering for traces.
trackio/frontend/src/lib/api.js Adds getTraceSteps client API wrapper (static + server modes).
examples/traces/large-trace-batch.py Adds a performance/stress test example generating large batched traces.
.changeset/young-views-do.md Declares a minor release changeset for the feature.
Comments suppressed due to low confidence (3)

trackio/frontend/src/pages/Traces.svelte:273

  • activeTotal multiplies the already-merged per-step count by selectedRuns.length, which overstates totals when multiple runs are selected (and inflates totalPages). Since loadSummary() sums counts across runs into availableSteps, the multiplier should be removed so totals/pagination reflect the real trace count.
  let activeTotal = $derived.by(() => {
    if (stepFilter === "all") return totalCount;
    const stepNum = Number(stepFilter);
    const entry = availableSteps.find((s) => s.step === stepNum);
    return entry ? entry.count * Math.max(1, selectedRuns.length) : 0;
  });

trackio/frontend/src/pages/Traces.svelte:167

  • The summary refresh/reset logic only keys off selectedRuns (runsKey(selectedRuns)), so switching project while keeping the same run selection can leave availableSteps/totalCount stale and pagination state inconsistent. Include project in the key (or track lastProject) so loadSummary() runs and paging/filter state resets on project changes.
  $effect(() => {
    project;
    const key = runsKey(selectedRuns);
    if (key !== lastRunsKey) {
      lastRunsKey = key;
      page = 0;
      stepFilter = "all";
      loadSummary();
    }

trackio/frontend/src/pages/Traces.svelte:183

  • Pagination (totalPages) is derived from totalCount/availableSteps, but those totals ignore the current search filter. With a non-empty search, the UI can show many pages and allow navigating to pages that will be empty even though there are no more matches. Consider returning a filtered total from the backend (e.g., add a count field/endpoint that takes search+step), or change the Next/total-pages logic to be driven by whether the current fetch returns a full page of results.
  $effect(() => {
    const trimmed = search.trim();
    if (trimmed !== lastSearch || sortBy !== lastSort || stepFilter !== lastStep) {
      if (lastSearch !== "" || trimmed !== "" || sortBy !== lastSort || stepFilter !== lastStep) {
        page = 0;
      }
      lastSearch = trimmed;
      lastSort = sortBy;
      lastStep = stepFilter;
    }

    const timeout = setTimeout(() => {
      loadTraces(trimmed, sortBy, stepFilter, page);
    }, 150);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +116 to 130
const stepNum = stepValue === "all" ? null : Number(stepValue);
const offset = currentPage * PAGE_SIZE;
const isSingleRun = selectedRuns.length === 1;
const perRunLimit = isSingleRun ? PAGE_SIZE : offset + PAGE_SIZE;
const perRunOffset = isSingleRun ? offset : 0;

const batches = await Promise.all(
selectedRuns.map(async (run) => {
const runTraces = await getTraces(project, run, {
search: searchQuery,
sort,
step: stepNum,
limit: perRunLimit,
offset: perRunOffset,
});
"trackio": minor
---

feat:Paginate Traces tab with step filter
@abidlabs

Copy link
Copy Markdown
Member Author

Thanks @Saba9!

@abidlabs abidlabs merged commit aee2923 into main May 21, 2026
15 checks passed
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.

5 participants