From 93939e0fff448b36247c29cc3d43084204cbb8c7 Mon Sep 17 00:00:00 2001 From: Paulo Lacerda Date: Mon, 31 Aug 2026 09:56:37 -0300 Subject: [PATCH] Default Observe time window to 7 days Change the Observe screen's default lookback from 24 hours to 7 days when no start/end is present in the URL. Updates the backend lookback constant, the UI range constant, and the mirrored constant in the embedded JavaScript, plus docstrings and docs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/observe.md | 2 +- src/agentops/agent/observe/queries.py | 4 ++-- src/agentops/agent/observe/ui.py | 11 +++++++---- tests/unit/test_observe_queries.py | 5 +++-- tests/unit/test_observe_ui.py | 6 +++--- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/observe.md b/docs/observe.md index 12b07619..548d32d5 100644 --- a/docs/observe.md +++ b/docs/observe.md @@ -65,7 +65,7 @@ selectors instead of the shared Observe time, source, project, model, tool, and run filters. This prevents a display filter from silently changing an allocation denominator. -The default range is 24 hours. Draft filters do not query until **Apply** is +The default range is 7 days. Draft filters do not query until **Apply** is selected. Applied filters are bookmarkable in the URL, refresh every five minutes, and may be refreshed manually. Raw trace content is never part of that URL or browser persistence. Alongside the existing agent, model, and time-range diff --git a/src/agentops/agent/observe/queries.py b/src/agentops/agent/observe/queries.py index 070fb299..d4c86a0a 100644 --- a/src/agentops/agent/observe/queries.py +++ b/src/agentops/agent/observe/queries.py @@ -33,7 +33,7 @@ MAX_SOURCES_PER_BATCH = 10 SOURCE_TIMEOUT_SECONDS = 30 DEFAULT_REQUEST_DEADLINE_SECONDS = 10 -DEFAULT_LOOKBACK_HOURS = 24 +DEFAULT_LOOKBACK_HOURS = 24 * 7 _TELEMETRY_TABLES = "union withsource=TelemetryTable AppDependencies, AppRequests" _APPGENAI_TABLE = "AppGenAIContent" @@ -91,7 +91,7 @@ def _iso(value: datetime) -> str: def default_lookback_window( *, now: datetime | None = None, hours: int = DEFAULT_LOOKBACK_HOURS ) -> tuple[datetime, datetime]: - """Return a bounded ``(start, end)`` window defaulting to 24 hours.""" + """Return a bounded ``(start, end)`` window defaulting to 7 days.""" end = now or datetime.now(timezone.utc) if end.tzinfo is None: end = end.replace(tzinfo=timezone.utc) diff --git a/src/agentops/agent/observe/ui.py b/src/agentops/agent/observe/ui.py index 302d1659..5fbfe964 100644 --- a/src/agentops/agent/observe/ui.py +++ b/src/agentops/agent/observe/ui.py @@ -21,7 +21,7 @@ content, evaluation explanations) is **never** written to the URL, to ``localStorage``/``sessionStorage``, or to cookies -- see :data:`_OBSERVE_SCRIPT` and the safety tests in ``test_observe_ui.py``. -* The default time range is the trailing 24 hours; refresh happens +* The default time range is the trailing 7 days; refresh happens automatically every five minutes and can also be triggered manually. Every fetch is issued with an ``AbortController`` and a monotonically increasing request token so that a response for a superseded request is silently @@ -139,7 +139,10 @@ ) #: Default lookback window, in hours, applied when no range is in the URL. -DEFAULT_RANGE_HOURS: int = 24 +#: Mirrors ``DEFAULT_LOOKBACK_HOURS`` in ``agentops.agent.observe.queries``; +#: this module deliberately imports nothing from the query layer, so the two +#: constants are kept in sync by convention (and by tests). +DEFAULT_RANGE_HOURS: int = 24 * 7 #: Automatic refresh interval, in milliseconds (five minutes). AUTO_REFRESH_MS: int = 5 * 60 * 1000 @@ -885,7 +888,7 @@ def render_filter_bar(scope_label: Optional[str] = None) -> str: read the *draft* values only when the user explicitly submits the form; nothing here is auto-applied on change/input. Filters default to "All" (an empty value), and the date/time fields default (client-side) to the - trailing 24 hours -- see :data:`_OBSERVE_SCRIPT`. + trailing 7 days -- see :data:`_OBSERVE_SCRIPT`. """ scope_html = ( f'

Scope: ' @@ -3290,7 +3293,7 @@ def render_trace_detail_shell( var COST_BREAKDOWN_WARNING = "Agent, tool, and run breakdowns are alternative reconciliations of the same billed pools; do not add them together."; var ATTRIBUTION_COST_UNAVAILABLE = "Cost attribution is unavailable. Configure a valid cost model and allocatable cost before selecting Cost."; var AUTO_REFRESH_MS = 300000; // five minutes - var DEFAULT_RANGE_MS = 24 * 60 * 60 * 1000; // trailing 24 hours + var DEFAULT_RANGE_MS = 7 * 24 * 60 * 60 * 1000; // trailing 7 days var CACHE_WINDOW_MS = 60 * 1000; // align default windows across browser sessions // Mirrors MAX_TREND_POINTS in ui.py: even though the backend is expected // to already bound each trend series (T053), the client re-bounds diff --git a/tests/unit/test_observe_queries.py b/tests/unit/test_observe_queries.py index 95347d2d..8592f440 100644 --- a/tests/unit/test_observe_queries.py +++ b/tests/unit/test_observe_queries.py @@ -145,15 +145,16 @@ def _usage(invocations: int) -> AttributionUsage: # --------------------------------------------------------------------------- -# T037: KQL builders - bounds, early filters, 24h defaults. +# T037: KQL builders - bounds, early filters, 7-day defaults. # --------------------------------------------------------------------------- -def test_default_lookback_window_is_24_hours() -> None: +def test_default_lookback_window_is_7_days() -> None: now = datetime(2024, 5, 1, 12, 0, tzinfo=timezone.utc) start, end = default_lookback_window(now=now) assert end == now assert end - start == timedelta(hours=DEFAULT_LOOKBACK_HOURS) + assert end - start == timedelta(days=7) def test_overview_query_is_bounded_to_time_window_and_tables() -> None: diff --git a/tests/unit/test_observe_ui.py b/tests/unit/test_observe_ui.py index d4c018da..e3d6406b 100644 --- a/tests/unit/test_observe_ui.py +++ b/tests/unit/test_observe_ui.py @@ -35,7 +35,7 @@ def _dt(hour: int = 0) -> datetime: def test_default_range_and_refresh_constants() -> None: - assert ui.DEFAULT_RANGE_HOURS == 24 + assert ui.DEFAULT_RANGE_HOURS == 24 * 7 assert ui.AUTO_REFRESH_MS == 5 * 60 * 1000 @@ -2126,9 +2126,9 @@ def test_script_auto_refreshes_every_five_minutes() -> None: assert "AUTO_REFRESH_MS = 300000" in script -def test_script_computes_default_24_hour_range_when_missing_from_url() -> None: +def test_script_computes_default_7_day_range_when_missing_from_url() -> None: script = ui._OBSERVE_SCRIPT - assert "DEFAULT_RANGE_MS = 24 * 60 * 60 * 1000" in script + assert "DEFAULT_RANGE_MS = 7 * 24 * 60 * 60 * 1000" in script assert 'value = local.toISOString().slice(0, 16);' in script assert "value = isNaN(moment.getTime()) ? \"\" : moment.toISOString();" in script