Skip to content

fix(ui): always show Full Report link when runId exists in session history#150

Open
toanalien wants to merge 3 commits into
HKUDS:mainfrom
toanalien:fix/run-report-visibility-cross-browser
Open

fix(ui): always show Full Report link when runId exists in session history#150
toanalien wants to merge 3 commits into
HKUDS:mainfrom
toanalien:fix/run-report-visibility-cross-browser

Conversation

@toanalien
Copy link
Copy Markdown
Contributor

@toanalien toanalien commented May 30, 2026

Summary

  • Fix "Full Report" link disappearing when loading sessions from a different browser or remote device
  • loadSessionMessages and SSE handler now always render the run_complete card when runId exists in message metadata, even if api.getRun() fails (auth error, 404, network issue)
  • Improve RunDetail error page with diagnostic hints (API auth, run directory) and a back button

Root Cause

When reloading a session from history, if metrics was missing from message metadata, the code called api.getRun(runId) to fetch run data. If that call failed (common for remote/cross-browser access due to auth), the error was silently caught and the card was never added — so the "Full Report" link disappeared entirely. The original browser still showed it because the card was cached in Zustand's in-memory store from the live SSE session.

Test plan

  • Open a session with completed backtest runs in the original browser — verify "Full Report" link still appears with metrics/chart
  • Open the same session in a new browser (or incognito) — verify "Full Report" link now appears
  • Click "Full Report" when run data is available — verify RunDetail page loads normally
  • Click "Full Report" when run data is unavailable — verify improved error page with hints and back button
  • cd frontend && npx vite build passes
CleanShot 2026-05-30 at 11 55 24@2x

toanalien added 2 commits May 30, 2026 11:53
…story

Previously, when loading a session from history (e.g. in a new browser),
the run_complete card was silently dropped if api.getRun() failed or
returned non-report-worthy data. This caused the "Full Report" link to
disappear for remote/cross-browser users while remaining visible in the
original browser's in-memory cache.

Now the card always renders when runId is present in message metadata,
with metrics and equity curve as optional enrichments. Also improves the
RunDetail error page with diagnostic hints and a back button.
@warren618
Copy link
Copy Markdown
Collaborator

Thanks for the fix — the root cause is real and the RunDetail not-found diagnostic page is a nice improvement. But the "always render the card when runId exists" approach is too broad and introduces a regression. Requesting changes before merge.

The regression

Every assistant turn carries a run_id, not just backtests. In service.py, every agent.run() creates a run directory (loop.py state_store.create_run_dir), and the reply metadata gets run_id whenever a run dir exists:

# session/service.py
if attempt.run_dir:
    reply_metadata["run_id"] = Path(attempt.run_dir).name

There is no separate lightweight chat path — a plain conversational answer also gets a run_id. Verified end-to-end against a local server:

# sent: "what is a moving average? answer in one sentence, do not run any backtest"
assistant metadata: {"run_id": "20260530_062432_41_d7d2d9", "status": "completed"}  # run_id present, no metrics
getRun(run_id) -> status=success, metrics=None, equity_curve=None, artifacts=[]
isReportWorthyRun(...) === false

On main, the else branch (if (isReportWorthyRun)) and the SSE branch (if (hasReport || shadowId)) correctly skip the card for these turns. With this PR, every plain chat answer now renders a spurious "Full Report →" link, and clicking it lands on a RunDetail page with no metrics / chart / trades.

The case worth preserving

The genuine bug is narrower: a run that is report-worthy but has no metrics in metadata (e.g. a Pine-only or equity-curve-only run). Metrics-bearing backtests already render from metadata alone (first branch, no getRun, so they're fine cross-browser). The link only disappears cross-browser when getRun fails (401/404/network) and we can't confirm report-worthiness.

Suggested fix

Only fall back to a bare card when getRun actually throws — i.e. distinguish "succeeded but not report-worthy" (plain chat → render nothing) from "couldn't fetch" (unknown → show the link):

let fetchedMetrics, fetchedCurve, runUnavailable = false;
try {
  const runData = await api.getRun(runId);
  if (isReportWorthyRun(runData)) {
    fetchedMetrics = runData.metrics;
    fetchedCurve = runData.equity_curve?.map(e => ({ time: e.time, equity: Number(e.equity) }));
  } else {
    // succeeded but not report-worthy (plain chat) -> no card
    continue; // or skip the addMessage in the SSE path
  }
} catch {
  runUnavailable = true; // can't tell -> still show the link
}
// push run_complete card only when we have data OR the run couldn't be fetched

This keeps the cross-browser fix (auth failure → catch → link still shows) without putting a "Full Report" link under every conversational reply. The RunDetail.tsx changes are good as-is.

…logic

Address PR review: not every run_id is a backtest — plain chat turns also
get a run_id. Now only show the Full Report card when getRun() confirms
report-worthiness OR when the fetch fails (auth/network). Plain chat turns
where getRun() succeeds but isReportWorthyRun is false correctly skip the
card, avoiding spurious links.
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.

2 participants