Skip to content

[Inference] Fix ActionsClientLlm failing with EIS connector IDs#260268

Merged
sphilipse merged 13 commits intoelastic:mainfrom
sphilipse:inference-fix-actionsclient-issue
Mar 30, 2026
Merged

[Inference] Fix ActionsClientLlm failing with EIS connector IDs#260268
sphilipse merged 13 commits intoelastic:mainfrom
sphilipse:inference-fix-actionsclient-issue

Conversation

@sphilipse
Copy link
Copy Markdown
Member

Summary

After PR #258530 consolidated connector listing, EIS connectors are returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet- chat_completion) as their connectorId rather than Kibana saved object IDs. Attack Discovery and Defend Insights passed these IDs to ActionsClientLlm which used actionsClient.execute(), failing with "Saved object [action/...] not found".

This PR uses a new path when actionTypeId is .inference and an inference client is available. ActionsClientLlm uses its existing isInferenceEndpoint path which calls inferenceClient.chatComplete() instead of actionsClient.execute().

After PR elastic#258530 consolidated connector listing, EIS connectors are
returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet-
chat_completion) as their connectorId rather than Kibana saved object
IDs. Attack Discovery and Defend Insights passed these IDs to
ActionsClientLlm which used actionsClient.execute(), failing with
"Saved object [action/...] not found".

Fix: Thread an InferenceClient from route handlers to ActionsClientLlm.
When actionTypeId is .inference and an inference client is available,
ActionsClientLlm uses its existing isInferenceEndpoint path which calls
inferenceClient.chatComplete() instead of actionsClient.execute(),
correctly handling inference endpoint IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sphilipse sphilipse requested review from a team as code owners March 30, 2026 14:02
@sphilipse sphilipse added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting Team:Search v9.4.0 labels Mar 30, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Mar 30, 2026

Approvability

Verdict: Needs human review

This PR changes how connector IDs are resolved from client-driven to server-driven across multiple security workflows (attack discovery, defend insights, scheduled tasks). The author does not own any of the 32 modified files, which span multiple team domains (@elastic/search-kibana, @elastic/security-generative-ai, @elastic/security-defend-workflows). Designated code owners should review these cross-cutting behavioral changes.

You can customize Macroscope's approvability policy. Learn more.

sphilipse and others added 2 commits March 30, 2026 16:16
Move connector validation from client-side useLoadConnectors lookup
to server-side resolution via inference.getConnectorById. The server
now resolves the authoritative actionTypeId from the connector ID,
so the client only needs to send the connectorId. This removes the
useLoadConnectors dependency from useAttackDiscovery and ensures
inference endpoint IDs (including EIS connectors) are resolved
correctly regardless of what the client sends.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sphilipse sphilipse force-pushed the inference-fix-actionsclient-issue branch from 3c628c7 to 8f38cbc Compare March 30, 2026 15:45
@sphilipse sphilipse requested a review from a team as a code owner March 30, 2026 15:45
@sphilipse sphilipse force-pushed the inference-fix-actionsclient-issue branch 2 times, most recently from 2478f50 to e320a10 Compare March 30, 2026 15:54
@sphilipse sphilipse force-pushed the inference-fix-actionsclient-issue branch from eb2cc5c to cc041bd Compare March 30, 2026 16:04
Add getConnectorByIdWithScopedServices to the inference plugin start
contract, which accepts pre-scoped actionsClient and esClient instead
of a KibanaRequest. This enables background tasks (like the attack
discovery schedule executor) to resolve connector types without needing
an HTTP request context.

The executor now uses this API to resolve the authoritative actionTypeId
for the connector, ensuring EIS inference endpoint IDs are handled
correctly in scheduled attack discovery generation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sphilipse sphilipse force-pushed the inference-fix-actionsclient-issue branch from 2c5ec43 to 3a9852e Compare March 30, 2026 16:42
When fetchAttackDiscoveries is called with overrideConnectorId (from
the settings flyout), look up the connector name via
getConnectorNameFromId using the already-loaded aiConnectors list
and pass it as overrideConnectorName. The toast now shows the correct
connector name for both default and override cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@e40pud e40pud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally and attack discovery schedules work with EIS models now. Thanks for the fix @sphilipse 🚀

Replace hand-rolled inference mock with inferenceMock.createStartContract()
which stays in sync with the InferenceServerStart interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sphilipse sphilipse requested a review from a team as a code owner March 30, 2026 18:00
Copy link
Copy Markdown
Contributor

@TattdCodeMonkey TattdCodeMonkey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review only.

@@ -157,9 +163,15 @@ export function getAssistantToolParams({
],
};

const isInferenceEndpoint =
apiConfig.actionTypeId === ('.inference' as InferenceConnectorType.Inference) &&
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we're doing '.inference' as InferenceConnectorType.Inference in a few places. would be nice to have a constant for this either in this file or somewhere sharable.

sphilipse and others added 2 commits March 30, 2026 20:05
Extract createClientWithoutRequest into create_client.ts, encapsulating
the ActionsPluginStart and KibanaRequest shims as an implementation
detail. The plugin.ts getClientWithoutRequest now delegates cleanly
without any type casts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The inference plugin only uses getActionsClientWithRequest from the
actions plugin. Define a narrow ActionsClientProvider interface with
just that method and use it throughout the internal implementation.
This removes the `as unknown as ActionsPluginStart` cast in
createClientWithoutRequest, since the wrapper object now directly
satisfies the narrower type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sphilipse sphilipse enabled auto-merge (squash) March 30, 2026 18:11
Copy link
Copy Markdown
Contributor

@paul-tavares paul-tavares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 ( elastic/security-defend-workflows team

cc/ @joeypoon

@sphilipse sphilipse disabled auto-merge March 30, 2026 19:46
@sphilipse sphilipse enabled auto-merge (squash) March 30, 2026 19:46
@sphilipse sphilipse merged commit 370a61a into elastic:main Mar 30, 2026
19 checks passed
@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
securitySolution 11.5MB 11.5MB -342.0B
Unknown metric groups

API count

id before after diff
inference 69 76 +7

History

e40pud pushed a commit to e40pud/kibana that referenced this pull request Mar 30, 2026
…tic#260268)

## Summary

After PR elastic#258530 consolidated connector listing, EIS connectors are
returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet-
chat_completion) as their connectorId rather than Kibana saved object
IDs. Attack Discovery and Defend Insights passed these IDs to
ActionsClientLlm which used actionsClient.execute(), failing with "Saved
object [action/...] not found".

This PR uses a new path when actionTypeId is .inference and an inference
client is available. ActionsClientLlm uses its existing
isInferenceEndpoint path which calls inferenceClient.chatComplete()
instead of actionsClient.execute().

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
pheyos pushed a commit that referenced this pull request Mar 31, 2026
) (#260345)

## Summary

Cherry pick #260268 to
`deploy-fix@1774851440`

After PR #258530 consolidated connector listing, EIS connectors are
returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet-
chat_completion) as their connectorId rather than Kibana saved object
IDs. Attack Discovery and Defend Insights passed these IDs to
ActionsClientLlm which used actionsClient.execute(), failing with "Saved
object [action/...] not found".

This PR uses a new path when actionTypeId is .inference and an inference
client is available. ActionsClientLlm uses its existing
isInferenceEndpoint path which calls inferenceClient.chatComplete()
instead of actionsClient.execute().

cc @sphilipse @pheyos

Co-authored-by: Sander Philipse <94373878+sphilipse@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
andrew-goldstein added a commit to andrew-goldstein/kibana that referenced this pull request Mar 31, 2026
…all code paths to fix EIS connectors

After rebasing ff51c50 (Workflows Integration), the inferenceClient threading from
PR elastic#260268 was lost. This restores it across all affected code paths so that EIS connectors
(actionTypeId='.inference') use inferenceClient.chatComplete() instead of actionsClient.execute(),
which fails with 'Saved object not found' for inference endpoint IDs.

Gaps fixed:
- Gap 1: Legacy public route handler (FF OFF) — adds inferenceClient to generateAndUpdateAttackDiscoveries call
- Gap 2: Schedule executor (FF OFF, scheduled runs) — threads getInference lazy getter through definition and executor, uses getClientWithoutRequest/getConnectorByIdWithoutClientRequest for background context
- Gap 3: Discoveries plugin inference dependency — adds InferenceServerStart to DiscoveriesPluginStartDeps and inference to optionalPlugins
- Gap 4: invokeAttackDiscoveryGraphWithAlerts (FF ON) — adds inferenceClient param, computes isInferenceEndpoint, passes both to ActionsClientLlm
- Gap 5: invokeGenerationGraph helper (FF ON) — forwards inferenceClient to invokeAttackDiscoveryGraphWithAlerts
- Gap 6: Generate step handler (FF ON) — creates inferenceClient from pluginsStart.inference and passes to invokeGenerationGraph

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jeramysoucy pushed a commit to jeramysoucy/kibana that referenced this pull request Apr 1, 2026
…tic#260268)

## Summary

After PR elastic#258530 consolidated connector listing, EIS connectors are
returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet-
chat_completion) as their connectorId rather than Kibana saved object
IDs. Attack Discovery and Defend Insights passed these IDs to
ActionsClientLlm which used actionsClient.execute(), failing with "Saved
object [action/...] not found".

This PR uses a new path when actionTypeId is .inference and an inference
client is available. ActionsClientLlm uses its existing
isInferenceEndpoint path which calls inferenceClient.chatComplete()
instead of actionsClient.execute().

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
paulinashakirova pushed a commit to paulinashakirova/kibana that referenced this pull request Apr 2, 2026
…tic#260268)

## Summary

After PR elastic#258530 consolidated connector listing, EIS connectors are
returned with inference endpoint IDs (e.g. anthropic-claude-3.7-sonnet-
chat_completion) as their connectorId rather than Kibana saved object
IDs. Attack Discovery and Defend Insights passed these IDs to
ActionsClientLlm which used actionsClient.execute(), failing with "Saved
object [action/...] not found".

This PR uses a new path when actionTypeId is .inference and an inference
client is available. ActionsClientLlm uses its existing
isInferenceEndpoint path which calls inferenceClient.chatComplete()
instead of actionsClient.execute().

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Search v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants