Skip to content

Commit a407578

Browse files
[9.0] [GenAI Connectors] Add support for telemetry metadata (elastic#208180) (elastic#210018)
# Backport This will backport the following commits from `main` to `9.0`: - [[GenAI Connectors] Add support for telemetry metadata (elastic#208180)](elastic#208180) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Marius Iversen","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-02-06T14:24:35Z","message":"[GenAI Connectors] Add support for telemetry metadata (elastic#208180)\n\n## Summary\n\nThis extends initial connector telemetry from PR ref\nhttps://github.com/elastic/pull/186936.\n\nThe PR adds the following optional fields when instantiating a new\nactionClient as part of its `subActionParams`:\n\n```ts\n{\n telemetryMetadata : {\n pluginId: \"your plugin name or unique identifier\",\n aggregateBy: \"ID to aggregate on\" \n }\n}\n```\n\nThe support is added to all AI connector models for both\nstream/non-stream/raw.\n\nThe PR also adds token count usage for bedrock `InvokeAIRaw`, as that\nwas currently not added correctly.\n\nPierre also helped with adding a new metadata optional field for the `NL\nto ESQL functions`, so that users can pass in similar metadata for LLM\nconversations using the InfereceClient.\n\nPluginId is a field used to filter telemetry in the way the team wants\nto implement it. It could be a team name, a plugin name etc, all\ndepending on how the team wants to group and filter on the telemetry\nevent.\n\nAggregateBy is intended to be used to group multiple LLM calls for\naggregations and stats, for example a conversationId that has multiple\nLLM calls.\n\nBoth fields are optional, so when you do not want to aggregate the\noption can simply be ignored.\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: pgayvallet <[email protected]>","sha":"3394b691b1582d504195182013f833ba727c5e7e","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team: SecuritySolution","backport:version","v8.18.0","v9.1.0","v8.19.0"],"title":"[GenAI Connectors] Add support for telemetry metadata","number":208180,"url":"https://github.com/elastic/kibana/pull/208180","mergeCommit":{"message":"[GenAI Connectors] Add support for telemetry metadata (elastic#208180)\n\n## Summary\n\nThis extends initial connector telemetry from PR ref\nhttps://github.com/elastic/pull/186936.\n\nThe PR adds the following optional fields when instantiating a new\nactionClient as part of its `subActionParams`:\n\n```ts\n{\n telemetryMetadata : {\n pluginId: \"your plugin name or unique identifier\",\n aggregateBy: \"ID to aggregate on\" \n }\n}\n```\n\nThe support is added to all AI connector models for both\nstream/non-stream/raw.\n\nThe PR also adds token count usage for bedrock `InvokeAIRaw`, as that\nwas currently not added correctly.\n\nPierre also helped with adding a new metadata optional field for the `NL\nto ESQL functions`, so that users can pass in similar metadata for LLM\nconversations using the InfereceClient.\n\nPluginId is a field used to filter telemetry in the way the team wants\nto implement it. It could be a team name, a plugin name etc, all\ndepending on how the team wants to group and filter on the telemetry\nevent.\n\nAggregateBy is intended to be used to group multiple LLM calls for\naggregations and stats, for example a conversationId that has multiple\nLLM calls.\n\nBoth fields are optional, so when you do not want to aggregate the\noption can simply be ignored.\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: pgayvallet <[email protected]>","sha":"3394b691b1582d504195182013f833ba727c5e7e"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.18","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208180","number":208180,"mergeCommit":{"message":"[GenAI Connectors] Add support for telemetry metadata (elastic#208180)\n\n## Summary\n\nThis extends initial connector telemetry from PR ref\nhttps://github.com/elastic/pull/186936.\n\nThe PR adds the following optional fields when instantiating a new\nactionClient as part of its `subActionParams`:\n\n```ts\n{\n telemetryMetadata : {\n pluginId: \"your plugin name or unique identifier\",\n aggregateBy: \"ID to aggregate on\" \n }\n}\n```\n\nThe support is added to all AI connector models for both\nstream/non-stream/raw.\n\nThe PR also adds token count usage for bedrock `InvokeAIRaw`, as that\nwas currently not added correctly.\n\nPierre also helped with adding a new metadata optional field for the `NL\nto ESQL functions`, so that users can pass in similar metadata for LLM\nconversations using the InfereceClient.\n\nPluginId is a field used to filter telemetry in the way the team wants\nto implement it. It could be a team name, a plugin name etc, all\ndepending on how the team wants to group and filter on the telemetry\nevent.\n\nAggregateBy is intended to be used to group multiple LLM calls for\naggregations and stats, for example a conversationId that has multiple\nLLM calls.\n\nBoth fields are optional, so when you do not want to aggregate the\noption can simply be ignored.\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: pgayvallet <[email protected]>","sha":"3394b691b1582d504195182013f833ba727c5e7e"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Marius Iversen <[email protected]>
1 parent b5d8b82 commit a407578

File tree

38 files changed

+764
-14
lines changed

38 files changed

+764
-14
lines changed

x-pack/platform/packages/shared/ai-infra/inference-common/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ export {
5656
isToolValidationError,
5757
isTokenLimitReachedError,
5858
isToolNotFoundError,
59+
type ChatCompleteMetadata,
60+
type ConnectorTelemetryMetadata,
5961
} from './src/chat_complete';
6062
export {
6163
OutputEventType,

x-pack/platform/packages/shared/ai-infra/inference-common/src/chat_complete/api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { Observable } from 'rxjs';
99
import type { ToolCallsOf, ToolOptions } from './tools';
1010
import type { Message } from './messages';
1111
import type { ChatCompletionEvent, ChatCompletionTokenCount } from './events';
12+
import type { ChatCompleteMetadata } from './metadata';
1213

1314
/**
1415
* Request a completion from the LLM based on a prompt or conversation.
@@ -109,6 +110,10 @@ export type ChatCompleteOptions<
109110
* Optional signal that can be used to forcefully abort the request.
110111
*/
111112
abortSignal?: AbortSignal;
113+
/**
114+
* Optional metadata related to call execution.
115+
*/
116+
metadata?: ChatCompleteMetadata;
112117
} & TToolOptions;
113118

114119
/**

x-pack/platform/packages/shared/ai-infra/inference-common/src/chat_complete/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export {
5050
type UnvalidatedToolCall,
5151
type ToolChoice,
5252
} from './tools';
53+
export type { ChatCompleteMetadata, ConnectorTelemetryMetadata } from './metadata';
5354
export {
5455
isChatCompletionChunkEvent,
5556
isChatCompletionEvent,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
/**
9+
* Set of metadata that can be used then calling the inference APIs
10+
*
11+
* @public
12+
*/
13+
export interface ChatCompleteMetadata {
14+
connectorTelemetry?: ConnectorTelemetryMetadata;
15+
}
16+
17+
/**
18+
* Pass through for the connector telemetry
19+
*/
20+
export interface ConnectorTelemetryMetadata {
21+
pluginId?: string;
22+
aggregateBy?: string;
23+
}

x-pack/platform/packages/shared/ai-infra/inference-common/src/output/api.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
*/
77

88
import type { Observable } from 'rxjs';
9-
import { Message, FunctionCallingMode, FromToolSchema, ToolSchema } from '../chat_complete';
9+
import {
10+
Message,
11+
FunctionCallingMode,
12+
FromToolSchema,
13+
ToolSchema,
14+
ChatCompleteMetadata,
15+
} from '../chat_complete';
1016
import { Output, OutputEvent } from './events';
1117

1218
/**
@@ -117,6 +123,10 @@ export interface OutputOptions<
117123
*/
118124
onValidationError?: boolean | number;
119125
};
126+
/**
127+
* Optional metadata related to call execution.
128+
*/
129+
metadata?: ChatCompleteMetadata;
120130
}
121131

122132
/**

x-pack/platform/packages/shared/kbn-langchain/server/language_models/bedrock_chat.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { ActionsClient } from '@kbn/actions-plugin/server';
1010
import { BaseChatModelParams } from '@langchain/core/language_models/chat_models';
1111
import { Logger } from '@kbn/logging';
1212
import { PublicMethodsOf } from '@kbn/utility-types';
13+
import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib';
1314
import { prepareMessages, DEFAULT_BEDROCK_MODEL, DEFAULT_BEDROCK_REGION } from '../utils/bedrock';
1415

1516
export interface CustomChatModelInput extends BaseChatModelParams {
@@ -20,6 +21,7 @@ export interface CustomChatModelInput extends BaseChatModelParams {
2021
signal?: AbortSignal;
2122
model?: string;
2223
maxTokens?: number;
24+
telemetryMetadata?: TelemetryMetadata;
2325
}
2426

2527
/**
@@ -49,6 +51,10 @@ export class ActionsClientBedrockChatModel extends _BedrockChat {
4951
params: {
5052
subAction: 'invokeAIRaw',
5153
subActionParams: {
54+
telemetryMetadata: {
55+
pluginId: params?.telemetryMetadata?.pluginId,
56+
aggregateBy: params?.telemetryMetadata?.aggregateBy,
57+
},
5258
messages: prepareMessages(inputBody.messages),
5359
temperature: params.temperature ?? inputBody.temperature,
5460
stopSequences: inputBody.stop_sequences,

x-pack/platform/packages/shared/kbn-langchain/server/language_models/chat_bedrock_converse/bedrock_runtime_client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,33 @@ import {
1313
ConverseStreamCommand,
1414
ConverseStreamResponse,
1515
} from '@aws-sdk/client-bedrock-runtime';
16+
import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib';
1617
import { constructStack } from '@smithy/middleware-stack';
1718
import { HttpHandlerOptions } from '@smithy/types';
1819
import { PublicMethodsOf } from '@kbn/utility-types';
1920
import type { ActionsClient } from '@kbn/actions-plugin/server';
20-
2121
import { prepareMessages } from '../../utils/bedrock';
2222

2323
export interface CustomChatModelInput extends BedrockRuntimeClientConfig {
2424
actionsClient: PublicMethodsOf<ActionsClient>;
2525
connectorId: string;
2626
streaming?: boolean;
27+
telemetryMetadata?: TelemetryMetadata;
2728
}
2829

2930
export class BedrockRuntimeClient extends _BedrockRuntimeClient {
3031
middlewareStack: _BedrockRuntimeClient['middlewareStack'];
3132
streaming: boolean;
3233
actionsClient: PublicMethodsOf<ActionsClient>;
3334
connectorId: string;
35+
telemetryMetadata?: TelemetryMetadata;
3436

3537
constructor({ actionsClient, connectorId, ...fields }: CustomChatModelInput) {
3638
super(fields ?? {});
3739
this.streaming = fields.streaming ?? true;
3840
this.actionsClient = actionsClient;
3941
this.connectorId = connectorId;
42+
this.telemetryMetadata = fields?.telemetryMetadata;
4043
// eliminate middleware steps that handle auth as Kibana connector handles auth
4144
this.middlewareStack = constructStack() as _BedrockRuntimeClient['middlewareStack'];
4245
}
@@ -56,6 +59,7 @@ export class BedrockRuntimeClient extends _BedrockRuntimeClient {
5659
params: {
5760
subAction: 'bedrockClientSend',
5861
subActionParams: {
62+
telemetryMetadata: this.telemetryMetadata,
5963
command,
6064
signal: options?.abortSignal,
6165
},

x-pack/platform/packages/shared/kbn-langchain/server/language_models/chat_bedrock_converse/chat_bedrock_converse.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { ActionsClient } from '@kbn/actions-plugin/server';
99
import { BaseChatModelParams } from '@langchain/core/language_models/chat_models';
1010
import { Logger } from '@kbn/logging';
1111
import { PublicMethodsOf } from '@kbn/utility-types';
12+
import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib';
1213
import { BedrockRuntimeClient } from './bedrock_runtime_client';
1314
import { DEFAULT_BEDROCK_MODEL, DEFAULT_BEDROCK_REGION } from '../../utils/bedrock';
1415

@@ -18,6 +19,7 @@ export interface CustomChatModelInput extends BaseChatModelParams {
1819
logger: Logger;
1920
signal?: AbortSignal;
2021
model?: string;
22+
telemetryMetadata?: TelemetryMetadata;
2123
}
2224

2325
/**
@@ -45,6 +47,7 @@ export class ActionsClientChatBedrockConverse extends ChatBedrockConverse {
4547
connectorId,
4648
streaming: this.streaming,
4749
region: DEFAULT_BEDROCK_REGION,
50+
telemetryMetadata: fields?.telemetryMetadata,
4851
});
4952
}
5053
}

x-pack/platform/packages/shared/kbn-langchain/server/language_models/chat_openai.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import { v4 as uuidv4 } from 'uuid';
99
import { Logger } from '@kbn/core/server';
1010
import type { ActionsClient } from '@kbn/actions-plugin/server';
1111
import { get } from 'lodash/fp';
12-
12+
import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib';
1313
import { ChatOpenAI } from '@langchain/openai';
1414
import { Stream } from 'openai/streaming';
1515
import type OpenAI from 'openai';
1616
import { PublicMethodsOf } from '@kbn/utility-types';
17+
1718
import { DEFAULT_OPEN_AI_MODEL, DEFAULT_TIMEOUT } from './constants';
1819
import {
1920
InferenceChatCompleteParamsSchema,
@@ -36,6 +37,7 @@ export interface ActionsClientChatOpenAIParams {
3637
temperature?: number;
3738
signal?: AbortSignal;
3839
timeout?: number;
40+
telemetryMetadata?: TelemetryMetadata;
3941
}
4042

4143
/**
@@ -65,6 +67,7 @@ export class ActionsClientChatOpenAI extends ChatOpenAI {
6567
#traceId: string;
6668
#signal?: AbortSignal;
6769
#timeout?: number;
70+
telemetryMetadata?: TelemetryMetadata;
6871

6972
constructor({
7073
actionsClient,
@@ -79,6 +82,7 @@ export class ActionsClientChatOpenAI extends ChatOpenAI {
7982
temperature,
8083
timeout,
8184
maxTokens,
85+
telemetryMetadata,
8286
}: ActionsClientChatOpenAIParams) {
8387
super({
8488
maxRetries,
@@ -109,6 +113,7 @@ export class ActionsClientChatOpenAI extends ChatOpenAI {
109113
// matters only for LangSmith logs (Metadata > Invocation Params)
110114
// the connector can be passed an undefined temperature through #temperature
111115
this.temperature = temperature ?? this.temperature;
116+
this.telemetryMetadata = telemetryMetadata;
112117
}
113118

114119
getActionResultData(): string {
@@ -237,6 +242,7 @@ export class ActionsClientChatOpenAI extends ChatOpenAI {
237242
: completionRequest.stream
238243
? { ...body, timeout: this.#timeout ?? DEFAULT_TIMEOUT }
239244
: { body: JSON.stringify(body), timeout: this.#timeout ?? DEFAULT_TIMEOUT }),
245+
telemetryMetadata: this.telemetryMetadata,
240246
signal: this.#signal,
241247
};
242248
return {

x-pack/platform/packages/shared/kbn-langchain/server/language_models/chat_vertex/chat_vertex.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Logger } from '@kbn/logging';
1818
import { BaseChatModelParams } from '@langchain/core/language_models/chat_models';
1919
import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
2020
import { GeminiPartText } from '@langchain/google-common/dist/types';
21+
import type { TelemetryMetadata } from '@kbn/actions-plugin/server/lib';
2122
import {
2223
convertResponseBadFinishReasonToErrorMsg,
2324
convertResponseContentToChatGenerationChunk,
@@ -34,12 +35,14 @@ export interface CustomChatModelInput extends BaseChatModelParams {
3435
signal?: AbortSignal;
3536
model?: string;
3637
maxTokens?: number;
38+
telemetryMetadata?: TelemetryMetadata;
3739
}
3840

3941
export class ActionsClientChatVertexAI extends ChatVertexAI {
4042
#actionsClient: PublicMethodsOf<ActionsClient>;
4143
#connectorId: string;
4244
#model?: string;
45+
telemetryMetadata?: TelemetryMetadata;
4346
constructor({ actionsClient, connectorId, ...props }: CustomChatModelInput) {
4447
super({
4548
...props,
@@ -62,7 +65,8 @@ export class ActionsClientChatVertexAI extends ChatVertexAI {
6265
client,
6366
false,
6467
actionsClient,
65-
connectorId
68+
connectorId,
69+
props?.telemetryMetadata
6670
);
6771
}
6872

@@ -89,6 +93,7 @@ export class ActionsClientChatVertexAI extends ChatVertexAI {
8993
subAction: 'invokeStream',
9094
subActionParams: {
9195
model: this.#model,
96+
telemetryMetadata: this.telemetryMetadata,
9297
messages: data?.contents,
9398
tools: data?.tools,
9499
temperature: this.temperature,

0 commit comments

Comments
 (0)