Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cc0410c
Attachment for APM error (inline)
viduni94 Nov 20, 2025
3a28d9a
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Nov 24, 2025
1ccbfd1
Use feature flag to determine which contextual insights to show
viduni94 Nov 24, 2025
35603e5
Use feature flag to determine which contextual insights to show
viduni94 Nov 24, 2025
10483ab
Introduce tools to fetch error details when needed for the error atta…
viduni94 Nov 24, 2025
8f8c78f
Update tool name
viduni94 Nov 24, 2025
a3d5ed8
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Nov 25, 2025
4982c72
Finalize prompts and instructions
viduni94 Nov 25, 2025
5da195b
Optionally test with Obs Agent
viduni94 Nov 25, 2025
af0ac1d
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Nov 26, 2025
3bb2c87
Inline contextual insights summary
viduni94 Nov 27, 2025
3cf2b6e
Inline contextual insights summary
viduni94 Nov 27, 2025
aee61ef
Remove attachment-specific tools
viduni94 Nov 27, 2025
6ee9a8e
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Nov 27, 2025
fbf77c1
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Nov 28, 2025
f77d911
Use common component and rename folders to agent_builder
viduni94 Nov 28, 2025
cbff403
Consume common attachment
viduni94 Nov 28, 2025
1d5a789
Remove error attachment
viduni94 Nov 28, 2025
ad40e30
Revert minor change
viduni94 Nov 28, 2025
de7aa86
Update route folder
viduni94 Nov 28, 2025
22f8f7a
Remove unused tools
viduni94 Nov 28, 2025
0cefbe2
Update attachment ID
viduni94 Nov 28, 2025
8cbf990
Update descriptions
viduni94 Nov 28, 2025
dac8c5b
Rename file
viduni94 Nov 28, 2025
6ee275c
Add todos
viduni94 Nov 28, 2025
3f61d56
Remove extra newline
viduni94 Nov 28, 2025
68d173e
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Dec 2, 2025
58787be
Fix conflicts
viduni94 Dec 3, 2025
49e4ace
Update return type
viduni94 Dec 3, 2025
e97411b
Use hook exposed by agent builder for connector selection
viduni94 Dec 3, 2025
68cc56f
Use hook exposed by agent builder for connector selection
viduni94 Dec 3, 2025
3299c90
Use data registry and move the error AI insights route to the observa…
viduni94 Dec 3, 2025
1b33932
Bring back the error attachment
viduni94 Dec 3, 2025
e224c63
Add server-side system prompt
viduni94 Dec 3, 2025
d3f9665
Attach error when the flyout is opened from that page
viduni94 Dec 3, 2025
6b822e9
Add comment
viduni94 Dec 3, 2025
7afd665
Add guardrail
viduni94 Dec 3, 2025
08c553a
Add data fetchers
viduni94 Dec 4, 2025
42c338a
Remove comment
viduni94 Dec 4, 2025
185c3c4
Merge branch 'main' into agent-builder-error-sample-contextual-insights
viduni94 Dec 4, 2025
a8adac0
Changes from node scripts/lint_ts_projects --fix
kibanamachine Dec 4, 2025
d8a8a2d
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine Dec 4, 2025
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: 2 additions & 0 deletions x-pack/platform/plugins/shared/onechat/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ export const plugin: PluginInitializer<
> = (pluginInitializerContext: PluginInitializerContext<ConfigSchema>) => {
return new OnechatPlugin(pluginInitializerContext);
};

export { useConnectorSelection } from './application/hooks/chat/use_connector_selection';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

// Duplicate of the attachment type ID defined in @kbn/observability-agent-plugin/server/attachments
// Re-defined here to avoid cross-plugin dependency cycles
export const OBSERVABILITY_AI_INSIGHT_ATTACHMENT_TYPE_ID = 'observability.ai_insight';
export const OBSERVABILITY_ERROR_ATTACHMENT_TYPE_ID = 'observability.error';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { CoreStart } from '@kbn/core/public';
import {
OBSERVABILITY_AGENT_FEATURE_FLAG,
OBSERVABILITY_AGENT_FEATURE_FLAG_DEFAULT,
} from './feature_flag';

export function getIsObservabilityAgentEnabled(coreStart: CoreStart): boolean {
return coreStart.featureFlags.getBooleanValue(
OBSERVABILITY_AGENT_FEATURE_FLAG,
OBSERVABILITY_AGENT_FEATURE_FLAG_DEFAULT
);
}
13 changes: 11 additions & 2 deletions x-pack/solutions/observability/plugins/apm/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,17 @@
"observabilityAIAssistant",
"observabilityAgent",
"share",
"onechat"
"onechat",
"inference"
],
"requiredBundles": ["fleet", "kibanaReact", "kibanaUtils", "ml", "observability", "maps"]
"requiredBundles": [
"fleet",
"kibanaReact",
"kibanaUtils",
"ml",
"observability",
"maps",
"onechat"
]
}
}
2 changes: 2 additions & 0 deletions x-pack/solutions/observability/plugins/apm/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ dependsOn:
- '@kbn/onechat-server'
- '@kbn/onechat-common'
- '@kbn/onechat-plugin'
- '@kbn/observability-agent-builder'
- '@kbn/observability-agent-plugin'
- '@kbn/inference-plugin'
tags:
- plugin
- prod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export const renderApp = ({
lens: pluginsStart.lens,
uiActions: pluginsStart.uiActions,
observabilityAIAssistant: pluginsStart.observabilityAIAssistant,
onechat: pluginsStart.onechat,
inference: pluginsStart.inference,
share: pluginsSetup.share,
kibanaEnvironment,
licensing: pluginsStart.licensing,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { i18n } from '@kbn/i18n';
import React, { useMemo, useState } from 'react';
import { EuiSpacer } from '@elastic/eui';
import { AiInsight } from '@kbn/observability-agent-builder';
import { useConnectorSelection } from '@kbn/onechat-plugin/public';
import {
OBSERVABILITY_AI_INSIGHT_ATTACHMENT_TYPE_ID,
OBSERVABILITY_ERROR_ATTACHMENT_TYPE_ID,
} from '../../../../../common/agent_builder/attachment_ids';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { getIsObservabilityAgentEnabled } from '../../../../../common/agent_builder/get_is_obs_agent_enabled';
import { useAnyOfApmParams } from '../../../../hooks/use_apm_params';
import { useTimeRange } from '../../../../hooks/use_time_range';
import type { APIReturnType } from '../../../../services/rest/create_call_apm_api';

export function ErrorSampleAgentBuilderAiInsight({
error,
transaction,
}: APIReturnType<'GET /internal/apm/services/{serviceName}/errors/{groupId}/error/{errorId}'>) {
const { onechat, core, inference } = useApmPluginContext();
const isObservabilityAgentEnabled = getIsObservabilityAgentEnabled(core);

const { query } = useAnyOfApmParams(
'/services/{serviceName}/errors/{groupId}',
'/mobile-services/{serviceName}/errors-and-crashes/errors/{groupId}',
'/mobile-services/{serviceName}/errors-and-crashes/crashes/{groupId}'
);
const { rangeFrom, rangeTo, environment, kuery } = query;
const { start, end } = useTimeRange({ rangeFrom, rangeTo });

const [isLoading, setIsLoading] = useState(false);
const [summary, setSummary] = useState('');
const [context, setContext] = useState('');

const { selectedConnector, defaultConnectorId } = useConnectorSelection();

const fetchAiInsights = async () => {
setIsLoading(true);
try {
const response = await core.http.post<{ summary: string; context: string }>(
'/internal/observability_agent_builder/ai_insights/error',
{
body: JSON.stringify({
serviceName: error.service.name,
errorId: error.error.id,
start,
end,
environment,
kuery,
connectorId: selectedConnector ?? defaultConnectorId ?? '',
}),
}
);

setSummary(response?.summary ?? '');
setContext(response?.context ?? '');
} catch (e) {
setSummary('');
setContext('');
} finally {
setIsLoading(false);
}
};

const attachments = useMemo(() => {
if (!onechat || !isObservabilityAgentEnabled) {
return [];
}

return [
{
id: 'apm_error_details_screen_context_attachment',
type: 'screen_context',
data: {
app: 'apm',
url: window.location.href,
description: `APM error details page for ${error.service.name}`,
},
hidden: true,
},
{
id: 'apm_error_details_ai_insight_attachment',
type: OBSERVABILITY_AI_INSIGHT_ATTACHMENT_TYPE_ID,
data: {
summary,
context,
},
},
{
id: 'apm_error_details_error_attachment',
type: OBSERVABILITY_ERROR_ATTACHMENT_TYPE_ID,
data: {
errorId: error.error.id,
serviceName: error.service.name,
environment,
start,
end,
},
},
];
}, [error, onechat, isObservabilityAgentEnabled, summary, context, environment, start, end]);

if (!onechat || !isObservabilityAgentEnabled || !inference) {
return <></>;
}

return (
<>
<AiInsight
title={i18n.translate('xpack.apm.errorAiInsight.titleLabel', {
defaultMessage: "What's this error?",
})}
description={i18n.translate('xpack.apm.errorAiInsight.descriptionLabel', {
defaultMessage: 'Get helpful insights from our Elastic AI Agent',
})}
content={summary}
isLoading={isLoading}
onOpen={fetchAiInsights}
onStartConversation={() => {
onechat.openConversationFlyout({
attachments,
sessionTag: 'apm-error-ai-insight',
newConversation: true,
});
}}
/>
<EuiSpacer size="s" />
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import { ErrorTabKey, getTabs } from './error_tabs';
import { ErrorUiActionsContextMenu } from './error_ui_actions_context_menu';
import { SampleSummary } from './sample_summary';
import { ErrorSampleContextualInsight } from './error_sample_contextual_insight';
import { ErrorSampleAgentBuilderAiInsight } from './error_sample_agent_builder_ai_insight';
import { getIsObservabilityAgentEnabled } from '../../../../../common/agent_builder/get_is_obs_agent_enabled';
import { getComparisonEnabled } from '../../../shared/time_comparison/get_comparison_enabled';
import { buildUrl } from '../../../../utils/build_url';
import { OpenErrorInDiscoverButton } from '../../../shared/links/discover_links/open_error_in_discover_button';
Expand Down Expand Up @@ -88,7 +90,8 @@ export function ErrorSampleDetails({
urlParams: { detailTab, offset, comparisonEnabled },
} = useLegacyUrlParams();

const { uiActions, core } = useApmPluginContext();
const { uiActions, core, onechat, inference } = useApmPluginContext();
const isObservabilityAgentEnabled = getIsObservabilityAgentEnabled(core);

const router = useApmRouter();

Expand Down Expand Up @@ -291,7 +294,11 @@ export function ErrorSampleDetails({
<SampleSummary error={error} />
)}

<ErrorSampleContextualInsight error={error} transaction={transaction} />
{onechat && inference && isObservabilityAgentEnabled ? (
<ErrorSampleAgentBuilderAiInsight error={error} transaction={transaction} />
) : (
<ErrorSampleContextualInsight error={error} transaction={transaction} />
)}

<EuiTabs>
{tabs.map(({ key, label }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import React, { useEffect } from 'react';
import { omit } from 'lodash';
import { useHistory } from 'react-router-dom';
import { usePerformanceContext } from '@kbn/ebt-tools';
import { OBSERVABILITY_ERROR_ATTACHMENT_TYPE_ID } from '../../../../common/agent_builder/attachment_ids';
import { isOpenTelemetryAgentName, isRumAgentName } from '../../../../common/agent_name';
import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
Expand All @@ -28,6 +29,7 @@ import { maybe } from '../../../../common/utils/maybe';
import { fromQuery, toQuery } from '../../shared/links/url_helpers';
import type { AgentName } from '../../../../typings/es_schemas/ui/fields/agent';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { getIsObservabilityAgentEnabled } from '../../../../common/agent_builder/get_is_obs_agent_enabled';

type ErrorSamplesAPIResponse =
APIReturnType<'GET /internal/apm/services/{serviceName}/errors/{groupId}/samples'>;
Expand Down Expand Up @@ -84,7 +86,8 @@ export function ErrorGroupDetails() {
const apmRouter = useApmRouter();
const history = useHistory();
const { onPageReady } = usePerformanceContext();
const { observabilityAIAssistant } = useApmPluginContext();
const { observabilityAIAssistant, onechat, core } = useApmPluginContext();
const isObservabilityAgentEnabled = getIsObservabilityAgentEnabled(core);

const {
path: { groupId },
Expand Down Expand Up @@ -198,6 +201,34 @@ export function ErrorGroupDetails() {
});
}, [observabilityAIAssistant, errorSamplesData.occurrencesCount, groupId]);

// Configure agent builder global flyout with the error attachment
useEffect(() => {
if (!onechat || !errorId || !isObservabilityAgentEnabled) {
return;
}

onechat.setConversationFlyoutActiveConfig({
newConversation: true,
attachments: [
{
id: errorId,
type: OBSERVABILITY_ERROR_ATTACHMENT_TYPE_ID,
data: {
errorId,
serviceName,
environment,
start,
end,
},
},
],
});

return () => {
onechat.clearConversationFlyoutActiveConfig();
};
}, [onechat, errorId, serviceName, environment, start, end, isObservabilityAgentEnabled]);

return (
<>
<EuiSpacer size={'s'} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public';
import type { SharePluginSetup } from '@kbn/share-plugin/public';
import type { OnechatPluginStart } from '@kbn/onechat-plugin/public';
import type { InferencePublicStart } from '@kbn/inference-plugin/public';
import type { LicensingPluginStart } from '@kbn/licensing-plugin/public';
import type { ApmPluginSetupDeps } from '../../plugin';
import type { ConfigSchema } from '../..';
Expand All @@ -38,6 +40,8 @@ export interface ApmPluginContextValue {
unifiedSearch: UnifiedSearchPublicPluginStart;
uiActions: UiActionsStart;
observabilityAIAssistant?: ObservabilityAIAssistantPublicStart;
onechat?: OnechatPluginStart;
inference?: InferencePublicStart;
share: SharePluginSetup;
kibanaEnvironment: KibanaEnvContext;
lens: LensPublicStart;
Expand Down
4 changes: 4 additions & 0 deletions x-pack/solutions/observability/plugins/apm/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/publ
import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import type { SharePublicStart } from '@kbn/share-plugin/public/plugin';
import type { ApmSourceAccessPluginStart } from '@kbn/apm-sources-access-plugin/public';
import type { OnechatPluginStart } from '@kbn/onechat-plugin/public';
import type { CasesPublicStart } from '@kbn/cases-plugin/public';
import type { InferencePublicStart } from '@kbn/inference-plugin/public';
import type {
DiscoverSharedPublicSetup,
DiscoverSharedPublicStart,
Expand Down Expand Up @@ -167,6 +169,8 @@ export interface ApmPluginStartDeps {
share?: SharePublicStart;
notifications: NotificationsStart;
discoverShared: DiscoverSharedPublicStart;
onechat?: OnechatPluginStart;
inference?: InferencePublicStart;
}

const applicationsTitle = i18n.translate('xpack.apm.navigation.rootTitle', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import type { CoreSetup, Logger } from '@kbn/core/server';
import type { BuiltinToolDefinition, StaticToolRegistration } from '@kbn/onechat-server';
import { ToolType } from '@kbn/onechat-common';
import { ToolResultType } from '@kbn/onechat-common/tools/tool_result';
import { timeRangeSchema } from './utils/tool_schemas';
import { buildApmToolResources } from './utils/build_apm_tool_resources';
import { getApmToolAvailability } from './utils/get_apm_tool_availability';
import { getApmDownstreamDependencies } from '../routes/assistant_functions/get_apm_downstream_dependencies';
import { OBSERVABILITY_GET_DOWNSTREAM_DEPENDENCIES_TOOL_ID } from '../../common/observability_agent/agent_tool_ids';
import type { APMPluginSetupDependencies, APMPluginStartDependencies } from '../types';
import { timeRangeSchema } from '../utils/tool_schemas';
import { buildApmToolResources } from '../utils/build_apm_tool_resources';
import { getApmToolAvailability } from '../utils/get_apm_tool_availability';
import { getApmDownstreamDependencies } from '../../routes/assistant_functions/get_apm_downstream_dependencies';
import { OBSERVABILITY_GET_DOWNSTREAM_DEPENDENCIES_TOOL_ID } from '../../../common/agent_builder/tool_ids';
import type { APMPluginSetupDependencies, APMPluginStartDependencies } from '../../types';

const getDownstreamDependenciesToolSchema = z.object({
...timeRangeSchema.shape,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import type { CoreSetup, Logger } from '@kbn/core/server';
import type { BuiltinToolDefinition, StaticToolRegistration } from '@kbn/onechat-server';
import { ToolType } from '@kbn/onechat-common';
import { ToolResultType } from '@kbn/onechat-common/tools/tool_result';
import { timeRangeSchema } from './utils/tool_schemas';
import { buildApmToolResources } from './utils/build_apm_tool_resources';
import { getApmToolAvailability } from './utils/get_apm_tool_availability';
import { getApmServiceList } from '../routes/assistant_functions/get_apm_service_list';
import type { APMPluginSetupDependencies, APMPluginStartDependencies } from '../types';
import { ServiceHealthStatus } from '../../common/service_health_status';
import { OBSERVABILITY_GET_SERVICES_TOOL_ID } from '../../common/observability_agent/agent_tool_ids';
import { timeRangeSchema } from '../utils/tool_schemas';
import { buildApmToolResources } from '../utils/build_apm_tool_resources';
import { getApmToolAvailability } from '../utils/get_apm_tool_availability';
import { getApmServiceList } from '../../routes/assistant_functions/get_apm_service_list';
import type { APMPluginSetupDependencies, APMPluginStartDependencies } from '../../types';
import { ServiceHealthStatus } from '../../../common/service_health_status';
import { OBSERVABILITY_GET_SERVICES_TOOL_ID } from '../../../common/agent_builder/tool_ids';

const getServicesSchema = z.object({
...timeRangeSchema.shape,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { CoreSetup, Logger } from '@kbn/core/server';
import type { StaticToolRegistration } from '@kbn/onechat-server';
import type { APMPluginStartDependencies, APMPluginSetupDependencies } from '../types';
import type { APMPluginStartDependencies, APMPluginSetupDependencies } from '../../types';
import { createDownstreamDependenciesTool } from './get_downstream_dependencies';
import { createGetServicesTool } from './get_services';

Expand Down
Loading