Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/observe.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/agentops/agent/observe/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 7 additions & 4 deletions src/agentops/agent/observe/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'<p class="observe-scope"><span class="observe-hint">Scope:</span> '
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/test_observe_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/test_observe_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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

Expand Down
Loading