[SigEvents] Enable Knowledge Indicators generation from the KI tab#263822
[SigEvents] Enable Knowledge Indicators generation from the KI tab#263822cesco-f merged 14 commits intoelastic:mainfrom
Conversation
…red/ Mechanical move of reusable components (GenerateSplitButton, ContextMenuSplitButton, ConnectorSubPanel, context_menu_helpers, translations, types) into a shared/ directory so they can be consumed by the Knowledge Indicators tab. Original files deleted. Made-with: Cursor
Move bulk onboarding, connector config, and stream fetching into a shared KiGenerationProvider so both the Streams and Knowledge Indicators tabs consume one source of truth. Add an inline generation row with StreamPicker on the KI tab, a progress callout, and a hidden-computed- features hint. Fix broken imports in insights_split_button pointing at the old streams_view/ location. Made-with: Cursor
|
/ci |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughAdds a React context provider (KiGenerationProvider) and hook (useKiGeneration) to centralize knowledge-indicator generation state, status callbacks, and optimistic generation actions. Introduces useBulkOnboarding for concurrent scheduling and status-queue processing. Integrates generation controls (StreamPicker, GenerateSplitButton) into empty states and wiring into KnowledgeIndicatorsTable and StreamsView. Adds related components, translations, and refactors stream fetching and onboarding scheduling to consume the new provider API. Possibly related PRs
Suggested labels
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Tools execution failed with the following error: Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error) Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/streams_view.tsx`:
- Around line 66-84: The Streams tab reads useKiGeneration() but never forwards
the isScheduling flag to the GenerateSplitButton, allowing bulkOnboardAll /
bulkOnboardFeaturesOnly / bulkOnboardQueriesOnly to be invoked twice; update the
StreamsView component to pass isScheduling into GenerateSplitButton (and any CTA
buttons) and use it to disable the button and short-circuit click handlers while
true, and also add a guard inside each bulkOnboard* call path (bulkOnboardAll,
bulkOnboardFeaturesOnly, bulkOnboardQueriesOnly) to return early if isScheduling
is already set to prevent concurrent scheduling.
In
`@x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/hooks/use_bulk_onboarding.ts`:
- Around line 50-67: The code currently enqueues every stream in streamNames
into onboardingStatusUpdateQueue and calls processStatusUpdateQueue regardless
of whether scheduleOnboardingTask succeeded; change the logic so only streams
that were successfully scheduled are added to onboardingStatusUpdateQueue.
Modify the pMap mapper used with scheduleOnboardingTask to return the streamName
(or a success marker) on success and throw/return a falsy value on failure,
collect the successful results after awaiting pMap (or build a successfulStreams
array inside the mapper), and then iterate only over successfulStreams to call
onboardingStatusUpdateQueue.add and invoke processStatusUpdateQueue; keep
existing error handling (toasts.addError/getFormattedError) and setIsScheduling
behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 88c4abed-a9ab-4711-939a-71290f8e3b5c
📒 Files selected for processing (18)
x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/index.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/ki_generation_context.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/knowledge_indicators_table.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/use_knowledge_indicators_table.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/connector_sub_panel.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_helpers.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/generate_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/stream_picker.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/types.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/insights_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/streams_view.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/hooks/use_bulk_onboarding.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/page.tsxx-pack/platform/plugins/shared/streams_app/public/hooks/sig_events/use_connector_config.ts
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughThis PR introduces a unified Possibly related PRs
Suggested labels
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/streams_view.tsx`:
- Around line 86-98: The status callback registration in StreamsView is
currently mounted only while the Streams tab exists, so move the
registerStatusCallback registration out of StreamsView into a higher-level,
always-mounted scope (e.g., the shared provider or parent-level consumer) so
KI-generation and other flows trigger toasts and refreshUnbackedQueriesCount
consistently; keep the same callback logic (checking taskResult.status ===
TaskStatus.Failed to call toasts.addError(getFormattedError(...), { title:
ONBOARDING_FAILURE_TITLE }) and TaskStatus.Completed to call
refreshUnbackedQueriesCount()), ensure you return the unregister function for
cleanup, and remove the registration from StreamsView to avoid duplicate
subscriptions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 535fd980-1b6e-43d0-909e-a43c1c52acc5
📒 Files selected for processing (18)
x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/index.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/ki_generation_context.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/knowledge_indicators_table.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/use_knowledge_indicators_table.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/connector_sub_panel.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_helpers.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/generate_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/stream_picker.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/types.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/insights_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/streams_view.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/hooks/use_bulk_onboarding.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/page.tsxx-pack/platform/plugins/shared/streams_app/public/hooks/sig_events/use_connector_config.ts
…instead of useLoadConnectors
bulkScheduleOnboardingTask now returns succeeded stream names. Wrappers in ki_generation_context compare requested vs succeeded and remove failed streams from generatingStreams so they don't appear stuck in generating state indefinitely. Made-with: Cursor
|
/ci |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
1 similar comment
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/ki_generation_context.tsx`:
- Around line 258-265: The isStreamActionable predicate ignores optimistic
in-flight streams and should short-circuit on the optimistic set; update
isStreamActionable to return false if generatingStreams.has(streamName) before
consulting streamStatusMap, so newly-marked streams from markAsGenerating are
treated as in-progress; reference the isStreamActionable function, the
generatingStreams Set, streamStatusMap, and IN_PROGRESS_STATUSES when making
this change.
- Around line 218-255: These wrappers mark streams optimistic with
markAsGenerating but never clear that mark on rejection; wrap each await
(rawBulkOnboardAll, rawBulkOnboardFeaturesOnly, rawBulkOnboardQueriesOnly,
rawBulkScheduleOnboardingTask) in try/catch and in the catch call
unmarkFailedStreams(streamNames, []) (to rollback the optimistic generating
state) then rethrow the error so callers still receive the failure; update
bulkOnboardAll, bulkOnboardFeaturesOnly, bulkOnboardQueriesOnly and
bulkScheduleOnboardingTask accordingly.
In
`@x-pack/platform/plugins/shared/streams_app/public/hooks/sig_events/use_inference_feature_connectors.ts`:
- Around line 41-53: The hook currently returns loading: query.isLoading while
keepPreviousData is true, which can leave resolvedConnectorId (computed from
featureConnectors/allConnectors/raw) stale during a refetch; update the return
to treat loading as query.isLoading || query.isFetching and, to avoid using
stale connector values while a fetch is in-flight, set resolvedConnectorId to
undefined when query.isFetching (i.e., compute resolvedConnectorId from raw only
if !query.isFetching, otherwise undefined) so KI generation won't act on the
previous feature's connector.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 3171234d-96f1-4aae-a02e-e2048d24d9f2
📒 Files selected for processing (20)
x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/index.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/ki_generation_context.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/knowledge_indicators_table.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/use_knowledge_indicators_table.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/connector_sub_panel.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_helpers.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/context_menu_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/generate_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/stream_picker.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/shared/types.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/insights_split_button.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/streams_view.tsxx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/streams_view/translations.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/hooks/use_bulk_onboarding.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/hooks/use_fetch_streams.tsx-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/page.tsxx-pack/platform/plugins/shared/streams_app/public/hooks/sig_events/use_connector_config.tsx-pack/platform/plugins/shared/streams_app/public/hooks/sig_events/use_inference_feature_connectors.ts
Remove connector fields, discovery state, and isStreamActionable from KiGenerationContext. Inline onboardingConfig state, delete use_connector_config.ts, replace renderless KiGenerationEffects with direct onTaskCompleted/onTaskFailed props, and flatten bulk onboarding callback chain. Made-with: Cursor
… use isFetching in connector hook isStreamActionable now short-circuits false for streams already in the optimistic generatingStreamNames set, closing the race window between markAsGenerating and the first status poll. use_inference_feature_connectors returns loading: true during background refetches (isFetching) as defensive guard for keepPreviousData. Made-with: Cursor
|
/ci |
…al default Switch back to useLoadConnectors from @kbn/inference-connectors. When no SO entry exists for a feature, prefer the first recommended connector instead of connectors[0] which is the global default prepended by the server. Made-with: Cursor
ApprovabilityVerdict: Needs human review This PR introduces a new user-facing feature enabling Knowledge Indicators generation directly from the KI tab, with new context providers, state management, and UI components. All changed files are owned by @elastic/obs-sig-events-team and the author is not a designated owner, warranting review by the owning team. An unresolved review comment about translation scaling also needs team input. You can customize Macroscope's approvability policy. Learn more. |
|
Did a quick test and works as expected. Thanks. |
|
If i type my name in the search bar, there are not KIs, but the hint gets triggered hinting me that if i toggle the Computed Properties on, i might see results, is this expected ?
Could we make it a counterfactual check — re-run const withComputedShown = knowledgeIndicators.filter((ki) =>
matchesKnowledgeIndicatorFilters(ki, {
statusFilter, selectedTypes, selectedStreams,
hideComputedTypes: false,
searchTerm: debouncedSearchTerm,
})
);
return withComputedShown.some((ki) => ki.kind === 'feature' && isComputedFeature(ki.feature));
|
| export const getGenerationInProgressDescription = (streamNames: string[]): string => | ||
| i18n.translate('xpack.streams.knowledgeIndicators.generationInProgressDescription', { | ||
| defaultMessage: 'Generation is running for: {streams}. This may take a few minutes.', | ||
| values: { streams: streamNames.join(', ') }, |
There was a problem hiding this comment.
This would probably not scale well. Imagine user having a lot of streams, and they want to onboard all of them. May be we should not list them ?
'Generation is running for {count, plural, one {stream {first}} other {# streams ({first}, {second}, and # more)}}.'
There was a problem hiding this comment.
Agreed. Changed in 884f4a4 — shows all names for 1–2 streams and a summary for 3+, e.g. "Generation is running for logs.ecs, logs.otel and 3 more."
|
|
||
| const [isScheduling, setIsScheduling] = useState(false); | ||
|
|
||
| const bulkScheduleOnboardingTask = useCallback( |
There was a problem hiding this comment.
A quick small nit here
async (streamName) => {
try {
await scheduleOnboardingTask(streamName, options);
succeeded.push(streamName);
} catch (error) {
toasts.addError(getFormattedError(error), {
title: ONBOARDING_SCHEDULING_FAILURE_TITLE,
});
}
},
{ concurrency: 10, stopOnError: false }This is already a big improvement over the previous behavior on main (stopOnError: true with a single outer catch, which silently dropped failures after the first) — so I'm not suggesting we go back. But firing toasts.addError per failing stream means bulk-scheduling failures (e.g. transient 5xx on a 10-stream batch) can stack 10 identical-titled toasts, which is a bit noisy.
Could we accumulate failures and surface a single summary toast after pMap resolves, keeping the per-stream detail in the expandable body so we don't lose the getFormattedError output?
const failures: Array<{ streamName: string; error: unknown }> = [];
await pMap(
streamNames,
async (streamName) => {
try {
await scheduleOnboardingTask(streamName, options);
succeeded.push(streamName);
} catch (error) {
failures.push({ streamName, error });
}
},
{ concurrency: 10, stopOnError: false }
);
if (failures.length > 0) {
toasts.addError(
new Error(
failures
.map(({ streamName, error }) => `${streamName}: ${getFormattedError(error).message}`)
.join('\n')
),
{
title: i18n.translate('...schedulingErrorSummary', {
defaultMessage:
'Failed to schedule onboarding for {count, plural, one {# stream} other {# streams}}',
values: { count: failures.length },
}),
}
);
}There was a problem hiding this comment.
Nice suggestion, done in 884f4a4. Failures are now accumulated during pMap and surfaced as a single toast with an ICU-pluralized title ("Failed to schedule onboarding for 3 streams") and per-stream detail in the error body. Also removed the now-unused ONBOARDING_SCHEDULING_FAILURE_TITLE.
achyutjhunjhunwala
left a comment
There was a problem hiding this comment.
great work on the PR and this makes our UI much better, just left small nits
- Counterfactual check for hidden-computed-features hint so it only shows when toggling the switch would actually reveal results. - Cap stream names in generation progress callout (show first two, summarise the rest). - Consolidate per-stream scheduling error toasts into a single summary toast with per-stream detail in the body. - Remove unused ONBOARDING_SCHEDULING_FAILURE_TITLE. Made-with: Cursor
|
Good catch! Done in 884f4a4 — |
Made-with: Cursor # Conflicts: # x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/knowledge_indicators_table.tsx # x-pack/platform/plugins/shared/streams_app/public/components/sig_events/significant_events_discovery/components/knowledge_indicators_table/use_knowledge_indicators_table.ts
💛 Build succeeded, but was flaky
Failed CI Steps
Test Failures
Metrics [docs]Module Count
Async chunks
Unknown metric groupsReferences to deprecated APIs
Unreferenced deprecated APIs
History
|
…ssue Resolves conflicts from main's PR elastic#263822 (KiGenerationProvider refactor): - packages/kbn-optimizer/limits.yml: took main's lens: 90000 (higher ceiling). - use_connector_config.ts: accepted main's deletion (state moved into KiGenerationProvider). - use_inference_feature_connectors.ts: kept our hook shape (connectors + resolvedConnectorId) with resolvedConnectorId = aiConnectors[0]?.id so the admin's global default wins over feature recommendedEndpoints when set, matching the alignment with the inference team. - streams_view.tsx: took main's useKiGeneration() destructure, dropped the useAIFeatures/allConnectors coupling, and derived connectorError / isConnectorCatalogUnavailable from the three per-step hooks. - knowledge_indicators_table.tsx: same per-step derivation; passes featuresConnectors/queriesConnectors (not allConnectors) into GenerateSplitButton. - ki_generation_context.tsx: extended ConnectorState to expose connectors and error from each per-step hook. Type check passes on both streams_app and streams projects.

Summary
Lets users generate Knowledge Indicators directly from the Knowledge Indicators tab (previously they had to bounce to the Streams tab). Under the hood, centralizes all KI-generation state — connectors, onboarding config, status polling, generating-stream tracking — in a single
KiGenerationProviderso both tabs render off the same source of truth.Motivation
The Streams and Knowledge Indicators tabs each owned a slice of the same state (onboarding status map, "in-progress" tracking, connector config, streams fetch). That caused:
What Changed
UX
GenerateSplitButtonrow at the top, plus a progressEuiCallOutwhile generation runs.Screen.Recording.2026-04-16.at.17.10.37.mov