diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpOverview.ts b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpOverview.ts
index 4402cbdc225d2d..6a49ded4b840ed 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpOverview.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpOverview.ts
@@ -6,7 +6,7 @@ import {WIDGET_COLUMN_LABELS} from 'sentry/views/dashboards/utils/prebuiltConfig
import {spaceWidgetsEquallyOnRow} from 'sentry/views/dashboards/utils/prebuiltConfigs/utils/spaceWidgetsEquallyOnRow';
import {SpanFields, SpanFunction} from 'sentry/views/insights/types';
-const MCP_SERVER_FILTER = `${SpanFields.SPAN_OP}:mcp.server`;
+const MCP_SERVER_FILTER = `${SpanFields.NAME}:mcp.server`;
const MCP_TOOL_FILTER = `${MCP_SERVER_FILTER} has:${SpanFields.MCP_TOOL_NAME}`;
const MCP_RESOURCE_FILTER = `${MCP_SERVER_FILTER} has:${SpanFields.MCP_RESOURCE_URI}`;
const MCP_PROMPT_FILTER = `${MCP_SERVER_FILTER} has:${SpanFields.MCP_PROMPT_NAME}`;
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpPrompts.ts b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpPrompts.ts
index 914f705a9440b1..e1deeae22e1453 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpPrompts.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpPrompts.ts
@@ -7,7 +7,7 @@ import {WIDGET_COLUMN_LABELS} from 'sentry/views/dashboards/utils/prebuiltConfig
import {spaceWidgetsEquallyOnRow} from 'sentry/views/dashboards/utils/prebuiltConfigs/utils/spaceWidgetsEquallyOnRow';
import {SpanFields, SpanFunction} from 'sentry/views/insights/types';
-const MCP_PROMPT_FILTER = `${SpanFields.SPAN_OP}:mcp.server has:${SpanFields.MCP_PROMPT_NAME}`;
+const MCP_PROMPT_FILTER = `${SpanFields.NAME}:mcp.server has:${SpanFields.MCP_PROMPT_NAME}`;
const FIRST_ROW_WIDGETS = spaceWidgetsEquallyOnRow(
[
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpResources.ts b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpResources.ts
index 363a577582af87..3b744454513f4f 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpResources.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpResources.ts
@@ -7,7 +7,7 @@ import {WIDGET_COLUMN_LABELS} from 'sentry/views/dashboards/utils/prebuiltConfig
import {spaceWidgetsEquallyOnRow} from 'sentry/views/dashboards/utils/prebuiltConfigs/utils/spaceWidgetsEquallyOnRow';
import {SpanFields, SpanFunction} from 'sentry/views/insights/types';
-const MCP_RESOURCE_FILTER = `${SpanFields.SPAN_OP}:mcp.server has:${SpanFields.MCP_RESOURCE_URI}`;
+const MCP_RESOURCE_FILTER = `${SpanFields.NAME}:mcp.server has:${SpanFields.MCP_RESOURCE_URI}`;
const FIRST_ROW_WIDGETS = spaceWidgetsEquallyOnRow(
[
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpTools.ts b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpTools.ts
index cf49305811d13d..567d9f1a172049 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpTools.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/ai/mcpTools.ts
@@ -7,7 +7,7 @@ import {WIDGET_COLUMN_LABELS} from 'sentry/views/dashboards/utils/prebuiltConfig
import {spaceWidgetsEquallyOnRow} from 'sentry/views/dashboards/utils/prebuiltConfigs/utils/spaceWidgetsEquallyOnRow';
import {SpanFields, SpanFunction} from 'sentry/views/insights/types';
-const MCP_TOOL_FILTER = `${SpanFields.SPAN_OP}:mcp.server has:${SpanFields.MCP_TOOL_NAME}`;
+const MCP_TOOL_FILTER = `${SpanFields.NAME}:mcp.server has:${SpanFields.MCP_TOOL_NAME}`;
const FIRST_ROW_WIDGETS = spaceWidgetsEquallyOnRow(
[
diff --git a/static/app/views/insights/pages/agents/components/toolsTable.tsx b/static/app/views/insights/pages/agents/components/toolsTable.tsx
index b45c9d16f5ee7a..d71e33c72ad917 100644
--- a/static/app/views/insights/pages/agents/components/toolsTable.tsx
+++ b/static/app/views/insights/pages/agents/components/toolsTable.tsx
@@ -189,7 +189,7 @@ const BodyCell = memo(function BodyCell({
},
],
query: `gen_ai.tool.name:"${dataRow.tool}"`,
- field: ['span.description', 'gen_ai.tool.output', 'span.duration', 'timestamp'],
+ field: ['span.name', 'gen_ai.tool.output', 'span.duration', 'timestamp'],
});
switch (column.key) {
diff --git a/static/app/views/insights/pages/agents/hooks/useAgentSpanSearchProps.tsx b/static/app/views/insights/pages/agents/hooks/useAgentSpanSearchProps.tsx
index 19781c3a5f4f86..3947ad16793ef1 100644
--- a/static/app/views/insights/pages/agents/hooks/useAgentSpanSearchProps.tsx
+++ b/static/app/views/insights/pages/agents/hooks/useAgentSpanSearchProps.tsx
@@ -34,9 +34,7 @@ export function useAgentSpanSearchProps() {
},
searchSource: 'agent-monitoring',
- replaceRawSearchKeys: hasRawSearchReplacement
- ? ['span.description', 'span.name']
- : undefined,
+ replaceRawSearchKeys: hasRawSearchReplacement ? ['span.name'] : undefined,
matchKeySuggestions: [
{key: 'trace', valuePattern: /^[0-9a-fA-F]{32}$/},
{key: 'id', valuePattern: /^[0-9a-fA-F]{16}$/},
diff --git a/static/app/views/insights/pages/agents/utils/aiTraceNodes.tsx b/static/app/views/insights/pages/agents/utils/aiTraceNodes.tsx
index 952bb04671e8da..7053a04b1b98b9 100644
--- a/static/app/views/insights/pages/agents/utils/aiTraceNodes.tsx
+++ b/static/app/views/insights/pages/agents/utils/aiTraceNodes.tsx
@@ -2,7 +2,7 @@ import type {EventTransaction} from 'sentry/types/event';
import {prettifyAttributeName} from 'sentry/views/explore/components/traceItemAttributes/utils';
import type {TraceItemResponseAttribute} from 'sentry/views/explore/hooks/useTraceItemDetails';
import {
- getGenAiOperationTypeFromSpanOp,
+ getGenAiOperationTypeFromSpanName,
getIsAiAgentSpan,
getIsAiGenerationSpan,
getIsExecuteToolSpan,
@@ -57,16 +57,18 @@ export function ensureAttributeObject(
/**
* Returns the `gen_ai.operation.type` for a given trace node.
- * If the attribute is not present it will deduce it from the `span.op`
+ * If the attribute is not present it will deduce it from the `span.name`
*
- * **Note:** To keep the complexity manageable, this logic does not work for the edge case of transactions without `span.op` on the old data model.
+ * **Note:** To keep the complexity manageable, this logic does not work for the edge case of transactions without `span.name` on the old data model.
*/
export function getGenAiOpType(node: BaseNode): string | undefined {
const attributeObject = node.attributes;
return (
(attributeObject?.[SpanFields.GEN_AI_OPERATION_TYPE] as string | undefined) ??
- getGenAiOperationTypeFromSpanOp(node.op)
+ getGenAiOperationTypeFromSpanName(
+ node.value && 'name' in node.value ? (node.value.name as string) : undefined
+ )
);
}
diff --git a/static/app/views/insights/pages/agents/utils/query.spec.ts b/static/app/views/insights/pages/agents/utils/query.spec.ts
new file mode 100644
index 00000000000000..2cccbf64d34fe6
--- /dev/null
+++ b/static/app/views/insights/pages/agents/utils/query.spec.ts
@@ -0,0 +1,53 @@
+import {GenAiOperationType, getGenAiOperationTypeFromSpanName} from './query';
+
+describe('getGenAiOperationTypeFromSpanName', () => {
+ it('returns undefined for undefined input', () => {
+ expect(getGenAiOperationTypeFromSpanName(undefined)).toBeUndefined();
+ });
+
+ it('returns undefined for empty string', () => {
+ expect(getGenAiOperationTypeFromSpanName('')).toBeUndefined();
+ });
+
+ it('returns undefined for non-gen_ai span names', () => {
+ expect(getGenAiOperationTypeFromSpanName('http.client')).toBeUndefined();
+ expect(getGenAiOperationTypeFromSpanName('db.query')).toBeUndefined();
+ expect(getGenAiOperationTypeFromSpanName('mcp.server')).toBeUndefined();
+ });
+
+ it('returns AGENT for gen_ai.invoke_agent', () => {
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.invoke_agent')).toBe(
+ GenAiOperationType.AGENT
+ );
+ });
+
+ it('returns AGENT for gen_ai.create_agent', () => {
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.create_agent')).toBe(
+ GenAiOperationType.AGENT
+ );
+ });
+
+ it('returns TOOL for gen_ai.execute_tool', () => {
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.execute_tool')).toBe(
+ GenAiOperationType.TOOL
+ );
+ });
+
+ it('returns HANDOFF for gen_ai.handoff', () => {
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.handoff')).toBe(
+ GenAiOperationType.HANDOFF
+ );
+ });
+
+ it('returns AI_CLIENT for other gen_ai span names', () => {
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.chat')).toBe(
+ GenAiOperationType.AI_CLIENT
+ );
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.completion')).toBe(
+ GenAiOperationType.AI_CLIENT
+ );
+ expect(getGenAiOperationTypeFromSpanName('gen_ai.embeddings')).toBe(
+ GenAiOperationType.AI_CLIENT
+ );
+ });
+});
diff --git a/static/app/views/insights/pages/agents/utils/query.tsx b/static/app/views/insights/pages/agents/utils/query.tsx
index 7e9022ccfdfdc6..493721cde993f5 100644
--- a/static/app/views/insights/pages/agents/utils/query.tsx
+++ b/static/app/views/insights/pages/agents/utils/query.tsx
@@ -75,20 +75,20 @@ export enum GenAiOperationType {
}
// Should be used only when we don't have the gen_ai.operation.type attribute available
-export const getGenAiOperationTypeFromSpanOp = (
- spanOp?: string
+export const getGenAiOperationTypeFromSpanName = (
+ spanName?: string
): GenAiOperationType | undefined => {
- if (!spanOp?.startsWith('gen_ai.')) {
+ if (!spanName?.startsWith('gen_ai.')) {
return undefined;
}
- if (['gen_ai.invoke_agent', 'gen_ai.create_agent'].includes(spanOp)) {
+ if (['gen_ai.invoke_agent', 'gen_ai.create_agent'].includes(spanName)) {
return GenAiOperationType.AGENT;
}
- if (spanOp === 'gen_ai.execute_tool') {
+ if (spanName === 'gen_ai.execute_tool') {
return GenAiOperationType.TOOL;
}
- if (spanOp === 'gen_ai.handoff') {
+ if (spanName === 'gen_ai.handoff') {
return GenAiOperationType.HANDOFF;
}
return GenAiOperationType.AI_CLIENT;
diff --git a/static/app/views/insights/pages/conversations/hooks/useConversation.spec.tsx b/static/app/views/insights/pages/conversations/hooks/useConversation.spec.tsx
index 17933d91724fd2..629d04f16913ef 100644
--- a/static/app/views/insights/pages/conversations/hooks/useConversation.spec.tsx
+++ b/static/app/views/insights/pages/conversations/hooks/useConversation.spec.tsx
@@ -36,8 +36,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-1',
trace: 'trace-1',
@@ -81,8 +80,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-output',
trace: 'trace-output',
@@ -123,8 +121,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-2',
trace: 'trace-2',
@@ -161,8 +158,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-3',
trace: 'trace-3',
@@ -201,8 +197,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-ts',
trace: 'trace-ts',
@@ -247,20 +242,18 @@ describe('useConversation', () => {
expect(queryArg).not.toHaveProperty('environment');
});
- it('falls back to span.name when span.description is empty', async () => {
+ it('uses span.name for description and name fields', async () => {
MockApiClient.addMockResponse({
- url: `/organizations/${organization.slug}/ai-conversations/conv-name-fallback/`,
+ url: `/organizations/${organization.slug}/ai-conversations/conv-name/`,
body: [
{
- 'gen_ai.conversation.id': 'conv-name-fallback',
+ 'gen_ai.conversation.id': 'conv-name',
parent_span: 'parent-1',
'precise.finish_ts': 1000.5,
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': '',
'span.name': 'My AI Agent',
- 'span.op': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-name',
trace: 'trace-name',
@@ -270,7 +263,7 @@ describe('useConversation', () => {
});
const {result} = renderHookWithProviders(
- () => useConversation({conversationId: 'conv-name-fallback'}),
+ () => useConversation({conversationId: 'conv-name'}),
{organization}
);
@@ -285,44 +278,6 @@ describe('useConversation', () => {
expect(value?.name).toBe('My AI Agent');
});
- it('prefers span.description over span.name when both exist', async () => {
- MockApiClient.addMockResponse({
- url: `/organizations/${organization.slug}/ai-conversations/conv-both/`,
- body: [
- {
- 'gen_ai.conversation.id': 'conv-both',
- parent_span: 'parent-1',
- 'precise.finish_ts': 1000.5,
- 'precise.start_ts': 1000.0,
- project: 'test-project',
- 'project.id': 1,
- 'span.description': 'AI generation',
- 'span.name': 'My AI Agent',
- 'span.op': 'gen_ai.generate',
- 'span.status': 'ok',
- span_id: 'span-both',
- trace: 'trace-both',
- 'gen_ai.operation.type': 'ai_client',
- },
- ],
- });
-
- const {result} = renderHookWithProviders(
- () => useConversation({conversationId: 'conv-both'}),
- {organization}
- );
-
- await waitFor(() => {
- expect(result.current.isLoading).toBe(false);
- });
-
- expect(result.current.nodes).toHaveLength(1);
- const node = result.current.nodes[0];
- const value = node?.value as {description?: string; name?: string};
- expect(value?.description).toBe('AI generation');
- expect(value?.name).toBe('AI generation');
- });
-
it('sorts nodes by start timestamp for AI spans list', async () => {
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/ai-conversations/conv-sort/`,
@@ -334,8 +289,7 @@ describe('useConversation', () => {
'precise.start_ts': 1001.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'Second by start, first by end',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'Second by start, first by end',
'span.status': 'ok',
span_id: 'span-b',
trace: 'trace-sort',
@@ -348,8 +302,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'First by start, second by end',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'First by start, second by end',
'span.status': 'ok',
span_id: 'span-a',
trace: 'trace-sort',
@@ -384,8 +337,7 @@ describe('useConversation', () => {
'precise.start_ts': 1000.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'AI generation',
- 'span.op': 'gen_ai.generate',
+ 'span.name': 'gen_ai.generate',
'span.status': 'ok',
span_id: 'span-ai',
trace: 'trace-1',
@@ -398,8 +350,7 @@ describe('useConversation', () => {
'precise.start_ts': 1001.0,
project: 'test-project',
'project.id': 1,
- 'span.description': 'HTTP request',
- 'span.op': 'http.client',
+ 'span.name': 'http.client',
'span.status': 'ok',
span_id: 'span-http',
trace: 'trace-1',
diff --git a/static/app/views/insights/pages/conversations/hooks/useConversation.tsx b/static/app/views/insights/pages/conversations/hooks/useConversation.tsx
index ab43380b1dfde5..97b8bd8fe3697c 100644
--- a/static/app/views/insights/pages/conversations/hooks/useConversation.tsx
+++ b/static/app/views/insights/pages/conversations/hooks/useConversation.tsx
@@ -6,7 +6,7 @@ import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import {useInfiniteApiQuery} from 'sentry/utils/queryClient';
import {useOrganization} from 'sentry/utils/useOrganization';
-import {getGenAiOperationTypeFromSpanOp} from 'sentry/views/insights/pages/agents/utils/query';
+import {getGenAiOperationTypeFromSpanName} from 'sentry/views/insights/pages/agents/utils/query';
import type {AITraceSpanNode} from 'sentry/views/insights/pages/agents/utils/types';
import {SpanFields} from 'sentry/views/insights/types';
import {EAPSpanNodeDetails} from 'sentry/views/performance/newTraceDetails/traceDrawer/details/span';
@@ -30,8 +30,7 @@ interface ConversationApiSpan {
'precise.start_ts': number;
project: string;
'project.id': number;
- 'span.description': string;
- 'span.op': string;
+ 'span.name': string;
'span.status': string;
span_id: string;
trace: string;
@@ -49,7 +48,8 @@ interface ConversationApiSpan {
'gen_ai.tool.input'?: string;
'gen_ai.tool.name'?: string;
'gen_ai.usage.total_tokens'?: number;
- 'span.name'?: string;
+ 'span.description'?: string;
+ 'span.op'?: string;
'user.email'?: string;
'user.id'?: string;
'user.ip'?: string;
@@ -60,7 +60,7 @@ function isGenAiSpan(span: ConversationApiSpan): boolean {
if (span['gen_ai.operation.type']) {
return true;
}
- return span['span.op']?.startsWith('gen_ai.') ?? false;
+ return span['span.name']?.startsWith('gen_ai.') ?? false;
}
interface UseConversationResult {
@@ -80,7 +80,7 @@ function createNodeFromApiSpan(
): AITraceSpanNode {
const operationType =
apiSpan['gen_ai.operation.type'] ||
- getGenAiOperationTypeFromSpanOp(apiSpan['span.op']);
+ getGenAiOperationTypeFromSpanName(apiSpan['span.name']);
const duration = apiSpan['precise.finish_ts'] - apiSpan['precise.start_ts'];
const value: TraceTree.EAPSpan = {
@@ -89,8 +89,8 @@ function createNodeFromApiSpan(
event_id: apiSpan.span_id,
event_type: 'span',
is_transaction: false,
- op: apiSpan['span.op'],
- description: apiSpan['span.description'] || apiSpan['span.name'],
+ op: apiSpan['span.name'],
+ description: apiSpan['span.name'],
start_timestamp: apiSpan['precise.start_ts'],
end_timestamp: apiSpan['precise.finish_ts'],
project_id: apiSpan['project.id'],
@@ -101,7 +101,7 @@ function createNodeFromApiSpan(
sdk_name: '',
transaction: '',
transaction_id: '',
- name: apiSpan['span.description'] || apiSpan['span.name'] || '',
+ name: apiSpan['span.name'] || '',
errors: [],
occurrences: [],
additional_attributes: {
diff --git a/static/app/views/insights/pages/conversations/overview.tsx b/static/app/views/insights/pages/conversations/overview.tsx
index 27d83b4b9519c6..64a1ec9cd0390c 100644
--- a/static/app/views/insights/pages/conversations/overview.tsx
+++ b/static/app/views/insights/pages/conversations/overview.tsx
@@ -105,9 +105,7 @@ function ConversationsContent({datePageFilterProps}: ConversationsOverviewPagePr
unsetCursor();
},
searchSource: 'conversations',
- replaceRawSearchKeys: hasRawSearchReplacement
- ? ['span.description', 'span.name']
- : undefined,
+ replaceRawSearchKeys: hasRawSearchReplacement ? ['span.name'] : undefined,
matchKeySuggestions: [
{key: 'trace', valuePattern: /^[0-9a-fA-F]{32}$/},
{key: 'id', valuePattern: /^[0-9a-fA-F]{16}$/},
diff --git a/static/app/views/insights/pages/mcp/components/mcpOverviewTable.tsx b/static/app/views/insights/pages/mcp/components/mcpOverviewTable.tsx
index bed2137d6daabb..edb53084af3b5a 100644
--- a/static/app/views/insights/pages/mcp/components/mcpOverviewTable.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpOverviewTable.tsx
@@ -53,7 +53,7 @@ const rightAlignColumns = new Set([
export function McpOverviewTable() {
const organization = useOrganization();
const {selection} = usePageFilters();
- const query = useCombinedQuery('span.op:mcp.server');
+ const query = useCombinedQuery('span.name:mcp.server');
const {tableSort} = useTableSort();
const tableDataRequest = useSpanTableData({
query,
@@ -188,7 +188,7 @@ function SpanDescriptionCell({
fields.push('timestamp');
const search = new MutableSearch('');
- search.addFilterValue(SpanFields.SPAN_OP, 'mcp.server');
+ search.addFilterValue(SpanFields.NAME, 'mcp.server');
search.addFilterValue(SpanFields.SPAN_DESCRIPTION, spanDescription);
const link = getExploreUrl({
organization,
diff --git a/static/app/views/insights/pages/mcp/components/mcpPromptDurationWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpPromptDurationWidget.tsx
index 6d47b35ba4c19c..c35d3c1c96ef99 100644
--- a/static/app/views/insights/pages/mcp/components/mcpPromptDurationWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpPromptDurationWidget.tsx
@@ -8,7 +8,7 @@ export function McpPromptDurationWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpPromptErrorRateWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpPromptErrorRateWidget.tsx
index bcbbafaf18006a..337557d2e1ed40 100644
--- a/static/app/views/insights/pages/mcp/components/mcpPromptErrorRateWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpPromptErrorRateWidget.tsx
@@ -8,7 +8,7 @@ export function McpPromptErrorRateWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpPromptTrafficWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpPromptTrafficWidget.tsx
index 384bc2d637f43a..1ea0a992182ff9 100644
--- a/static/app/views/insights/pages/mcp/components/mcpPromptTrafficWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpPromptTrafficWidget.tsx
@@ -8,7 +8,7 @@ export function McpPromptTrafficWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpPromptsTable.tsx b/static/app/views/insights/pages/mcp/components/mcpPromptsTable.tsx
index 8095888965e3e7..7cbae00cff0706 100644
--- a/static/app/views/insights/pages/mcp/components/mcpPromptsTable.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpPromptsTable.tsx
@@ -49,7 +49,9 @@ const rightAlignColumns = new Set([
export function McpPromptsTable() {
const organization = useOrganization();
const {selection} = usePageFilters();
- const query = useCombinedQuery(`span.op:mcp.server has:${SpanFields.MCP_PROMPT_NAME}`);
+ const query = useCombinedQuery(
+ `span.name:mcp.server has:${SpanFields.MCP_PROMPT_NAME}`
+ );
const {tableSort} = useTableSort();
const tableDataRequest = useSpanTableData({
query,
@@ -155,7 +157,7 @@ function McpPromptCell({prompt}: {prompt: string}) {
const {selection} = usePageFilters();
const search = new MutableSearch('');
- search.addFilterValue(SpanFields.SPAN_OP, 'mcp.server');
+ search.addFilterValue(SpanFields.NAME, 'mcp.server');
search.addFilterValue(SpanFields.MCP_PROMPT_NAME, prompt);
const link = getExploreUrl({
@@ -169,7 +171,7 @@ function McpPromptCell({prompt}: {prompt: string}) {
},
],
field: [
- 'span.description',
+ 'span.name',
'span.status',
'mcp.prompt.result.message_content',
'span.duration',
diff --git a/static/app/views/insights/pages/mcp/components/mcpResourceDurationWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpResourceDurationWidget.tsx
index f2e55e7e1b919e..21f70f0fb9b145 100644
--- a/static/app/views/insights/pages/mcp/components/mcpResourceDurationWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpResourceDurationWidget.tsx
@@ -8,7 +8,7 @@ export function McpResourceDurationWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpResourceErrorRateWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpResourceErrorRateWidget.tsx
index 403a668e9639f5..b08403858d4a0e 100644
--- a/static/app/views/insights/pages/mcp/components/mcpResourceErrorRateWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpResourceErrorRateWidget.tsx
@@ -8,7 +8,7 @@ export function McpResourceErrorRateWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpResourceTrafficWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpResourceTrafficWidget.tsx
index b48ce520ab8d76..094ce53f3791f6 100644
--- a/static/app/views/insights/pages/mcp/components/mcpResourceTrafficWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpResourceTrafficWidget.tsx
@@ -8,7 +8,7 @@ export function McpResourceTrafficWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpResourcesTable.tsx b/static/app/views/insights/pages/mcp/components/mcpResourcesTable.tsx
index 2333e9be2c663e..3c54945a369464 100644
--- a/static/app/views/insights/pages/mcp/components/mcpResourcesTable.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpResourcesTable.tsx
@@ -49,7 +49,9 @@ const rightAlignColumns = new Set([
export function McpResourcesTable() {
const organization = useOrganization();
const {selection} = usePageFilters();
- const query = useCombinedQuery(`span.op:mcp.server has:${SpanFields.MCP_RESOURCE_URI}`);
+ const query = useCombinedQuery(
+ `span.name:mcp.server has:${SpanFields.MCP_RESOURCE_URI}`
+ );
const {tableSort} = useTableSort();
const tableDataRequest = useSpanTableData({
query,
@@ -155,7 +157,7 @@ function McpResourceCell({resource}: {resource: string}) {
const {selection} = usePageFilters();
const search = new MutableSearch('');
- search.addFilterValue(SpanFields.SPAN_OP, 'mcp.server');
+ search.addFilterValue(SpanFields.NAME, 'mcp.server');
search.addFilterValue(SpanFields.MCP_RESOURCE_URI, resource);
const link = getExploreUrl({
@@ -168,7 +170,7 @@ function McpResourceCell({resource}: {resource: string}) {
yAxes: ['count(span.duration)'],
},
],
- field: ['span.description', 'span.status', 'span.duration', 'timestamp'],
+ field: ['span.name', 'span.status', 'span.duration', 'timestamp'],
query: search.formatString(),
sort: '-count(span.duration)',
});
diff --git a/static/app/views/insights/pages/mcp/components/mcpToolDurationWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpToolDurationWidget.tsx
index d251bd0d543b69..75b7010cd252a0 100644
--- a/static/app/views/insights/pages/mcp/components/mcpToolDurationWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpToolDurationWidget.tsx
@@ -8,7 +8,7 @@ export function McpToolDurationWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpToolErrorRateWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpToolErrorRateWidget.tsx
index 7c43da59813a3a..5384a71f25737e 100644
--- a/static/app/views/insights/pages/mcp/components/mcpToolErrorRateWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpToolErrorRateWidget.tsx
@@ -8,7 +8,7 @@ export function McpToolErrorRateWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpToolTrafficWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpToolTrafficWidget.tsx
index 888f549b1f4673..6b190c30474647 100644
--- a/static/app/views/insights/pages/mcp/components/mcpToolTrafficWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpToolTrafficWidget.tsx
@@ -8,7 +8,7 @@ export function McpToolTrafficWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpToolsTable.tsx b/static/app/views/insights/pages/mcp/components/mcpToolsTable.tsx
index ea354119626608..e37aea7b5f7809 100644
--- a/static/app/views/insights/pages/mcp/components/mcpToolsTable.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpToolsTable.tsx
@@ -49,7 +49,7 @@ const rightAlignColumns = new Set([
export function McpToolsTable() {
const organization = useOrganization();
const {selection} = usePageFilters();
- const query = useCombinedQuery(`span.op:mcp.server has:${SpanFields.MCP_TOOL_NAME}`);
+ const query = useCombinedQuery(`span.name:mcp.server has:${SpanFields.MCP_TOOL_NAME}`);
const {tableSort} = useTableSort();
const tableDataRequest = useSpanTableData({
query,
@@ -155,7 +155,7 @@ function McpToolCell({tool}: {tool: string}) {
const {selection} = usePageFilters();
const search = new MutableSearch('');
- search.addFilterValue(SpanFields.SPAN_OP, 'mcp.server');
+ search.addFilterValue(SpanFields.NAME, 'mcp.server');
search.addFilterValue(SpanFields.MCP_TOOL_NAME, tool);
const link = getExploreUrl({
@@ -170,7 +170,7 @@ function McpToolCell({tool}: {tool: string}) {
],
query: search.formatString(),
sort: '-count(span.duration)',
- field: ['span.description', 'mcp.tool.result.content', 'span.duration', 'timestamp'],
+ field: ['span.name', 'mcp.tool.result.content', 'span.duration', 'timestamp'],
});
return {tool};
}
diff --git a/static/app/views/insights/pages/mcp/components/mcpTrafficByClientWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpTrafficByClientWidget.tsx
index e4888d910c04b1..80e1e4df050d5a 100644
--- a/static/app/views/insights/pages/mcp/components/mcpTrafficByClientWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpTrafficByClientWidget.tsx
@@ -8,7 +8,7 @@ export function McpTrafficByClientWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/components/mcpTransportWidget.tsx b/static/app/views/insights/pages/mcp/components/mcpTransportWidget.tsx
index 6d6e2780fb55da..ca9fa313d96c8c 100644
--- a/static/app/views/insights/pages/mcp/components/mcpTransportWidget.tsx
+++ b/static/app/views/insights/pages/mcp/components/mcpTransportWidget.tsx
@@ -8,7 +8,7 @@ export function McpTransportWidget() {
);
diff --git a/static/app/views/insights/pages/mcp/hooks/useMcpSpanSearchProps.tsx b/static/app/views/insights/pages/mcp/hooks/useMcpSpanSearchProps.tsx
index 667d8fac341346..8ebcda9629b3db 100644
--- a/static/app/views/insights/pages/mcp/hooks/useMcpSpanSearchProps.tsx
+++ b/static/app/views/insights/pages/mcp/hooks/useMcpSpanSearchProps.tsx
@@ -29,9 +29,7 @@ export function useMcpSpanSearchProps() {
},
searchSource: 'mcp-monitoring',
- replaceRawSearchKeys: hasRawSearchReplacement
- ? ['span.description', 'span.name']
- : undefined,
+ replaceRawSearchKeys: hasRawSearchReplacement ? ['span.name'] : undefined,
matchKeySuggestions: [
{key: 'trace', valuePattern: /^[0-9a-fA-F]{32}$/},
{key: 'id', valuePattern: /^[0-9a-fA-F]{16}$/},
diff --git a/static/app/views/insights/pages/mcp/onboarding.tsx b/static/app/views/insights/pages/mcp/onboarding.tsx
index 439c72f06be484..4e5fbccb13cab7 100644
--- a/static/app/views/insights/pages/mcp/onboarding.tsx
+++ b/static/app/views/insights/pages/mcp/onboarding.tsx
@@ -70,7 +70,7 @@ function useAiSpanWaiter(project: Project) {
const request = useSpans(
{
- search: 'span.op:"gen_ai.*"',
+ search: 'span.name:"gen_ai.*"',
fields: ['id'],
limit: 1,
enabled: !!project,
diff --git a/static/app/views/insights/pages/mcp/utils/mcpTraceNodes.tsx b/static/app/views/insights/pages/mcp/utils/mcpTraceNodes.tsx
index fa1d0156ea758b..3adfa103665594 100644
--- a/static/app/views/insights/pages/mcp/utils/mcpTraceNodes.tsx
+++ b/static/app/views/insights/pages/mcp/utils/mcpTraceNodes.tsx
@@ -1,5 +1,7 @@
import type {BaseNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode';
export function getIsMCPNode(node: BaseNode) {
- return node.op?.startsWith('mcp.');
+ const name =
+ node.value && 'name' in node.value ? (node.value.name as string) : undefined;
+ return name?.startsWith('mcp.') ?? false;
}
diff --git a/static/app/views/performance/newTraceDetails/traceRow/traceEAPSpanRow.tsx b/static/app/views/performance/newTraceDetails/traceRow/traceEAPSpanRow.tsx
index 424899673a5d95..02f10fec8ba04e 100644
--- a/static/app/views/performance/newTraceDetails/traceRow/traceEAPSpanRow.tsx
+++ b/static/app/views/performance/newTraceDetails/traceRow/traceEAPSpanRow.tsx
@@ -8,7 +8,7 @@ import {
} from 'sentry/views/insights/pages/agents/utils/aiTraceNodes';
import {
GenAiOperationType,
- getGenAiOperationTypeFromSpanOp,
+ getGenAiOperationTypeFromSpanName,
} from 'sentry/views/insights/pages/agents/utils/query';
import {SpanFields} from 'sentry/views/insights/types';
import {TraceIcons} from 'sentry/views/performance/newTraceDetails/traceIcons';
@@ -36,7 +36,7 @@ function getAIEnhancedDescription(node: EapSpanNode): string | undefined {
const opType =
(attrs[SpanFields.GEN_AI_OPERATION_TYPE] as string | undefined) ??
- getGenAiOperationTypeFromSpanOp(node.op);
+ getGenAiOperationTypeFromSpanName(node.value.name);
if (!opType) {
return undefined;