diff --git a/x-pack/platform/packages/shared/kbn-langchain/server/language_models/llm.ts b/x-pack/platform/packages/shared/kbn-langchain/server/language_models/llm.ts index 787c4e85b1358..166a8db644870 100644 --- a/x-pack/platform/packages/shared/kbn-langchain/server/language_models/llm.ts +++ b/x-pack/platform/packages/shared/kbn-langchain/server/language_models/llm.ts @@ -11,6 +11,7 @@ import { LLM } from '@langchain/core/language_models/llms'; import { get } from 'lodash/fp'; import { v4 as uuidv4 } from 'uuid'; import { PublicMethodsOf } from '@kbn/utility-types'; +import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib'; import { DEFAULT_TIMEOUT, getDefaultArguments } from './constants'; import { getMessageContentAndRole } from './helpers'; @@ -28,6 +29,7 @@ interface ActionsClientLlmParams { timeout?: number; traceId?: string; traceOptions?: TraceOptions; + telemetryMetadata?: TelemetryMetadata; } export class ActionsClientLlm extends LLM { @@ -36,6 +38,7 @@ export class ActionsClientLlm extends LLM { #logger: Logger; #traceId: string; #timeout?: number; + telemetryMetadata?: TelemetryMetadata; // Local `llmType` as it can change and needs to be accessed by abstract `_llmType()` method // Not using getter as `this._llmType()` is called in the constructor via `super({})` @@ -54,6 +57,7 @@ export class ActionsClientLlm extends LLM { temperature, timeout, traceOptions, + telemetryMetadata, }: ActionsClientLlmParams) { super({ callbacks: [...(traceOptions?.tracers ?? [])], @@ -67,6 +71,7 @@ export class ActionsClientLlm extends LLM { this.#timeout = timeout; this.model = model; this.temperature = temperature; + this.telemetryMetadata = telemetryMetadata; } _llmType() { @@ -102,6 +107,7 @@ export class ActionsClientLlm extends LLM { model: this.model, messages: [assistantMessage], // the assistant message }, + telemetryMetadata: this.telemetryMetadata, }, } : { @@ -113,6 +119,7 @@ export class ActionsClientLlm extends LLM { ...getDefaultArguments(this.llmType, this.temperature), // This timeout is large because LangChain prompts can be complicated and take a long time timeout: this.#timeout ?? DEFAULT_TIMEOUT, + telemetryMetadata: this.telemetryMetadata, }, }, }; diff --git a/x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_logs_routes.ts b/x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_logs_routes.ts index de6f3fc054dc6..e75af5344c869 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_logs_routes.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_logs_routes.ts @@ -90,6 +90,9 @@ export function registerAnalyzeLogsRoutes( maxTokens: 4096, signal: abortSignal, streaming: false, + telemetryMetadata: { + pluginId: 'automatic_import', + }, }); const options = { callbacks: [ diff --git a/x-pack/platform/plugins/shared/integration_assistant/server/routes/categorization_routes.ts b/x-pack/platform/plugins/shared/integration_assistant/server/routes/categorization_routes.ts index 72aaf1d963efb..47462f7499a80 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/server/routes/categorization_routes.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/server/routes/categorization_routes.ts @@ -95,6 +95,9 @@ export function registerCategorizationRoutes( maxTokens: 4096, signal: abortSignal, streaming: false, + telemetryMetadata: { + pluginId: 'automatic_import', + }, }); const parameters = { diff --git a/x-pack/platform/plugins/shared/integration_assistant/server/routes/cel_routes.ts b/x-pack/platform/plugins/shared/integration_assistant/server/routes/cel_routes.ts index 63faeb6a71f26..5269421ca4362 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/server/routes/cel_routes.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/server/routes/cel_routes.ts @@ -77,6 +77,9 @@ export function registerCelInputRoutes(router: IRouter { const response = await connector.performApiUnifiedCompletion({ body: { messages: [{ content: 'What is Elastic?', role: 'user' }] }, + telemetryMetadata: { pluginId: 'security_ai_assistant' }, }); expect(mockEsClient.transport.request).toBeCalledTimes(1); expect(mockEsClient.transport.request).toHaveBeenCalledWith( @@ -86,7 +87,13 @@ describe('InferenceConnector', () => { method: 'POST', path: '_inference/chat_completion/test/_stream', }, - { asStream: true, meta: true } + { + asStream: true, + meta: true, + headers: { + 'X-Elastic-Product-Use-Case': 'security_ai_assistant', + }, + } ); expect(response.choices[0].message.content).toEqual(' you'); }); @@ -292,7 +299,10 @@ describe('InferenceConnector', () => { method: 'POST', path: '_inference/chat_completion/test/_stream', }, - { asStream: true, meta: true } + { + asStream: true, + meta: true, + } ); }); @@ -314,7 +324,11 @@ describe('InferenceConnector', () => { method: 'POST', path: '_inference/chat_completion/test/_stream', }, - { asStream: true, meta: true, signal } + { + asStream: true, + meta: true, + signal, + } ); }); diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/inference/inference.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/inference/inference.ts index 5e319a7b5dfcf..ab43c0b516689 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/inference/inference.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/inference/inference.ts @@ -196,6 +196,13 @@ export class InferenceConnector extends SubActionConnector { asStream: true, meta: true, signal: params.signal, + ...(params.telemetryMetadata?.pluginId + ? { + headers: { + 'X-Elastic-Product-Use-Case': params.telemetryMetadata?.pluginId, + }, + } + : {}), } ); // errors should be thrown as it will not be a stream response diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/helpers/get_evaluator_llm/index.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/helpers/get_evaluator_llm/index.ts index 236def9670d07..968a21122361a 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/helpers/get_evaluator_llm/index.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/helpers/get_evaluator_llm/index.ts @@ -61,5 +61,8 @@ export const getEvaluatorLlm = async ({ temperature: 0, // zero temperature for evaluation timeout: connectorTimeout, traceOptions, + telemetryMetadata: { + pluginId: 'security_attack_discovery', + }, }); }; diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/index.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/index.ts index 2de3eb0bdf9d3..ce5b2ab71d177 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/index.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/attack_discovery/evaluation/index.ts @@ -92,6 +92,9 @@ export const evaluateAttackDiscovery = async ({ temperature: 0, // zero temperature for attack discovery, because we want structured JSON output timeout: connectorTimeout, traceOptions, + telemetryMetadata: { + pluginId: 'security_attack_discovery', + }, }); const graph = getDefaultAttackDiscoveryGraph({ diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/langchain/graphs/default_assistant_graph/index.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/langchain/graphs/default_assistant_graph/index.ts index da1d2244e5c5e..10039f1b1039d 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/langchain/graphs/default_assistant_graph/index.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/langchain/graphs/default_assistant_graph/index.ts @@ -89,6 +89,9 @@ export const callAssistantGraph: AgentExecutor = async ({ // failure could be due to bad connector, we should deliver that result to the client asap maxRetries: 0, convertSystemMessageToHumanContent: false, + telemetryMetadata: { + pluginId: 'security_ai_assistant', + }, }); const anonymizationFieldsRes = diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/invoke_attack_discovery_graph/index.tsx b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/invoke_attack_discovery_graph/index.tsx index 850bb06829d13..f0be667a81800 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/invoke_attack_discovery_graph/index.tsx +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/invoke_attack_discovery_graph/index.tsx @@ -87,6 +87,9 @@ export const invokeAttackDiscoveryGraph = async ({ temperature: 0, // zero temperature for attack discovery, because we want structured JSON output timeout: connectorTimeout, traceOptions, + telemetryMetadata: { + pluginId: 'security_attack_discovery', + }, }); if (llm == null) { diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/defend_insights/helpers.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/defend_insights/helpers.ts index 88ba28c06b8c7..7679e668aae80 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/defend_insights/helpers.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/defend_insights/helpers.ts @@ -162,6 +162,9 @@ export function getAssistantToolParams({ temperature: 0, // zero temperature because we want structured JSON output timeout: connectorTimeout, traceOptions, + telemetryMetadata: { + pluginId: 'security_defend_insights', + }, }); return { diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts index ae82fec6ceeca..1056b9bb29a5b 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts @@ -250,6 +250,9 @@ export const postEvaluateRoute = ( streaming: false, maxRetries: 0, convertSystemMessageToHumanContent: false, + telemetryMetadata: { + pluginId: 'security_ai_assistant', + }, }); const llm = createLlmInstance(); const anonymizationFieldsRes =