feat(assisted-query): Add AI search bar to metrics tab#111797
feat(assisted-query): Add AI search bar to metrics tab#111797isaacwang-sentry wants to merge 2 commits intomasterfrom
Conversation
Integrate the Seer assisted query agent into the metrics tab filter bar, enabling natural language to metrics query translation. The Seer backend already supports the Metrics strategy; this wires up the frontend. - Create MetricsTabSeerComboBox component following the logs/spans pattern - Modify filter.tsx to conditionally render AI search when feature flag is on - Register metrics AI query analytics events Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared a fix for 1 of the 2 issues found in the latest run.
- ✅ Fixed: AI search props may be overridden by spread
- Moved enableAISearch and aiSearchBadgeType props after the spread operator to ensure they take priority and cannot be overridden.
Or push these changes by commenting:
@cursor push cf15e7c25b
Preview (cf15e7c25b)
diff --git a/static/app/views/explore/metrics/metricToolbar/filter.tsx b/static/app/views/explore/metrics/metricToolbar/filter.tsx
--- a/static/app/views/explore/metrics/metricToolbar/filter.tsx
+++ b/static/app/views/explore/metrics/metricToolbar/filter.tsx
@@ -166,9 +166,9 @@
// Use the metric name as a key to force remount when it changes
// This prevents race conditions when navigating between different metrics
key={traceMetric.name}
+ {...searchQueryBuilderProviderProps}
enableAISearch={hasTranslateEndpoint}
aiSearchBadgeType="alpha"
- {...searchQueryBuilderProviderProps}
>
<MetricsSearchBar
tracesItemSearchQueryBuilderProps={tracesItemSearchQueryBuilderProps}This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
| const filteredCommittedQuery = queryDetails?.parsedQuery | ||
| ?.filter( | ||
| token => | ||
| !(token.type === Token.FREE_TEXT && inputValue && token.text.includes(inputValue)) | ||
| ) | ||
| ?.map(token => stringifyToken(token)) | ||
| ?.join(' ') | ||
| ?.trim(); |
| query: r?.query ?? '', | ||
| sort: r?.sort ?? '', | ||
| groupBys: r?.group_by ?? [], | ||
| statsPeriod: r?.stats_period ?? '', | ||
| start: r?.start ?? null, | ||
| end: r?.end ?? null, | ||
| mode: r?.mode ?? 'metrics', |
There was a problem hiding this comment.
does everything need a fallabck?
Move spread operator before explicit AI search props so they cannot be silently overridden. Remove unnecessary optional chaining on values that are always defined, and remove redundant fallback defaults where TypeScript types already guarantee the values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| } | ||
|
|
||
| // Update per-query state atomically (query, aggregateFields, mode) | ||
| setQueryParams({query: queryToUse, aggregateFields, mode}); |
There was a problem hiding this comment.
Bug: The AI search feature updates the global time range via navigate(), causing all metric rows to change their time range, instead of only affecting the specific row being edited.
Severity: HIGH
Suggested Fix
Instead of using navigate() to update the global time range, use the per-metric setQueryParams function to update the time range for only the specific metric row. This will align the time range update mechanism with how other per-metric parameters like query and aggregateFields are handled, respecting the intended row isolation.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: static/app/views/explore/metrics/metricsTabSeerComboBox.tsx#L227
Potential issue: The `applySeerSearchQuery` callback updates the time range by calling
`navigate()` with new `start`, `end`, and `statsPeriod` values in the global
`location.query`. This action modifies the time range for all metric rows displayed on
the page simultaneously. This behavior contradicts the intended design, where changes
from an AI search should only apply to the specific metric row being edited. The current
implementation breaks the per-row isolation, causing an AI search on one metric to
unexpectedly alter the time range for all other metrics on the page.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| ) | ||
| .map(token => stringifyToken(token)) | ||
| .join(' ') | ||
| .trim(); |
There was a problem hiding this comment.
Missing optional chaining causes crash on null parsedQuery
High Severity
parseQueryBuilderValue returns ParseResult | null. When parsedQuery is null, the ?.filter(...) evaluates to undefined, but the subsequent .map(), .join(), and .trim() calls lack optional chaining and will throw a TypeError. The equivalent code in LogsTabSeerComboBox and SpansTabSeerComboBox correctly uses ?.map(...)?.join(' ')?.trim() throughout the chain.



Summary
MetricsTabSeerComboBoxcomponent following the established logs/spans pattern, with metrics-specific adaptations (per-query state updates, default mode'metrics')Filtercomponent to enable AI search viaSearchQueryBuilderProviderand conditionally render the seer comboboxai_query_applied,ai_query_submitted,ai_query_rejected,ai_query_interface)gen-ai-search-agent-translatefeature flagTest plan
gen-ai-featuresandgen-ai-search-agent-translatefeature flags🤖 Generated with Claude Code