Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
515ad1e
[EA] Add rich renderer for security entity attachments
opauloh Apr 21, 2026
fee3130
This commit has a draft version of entity analytics in chat + some fi…
YulNaumenko Apr 21, 2026
bc082df
[EA] Expand entity attachment with rich sub-sections and follow-up ac…
opauloh Apr 21, 2026
a79cd4e
reverting agent build changes
opauloh Apr 21, 2026
4d34457
fixed card and navigate to Entity page with chat
YulNaumenko Apr 22, 2026
63204d4
fixed dashboard and links to chat
YulNaumenko Apr 22, 2026
58ff2c3
[EA] Add data source filtering and inline table attachments for entit…
opauloh Apr 22, 2026
f8849e0
[EA] Improve entity resolution and attachment logic in get_entity tool
opauloh Apr 22, 2026
400f787
[EA] Fix rendering and parsing issues for entity attachments in Agent…
opauloh Apr 22, 2026
a28e0bd
[EA] Enrich entity attachments with detailed risk and resolution stat…
opauloh Apr 22, 2026
944ca6f
[EA] Improve entity table legibility in chat with horizontal scrolling
opauloh Apr 22, 2026
a9d7ba1
[EA] Use canonical entity IDs for more reliable entity attachment res…
opauloh Apr 22, 2026
347aed6
[EA] Use record timestamp for more reliable "Last seen" in entity table
opauloh Apr 22, 2026
6e5cd78
Merge branch 'entity-analytics-in-chat' into ea/chat-first-exp-combined
opauloh Apr 22, 2026
937a289
revert temporary changes
opauloh Apr 22, 2026
96a83ee
Merge branch 'main' into ea/chat-first-exp-combined
opauloh Apr 22, 2026
1d4df71
[EA] Refine entity analytics prompt to prevent redundant markdown output
opauloh Apr 22, 2026
b130775
[EA] Refine dashboard trigger logic in entity analytics skill
opauloh Apr 22, 2026
0f5eb17
Changes from node scripts/lint.js --fix
kibanamachine Apr 22, 2026
59ae2fc
[EA] Implement rich entity renderer and canvas preview for security e…
opauloh Apr 22, 2026
2f53661
[EA] Implement responsive layout for entity analytics dashboard risk …
opauloh Apr 22, 2026
b8eac09
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Apr 22, 2026
d59e79f
[EA] Enhance entity attachment rendering and search precision in AI a…
opauloh Apr 23, 2026
c2f222b
Merge remote-tracking branch 'origin/ea/chat-first-exp-combined' into…
opauloh Apr 23, 2026
0ca2e20
[EA] Clear search session before navigating from Agent Builder to Sec…
opauloh Apr 23, 2026
d5be8d6
Implement lazy loading pattern on Canvas-content
opauloh Apr 23, 2026
46f3022
fix lint errors
opauloh Apr 23, 2026
4f80cfe
remove unnecessary border
opauloh Apr 23, 2026
d5d4961
adding lazy loading on entity attachments
opauloh Apr 23, 2026
7fd3bf4
Changes from node scripts/lint_ts_projects --fix
kibanamachine Apr 23, 2026
6d72eb1
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine Apr 23, 2026
ef02834
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Apr 23, 2026
d707e59
Enhance entity attachment functionality and improve error handling
opauloh Apr 23, 2026
830a6de
Refine time range label handling in entity analytics skill documentation
opauloh Apr 23, 2026
cf7c8be
add pagination overrides
opauloh Apr 23, 2026
4a3b68b
Merge remote-tracking branch 'origin/ea/chat-first-exp-combined' into…
opauloh Apr 23, 2026
fff9188
fix type errors
opauloh Apr 23, 2026
89b1ee4
Refactor entity attachment components and tests for improved clarity …
opauloh Apr 23, 2026
82b2d74
reverting change
opauloh Apr 23, 2026
808f273
Merge branch 'main' into ea/chat-first-exp-combined
opauloh Apr 23, 2026
c47b7db
fixing unit test
opauloh Apr 23, 2026
c5302f3
Enhance entity analytics tool with sorting capabilities and parameter…
opauloh Apr 23, 2026
7117cbf
Add unit tests for EntityCardActions component
opauloh Apr 23, 2026
5e816db
addressing PR feedbacks
opauloh Apr 23, 2026
8d32538
Enhance entity analytics tool with improved risk score handling and s…
opauloh Apr 23, 2026
d04c9b9
updating Entity Store default feature flag behavior
opauloh Apr 23, 2026
535fab8
Refactor EntityListTable to improve label display
opauloh Apr 23, 2026
2db55cf
addressing pr review feedback about incorporating user.name and host.…
opauloh Apr 23, 2026
ea3d7c4
adding clarification about the resolution target candidates
opauloh Apr 23, 2026
987d2b1
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Apr 23, 2026
8f97128
Merge branch 'main' into ea/chat-first-exp-combined
opauloh Apr 23, 2026
c3ba9b8
revert on entity flyout changes
opauloh Apr 23, 2026
f772eeb
Add canvas width configuration for Entity Analytics and Entity Attach…
opauloh Apr 23, 2026
df35c46
Refactor experimental features and attachment registration
opauloh Apr 23, 2026
84cfec9
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Apr 24, 2026
3d9daa7
entity risk level chart improvements
opauloh Apr 24, 2026
8a14f90
update links to the explore page to open the entity analytics flyout …
opauloh Apr 24, 2026
89a37a5
closing dashboard attachment when opening the entity flyout
opauloh Apr 24, 2026
5412402
adding one more option to entity.source
opauloh Apr 24, 2026
9458cbc
adding link to job id in entity analytics
opauloh Apr 24, 2026
13b8f2a
Merge remote-tracking branch 'origin/ea/chat-first-exp-combined' into…
opauloh Apr 24, 2026
046217c
Merge branch 'ea-page-ux-improvements-chart-only' into ea/chat-first-…
opauloh Apr 24, 2026
56fa7de
removing datetime picker from the entity analytics table
opauloh Apr 24, 2026
cf00549
Changes from node scripts/lint.js --fix
kibanamachine Apr 24, 2026
48f383a
updating show more badge and alerts fetching
opauloh Apr 24, 2026
bff01f2
Merge remote-tracking branch 'origin/ea/chat-first-exp-combined' into…
opauloh Apr 24, 2026
07b9453
Merge remote-tracking branch 'upstream/main' into ea/chat-first-exp-c…
opauloh Apr 24, 2026
22216b9
Changes from node scripts/styled_components_mapping
kibanamachine Apr 24, 2026
0b7b6fa
fix ci type error
opauloh Apr 24, 2026
66b2912
Merge remote-tracking branch 'origin/ea/chat-first-exp-combined' into…
opauloh Apr 24, 2026
8bbc181
revert styled components usage
opauloh Apr 24, 2026
28d70fa
Merge remote-tracking branch 'origin/main' into ea/chat-first-exp-com…
jaredburgettelastic Apr 24, 2026
a6406ea
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Apr 24, 2026
aff44b1
Merge branch 'main' into ea/chat-first-exp-combined
enriquesanchez-elastic Apr 24, 2026
7939735
Fix useIntervalForHeatmap tests passing numeric timestamps instead of…
hop-dev Apr 24, 2026
525b709
[Entity Analytics] Default pageIndex for flyout-driven home URLs
hop-dev Apr 24, 2026
2eba3a9
[Entity Analytics] Preserve URL state when opening flyout from Agent …
hop-dev Apr 24, 2026
acc31db
Fix accidentally reverted prebuiltRulesDeprecationUIEnabled flag
hop-dev Apr 24, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { ReactNode } from 'react';
import React from 'react';
import { DEFAULTS, useFetchAnonymizationFields } from './use_fetch_anonymization_fields';
import type { HttpSetup } from '@kbn/core-http-browser';
import { useAssistantContext } from '../../../assistant_context';
import { useMaybeAssistantContext } from '../../../assistant_context';
import { API_VERSIONS, defaultAssistantFeatures } from '@kbn/elastic-assistant-common';

const http = {
Expand All @@ -30,7 +30,7 @@ const createWrapper = () => {
};

describe('useFetchAnonymizationFields', () => {
(useAssistantContext as jest.Mock).mockReturnValue({
(useMaybeAssistantContext as jest.Mock).mockReturnValue({
http,
assistantAvailability: {
isAssistantEnabled: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
ELASTIC_AI_ASSISTANT_ANONYMIZATION_FIELDS_URL_FIND,
API_VERSIONS,
} from '@kbn/elastic-assistant-common';
import { useAssistantContext } from '../../../assistant_context';
import { useMaybeAssistantContext } from '../../../assistant_context';

export interface UseFetchAnonymizationFieldsParams {
page?: number; // API uses 1-based index
Expand Down Expand Up @@ -85,13 +85,15 @@ export const useFetchAnonymizationFields = (
filter,
} = params || {};

const {
http,
assistantAvailability: { isAssistantEnabled },
} = useAssistantContext();
const assistantContext = useMaybeAssistantContext();
const http = assistantContext?.http;
const isAssistantEnabled = assistantContext?.assistantAvailability.isAssistantEnabled ?? false;

const fetchPage = useCallback(
async ({ pageParam = { page, perPage, sortField, sortOrder, filter, all } }) => {
if (!http) {
throw new Error('useFetchAnonymizationFields requires AssistantProvider when fetching');
}
const {
page: p = page,
perPage: pp = perPage,
Expand Down Expand Up @@ -122,6 +124,8 @@ export const useFetchAnonymizationFields = (
[page, perPage, sortField, sortOrder, filter, all, http, signal]
);

const queryEnabled = Boolean(http) && isAssistantEnabled;

// Next page param: include current sorting in next request
const getNextPageParam = useCallback(
(lastPage: FindAnonymizationFieldsResponse) => {
Expand Down Expand Up @@ -155,7 +159,7 @@ export const useFetchAnonymizationFields = (
FindAnonymizationFieldsResponse
>(CACHING_KEYS, fetchPage, {
getNextPageParam,
enabled: isAssistantEnabled,
enabled: queryEnabled,
refetchOnWindowFocus: true,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ export const useAssistantContext = () => {
return context;
};

/**
* Same context as {@link useAssistantContext}, but returns `undefined` when no provider is present.
* Prefer {@link useAssistantContext} for assistant UI; use this only when a hook must degrade
* gracefully outside `AssistantProvider` (e.g. embedded previews).
*/
export const useMaybeAssistantContext = (): UseAssistantContext | undefined =>
React.useContext(AssistantContext);

export const useAssistantContextValue = (props: AssistantProviderProps): UseAssistantContext => {
const {
actionTypeRegistry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
// happens in the root of your app. Optionally provide a custom title for the assistant:

/** provides context (from the app) to the assistant, and injects Kibana services, like `http` */
export { AssistantProvider, useAssistantContext } from './impl/assistant_context';
export {
AssistantProvider,
useAssistantContext,
useMaybeAssistantContext,
} from './impl/assistant_context';

// Step 2.1: Add the `AssistantOverlay` component to your app. This component displays the assistant
// overlay in a modal, bound to a shortcut key:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 { agentBuilderDefaultAgentId } from '@kbn/agent-builder-common';

import {
consumePreserveAgentBuilderSessionGate,
markPreserveAgentBuilderSessionDuringNextSecurityNavigation,
readLastAgentBuilderAgentIdForSecuritySession,
} from './agent_builder_navigation_gate';

describe('agent_builder_navigation_gate', () => {
beforeEach(() => {
sessionStorage.clear();
localStorage.clear();
});

it('consume returns false when not marked', () => {
expect(consumePreserveAgentBuilderSessionGate()).toBe(false);
expect(consumePreserveAgentBuilderSessionGate()).toBe(false);
});

it('consume returns true once after mark', () => {
markPreserveAgentBuilderSessionDuringNextSecurityNavigation();
expect(consumePreserveAgentBuilderSessionGate()).toBe(true);
expect(consumePreserveAgentBuilderSessionGate()).toBe(false);
});

it('readLastAgentBuilderAgentIdForSecuritySession falls back to default', () => {
expect(readLastAgentBuilderAgentIdForSecuritySession()).toBe(agentBuilderDefaultAgentId);
});

it('readLastAgentBuilderAgentIdForSecuritySession reads raw string from localStorage', () => {
localStorage.setItem('agentBuilder.agentId', 'my-agent');
expect(readLastAgentBuilderAgentIdForSecuritySession()).toBe('my-agent');
});

it('readLastAgentBuilderAgentIdForSecuritySession parses JSON-encoded string', () => {
localStorage.setItem('agentBuilder.agentId', JSON.stringify('json-agent'));
expect(readLastAgentBuilderAgentIdForSecuritySession()).toBe('json-agent');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 { agentBuilderDefaultAgentId } from '@kbn/agent-builder-common';

/** Same as agent_builder `storageKeys.agentId`. */
const AGENT_BUILDER_LAST_AGENT_ID_STORAGE_KEY = 'agentBuilder.agentId';

/**
* Session flag: the next Security app effect teardown is from an in-app navigation that must not
* clear Agent Builder session state (e.g. "Open entity in Security" from an attachment).
*/
const IN_APP_NAV_PRESERVE_AGENT_BUILDER_SESSION_KEY =
'securitySolution.preserveAgentBuilderSessionDuringInAppNav';

export const readLastAgentBuilderAgentIdForSecuritySession = (): string => {
if (typeof window === 'undefined' || window.localStorage == null) {
return agentBuilderDefaultAgentId;
}
const stored = window.localStorage.getItem(AGENT_BUILDER_LAST_AGENT_ID_STORAGE_KEY);
if (stored == null || stored === '') {
return agentBuilderDefaultAgentId;
}
try {
const parsed = JSON.parse(stored);
return typeof parsed === 'string' ? parsed : stored;
} catch {
return stored;
}
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
};

export const markPreserveAgentBuilderSessionDuringNextSecurityNavigation = (): void => {
try {
window.sessionStorage?.setItem(IN_APP_NAV_PRESERVE_AGENT_BUILDER_SESSION_KEY, '1');
} catch {
// private mode / quota
}
};

/**
* Returns true once if a preserve gate was set (and clears it). Idempotent per consume call.
*/
export const consumePreserveAgentBuilderSessionGate = (): boolean => {
try {
if (window.sessionStorage?.getItem(IN_APP_NAV_PRESERVE_AGENT_BUILDER_SESSION_KEY) === '1') {
window.sessionStorage.removeItem(IN_APP_NAV_PRESERVE_AGENT_BUILDER_SESSION_KEY);
return true;
}
} catch {
// ignore
}
return false;
};
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ export const ESSENTIAL_ALERT_FIELDS: string[] = [
export enum SecurityAgentBuilderAttachments {
alert = 'security.alert',
entity = 'security.entity',
entityAnalyticsDashboard = 'security.entity_analytics_dashboard',
rule = 'security.rule',
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ dependsOn:
- '@kbn/shared-ux-column-presets'
- '@kbn/core-overlays-browser'
- '@kbn/workflows-management-plugin'
- '@kbn/core-application-browser-mocks'
tags:
- plugin
- prod
Expand Down
Loading
Loading