@launchdarkly/server-sdk-ai 0.16.3 → 0.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.16.5](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.16.4...server-sdk-ai-v0.16.5) (2026-03-04)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * devDependencies
10
+ * @launchdarkly/js-server-sdk-common bumped from 2.18.1 to 2.18.2
11
+ * peerDependencies
12
+ * @launchdarkly/js-server-sdk-common bumped from 2.x to 2.18.2
13
+
14
+ ## [0.16.4](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.16.3...server-sdk-ai-v0.16.4) (2026-02-25)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * Improve usage reporting ([#1108](https://github.com/launchdarkly/js-core/issues/1108)) ([7a003b7](https://github.com/launchdarkly/js-core/commit/7a003b78d7de2f91bc9f58b231fb5f660eb09329))
20
+
21
+
22
+ ### Dependencies
23
+
24
+ * The following workspace dependencies were updated
25
+ * devDependencies
26
+ * @launchdarkly/js-server-sdk-common bumped from 2.18.0 to 2.18.1
27
+ * peerDependencies
28
+ * @launchdarkly/js-server-sdk-common bumped from 2.x to 2.18.1
29
+
3
30
  ## [0.16.3](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.16.2...server-sdk-ai-v0.16.3) (2026-02-25)
4
31
 
5
32
 
package/dist/index.cjs CHANGED
@@ -741,10 +741,6 @@ function createVercelAISDKTokenUsage(data) {
741
741
  };
742
742
  }
743
743
 
744
- // src/sdkInfo.ts
745
- var aiSdkName = "@launchdarkly/server-sdk-ai";
746
- var aiSdkVersion = "0.16.3";
747
-
748
744
  // src/LDAIConfigTrackerImpl.ts
749
745
  var LDAIConfigTrackerImpl = class {
750
746
  constructor(_ldClient, _configKey, _variationKey, _version, _modelName, _providerName, _context) {
@@ -763,9 +759,7 @@ var LDAIConfigTrackerImpl = class {
763
759
  configKey: this._configKey,
764
760
  version: this._version,
765
761
  modelName: this._modelName,
766
- providerName: this._providerName,
767
- aiSdkName,
768
- aiSdkVersion
762
+ providerName: this._providerName
769
763
  };
770
764
  }
771
765
  trackDuration(duration) {
@@ -932,17 +926,38 @@ var LDAIConfigTrackerImpl = class {
932
926
  }
933
927
  };
934
928
 
929
+ // src/sdkInfo.ts
930
+ var aiSdkName = "@launchdarkly/server-sdk-ai";
931
+ var aiSdkVersion = "0.16.5";
932
+ var aiSdkLanguage = "javascript";
933
+
935
934
  // src/LDAIClientImpl.ts
936
- var TRACK_CONFIG_SINGLE = "$ld:ai:config:function:single";
937
- var TRACK_CONFIG_CREATE_CHAT = "$ld:ai:config:function:createChat";
938
- var TRACK_JUDGE_SINGLE = "$ld:ai:judge:function:single";
939
- var TRACK_JUDGE_CREATE = "$ld:ai:judge:function:createJudge";
940
- var TRACK_AGENT_SINGLE = "$ld:ai:agent:function:single";
941
- var TRACK_AGENT_MULTIPLE = "$ld:ai:agent:function:multiple";
935
+ var TRACK_SDK_INFO = "$ld:ai:sdk:info";
936
+ var TRACK_USAGE_COMPLETION_CONFIG = "$ld:ai:usage:completion-config";
937
+ var TRACK_USAGE_CREATE_CHAT = "$ld:ai:usage:create-chat";
938
+ var TRACK_USAGE_JUDGE_CONFIG = "$ld:ai:usage:judge-config";
939
+ var TRACK_USAGE_CREATE_JUDGE = "$ld:ai:usage:create-judge";
940
+ var TRACK_USAGE_AGENT_CONFIG = "$ld:ai:usage:agent-config";
941
+ var TRACK_USAGE_AGENT_CONFIGS = "$ld:ai:usage:agent-configs";
942
+ var INIT_TRACK_CONTEXT = {
943
+ kind: "ld_ai",
944
+ key: "ld-internal-tracking",
945
+ anonymous: true
946
+ };
942
947
  var LDAIClientImpl = class {
943
948
  constructor(_ldClient) {
944
949
  this._ldClient = _ldClient;
945
950
  this._logger = _ldClient.logger;
951
+ this._ldClient.track(
952
+ TRACK_SDK_INFO,
953
+ INIT_TRACK_CONTEXT,
954
+ {
955
+ aiSdkName,
956
+ aiSdkVersion,
957
+ aiSdkLanguage
958
+ },
959
+ 1
960
+ );
946
961
  }
947
962
  _interpolateTemplate(template, variables) {
948
963
  return import_mustache2.default.render(template, variables, void 0, { escape: (item) => item });
@@ -1010,24 +1025,30 @@ var LDAIClientImpl = class {
1010
1025
  });
1011
1026
  return judges;
1012
1027
  }
1013
- async completionConfig(key, context, defaultValue, variables) {
1014
- this._ldClient.track(TRACK_CONFIG_SINGLE, context, key, 1);
1028
+ async _completionConfig(key, context, defaultValue, variables) {
1015
1029
  const config = await this._evaluate(key, context, defaultValue, "completion", variables);
1016
1030
  return config;
1017
1031
  }
1032
+ async completionConfig(key, context, defaultValue, variables) {
1033
+ this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1);
1034
+ return this._completionConfig(key, context, defaultValue, variables);
1035
+ }
1018
1036
  /**
1019
1037
  * @deprecated Use `completionConfig` instead. This method will be removed in a future version.
1020
1038
  */
1021
1039
  async config(key, context, defaultValue, variables) {
1022
1040
  return this.completionConfig(key, context, defaultValue, variables);
1023
1041
  }
1024
- async judgeConfig(key, context, defaultValue, variables) {
1025
- this._ldClient.track(TRACK_JUDGE_SINGLE, context, key, 1);
1042
+ async _judgeConfig(key, context, defaultValue, variables) {
1026
1043
  const config = await this._evaluate(key, context, defaultValue, "judge", variables);
1027
1044
  return config;
1028
1045
  }
1046
+ async judgeConfig(key, context, defaultValue, variables) {
1047
+ this._ldClient.track(TRACK_USAGE_JUDGE_CONFIG, context, key, 1);
1048
+ return this._judgeConfig(key, context, defaultValue, variables);
1049
+ }
1029
1050
  async agentConfig(key, context, defaultValue, variables) {
1030
- this._ldClient.track(TRACK_AGENT_SINGLE, context, key, 1);
1051
+ this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1);
1031
1052
  const config = await this._evaluate(key, context, defaultValue, "agent", variables);
1032
1053
  return config;
1033
1054
  }
@@ -1038,7 +1059,12 @@ var LDAIClientImpl = class {
1038
1059
  return this.agentConfig(key, context, defaultValue, variables);
1039
1060
  }
1040
1061
  async agentConfigs(agentConfigs, context) {
1041
- this._ldClient.track(TRACK_AGENT_MULTIPLE, context, agentConfigs.length, agentConfigs.length);
1062
+ this._ldClient.track(
1063
+ TRACK_USAGE_AGENT_CONFIGS,
1064
+ context,
1065
+ agentConfigs.length,
1066
+ agentConfigs.length
1067
+ );
1042
1068
  const agents = {};
1043
1069
  await Promise.all(
1044
1070
  agentConfigs.map(async (config) => {
@@ -1061,8 +1087,8 @@ var LDAIClientImpl = class {
1061
1087
  return this.agentConfigs(agentConfigs, context);
1062
1088
  }
1063
1089
  async createChat(key, context, defaultValue, variables, defaultAiProvider) {
1064
- this._ldClient.track(TRACK_CONFIG_CREATE_CHAT, context, key, 1);
1065
- const config = await this.completionConfig(key, context, defaultValue, variables);
1090
+ this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1);
1091
+ const config = await this._completionConfig(key, context, defaultValue, variables);
1066
1092
  if (!config.enabled || !config.tracker) {
1067
1093
  this._logger?.info(`Chat configuration is disabled: ${key}`);
1068
1094
  return void 0;
@@ -1080,7 +1106,7 @@ var LDAIClientImpl = class {
1080
1106
  return new TrackedChat(config, config.tracker, provider, judges, this._logger);
1081
1107
  }
1082
1108
  async createJudge(key, context, defaultValue, variables, defaultAiProvider) {
1083
- this._ldClient.track(TRACK_JUDGE_CREATE, context, key, 1);
1109
+ this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1);
1084
1110
  try {
1085
1111
  if (variables?.message_history !== void 0) {
1086
1112
  this._logger?.warn(
@@ -1097,7 +1123,7 @@ var LDAIClientImpl = class {
1097
1123
  message_history: "{{message_history}}",
1098
1124
  response_to_evaluate: "{{response_to_evaluate}}"
1099
1125
  };
1100
- const judgeConfig = await this.judgeConfig(key, context, defaultValue, extendedVariables);
1126
+ const judgeConfig = await this._judgeConfig(key, context, defaultValue, extendedVariables);
1101
1127
  if (!judgeConfig.enabled || !judgeConfig.tracker) {
1102
1128
  this._logger?.info(`Judge configuration is disabled: ${key}`);
1103
1129
  return void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/LDAIClientImpl.ts","../src/api/chat/TrackedChat.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/judge/Judge.ts","../src/api/judge/EvaluationSchemaBuilder.ts","../src/api/providers/AIProvider.ts","../src/api/providers/AIProviderFactory.ts","../src/api/metrics/BedrockTokenUsage.ts","../src/api/metrics/OpenAiUsage.ts","../src/api/metrics/LDFeedbackKind.ts","../src/api/metrics/VercelAISDKTokenUsage.ts","../src/sdkInfo.ts","../src/LDAIConfigTrackerImpl.ts"],"sourcesContent":["/**\n * This is the API reference for the LaunchDarkly AI SDK for Server-Side JavaScript.\n *\n * In typical usage, you will call {@link initAi} once at startup time to obtain an instance of\n * {@link LDAIClient}, which provides access to all of the SDK's functionality.\n *\n * @packageDocumentation\n */\n// IMPORTANT: Namespace import required for CJS compatibility. js-server-sdk-common is CommonJS-only;\n// Node.js ESM can't reliably import named exports from CJS. DO NOT change to named imports.\nimport * as common from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIClient } from './api/LDAIClient';\nimport { LDAIClientImpl } from './LDAIClientImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Initialize a new AI client. This client will be used to perform any AI operations.\n * @param ldClient The base LaunchDarkly client.\n * @returns A new AI client.\n */\nexport function initAi(ldClient: LDClientMin): LDAIClient {\n return new LDAIClientImpl(ldClient);\n}\n\nexport type LDLogger = common.LDLogger;\n\nexport * from './api';\n","import Mustache from 'mustache';\n\nimport { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { TrackedChat } from './api/chat';\nimport {\n LDAIAgentConfig,\n LDAIAgentConfigDefault,\n LDAIAgentRequestConfig,\n LDAICompletionConfig,\n LDAICompletionConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { Judge } from './api/judge/Judge';\nimport { LDAIClient } from './api/LDAIClient';\nimport { AIProviderFactory, SupportedAIProvider } from './api/providers';\nimport { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Tracking event keys for AI SDK usage metrics.\n */\nconst TRACK_CONFIG_SINGLE = '$ld:ai:config:function:single';\nconst TRACK_CONFIG_CREATE_CHAT = '$ld:ai:config:function:createChat';\nconst TRACK_JUDGE_SINGLE = '$ld:ai:judge:function:single';\nconst TRACK_JUDGE_CREATE = '$ld:ai:judge:function:createJudge';\nconst TRACK_AGENT_SINGLE = '$ld:ai:agent:function:single';\nconst TRACK_AGENT_MULTIPLE = '$ld:ai:agent:function:multiple';\n\nexport class LDAIClientImpl implements LDAIClient {\n private _logger?: LDLogger;\n\n constructor(private _ldClient: LDClientMin) {\n this._logger = _ldClient.logger;\n }\n\n private _interpolateTemplate(template: string, variables: Record<string, unknown>): string {\n return Mustache.render(template, variables, undefined, { escape: (item: any) => item });\n }\n\n private async _evaluate(\n key: string,\n context: LDContext,\n defaultValue: LDAIConfigDefaultKind,\n mode: LDAIConfigMode,\n variables?: Record<string, unknown>,\n ): Promise<LDAIConfigKind> {\n const ldFlagValue = LDAIConfigUtils.toFlagValue(defaultValue, mode);\n\n const value: LDAIConfigFlagValue = await this._ldClient.variation(key, context, ldFlagValue);\n\n // Validate mode match\n // eslint-disable-next-line no-underscore-dangle\n const flagMode = value._ldMeta?.mode ?? 'completion';\n if (flagMode !== mode) {\n this._logger?.warn(\n `AI Config mode mismatch for ${key}: expected ${mode}, got ${flagMode}. Returning disabled config.`,\n );\n return LDAIConfigUtils.createDisabledConfig(key, mode);\n }\n\n const tracker = new LDAIConfigTrackerImpl(\n this._ldClient,\n key,\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.variationKey ?? '',\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.version ?? 1,\n value.model?.name ?? '',\n value.provider?.name ?? '',\n context,\n );\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, tracker);\n\n // Apply variable interpolation (always needed for ldctx)\n return this._applyInterpolation(config, context, variables);\n }\n\n private _applyInterpolation(\n config: LDAIConfigKind,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): LDAIConfigKind {\n const allVariables = { ...variables, ldctx: context };\n\n if ('messages' in config && config.messages) {\n return {\n ...config,\n messages: config.messages.map((entry: LDMessage) => ({\n ...entry,\n content: this._interpolateTemplate(entry.content, allVariables),\n })),\n };\n }\n\n if ('instructions' in config && config.instructions) {\n return {\n ...config,\n instructions: this._interpolateTemplate(config.instructions, allVariables),\n };\n }\n\n return config;\n }\n\n private async _initializeJudges(\n judgeConfigs: LDJudge[],\n context: LDContext,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Record<string, Judge>> {\n const judges: Record<string, Judge> = {};\n\n const judgePromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = await this.createJudge(\n judgeConfig.key,\n context,\n { enabled: false },\n variables,\n defaultAiProvider,\n );\n return judge ? { key: judgeConfig.key, judge } : null;\n });\n\n const results = await Promise.all(judgePromises);\n results.forEach((result) => {\n if (result) {\n judges[result.key] = result.judge;\n }\n });\n\n return judges;\n }\n\n async completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n this._ldClient.track(TRACK_CONFIG_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'completion', variables);\n return config as LDAICompletionConfig;\n }\n\n /**\n * @deprecated Use `completionConfig` instead. This method will be removed in a future version.\n */\n async config(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n return this.completionConfig(key, context, defaultValue, variables);\n }\n\n async judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n this._ldClient.track(TRACK_JUDGE_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'judge', variables);\n return config as LDAIJudgeConfig;\n }\n\n async agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n this._ldClient.track(TRACK_AGENT_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'agent', variables);\n return config as LDAIAgentConfig;\n }\n\n /**\n * @deprecated Use `agentConfig` instead. This method will be removed in a future version.\n */\n async agent(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n return this.agentConfig(key, context, defaultValue, variables);\n }\n\n async agentConfigs<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n this._ldClient.track(TRACK_AGENT_MULTIPLE, context, agentConfigs.length, agentConfigs.length);\n\n const agents = {} as Record<T[number]['key'], LDAIAgentConfig>;\n\n await Promise.all(\n agentConfigs.map(async (config) => {\n const agent = await this._evaluate(\n config.key,\n context,\n config.defaultValue,\n 'agent',\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent as LDAIAgentConfig;\n }),\n );\n\n return agents;\n }\n\n /**\n * @deprecated Use `agentConfigs` instead. This method will be removed in a future version.\n */\n async agents<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n return this.agentConfigs(agentConfigs, context);\n }\n\n async createChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n this._ldClient.track(TRACK_CONFIG_CREATE_CHAT, context, key, 1);\n\n const config = await this.completionConfig(key, context, defaultValue, variables);\n\n if (!config.enabled || !config.tracker) {\n this._logger?.info(`Chat configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(config, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n const judges = await this._initializeJudges(\n config.judgeConfiguration?.judges ?? [],\n context,\n variables,\n defaultAiProvider,\n );\n\n return new TrackedChat(config, config.tracker, provider, judges, this._logger);\n }\n\n async createJudge(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Judge | undefined> {\n this._ldClient.track(TRACK_JUDGE_CREATE, context, key, 1);\n\n try {\n if (variables?.message_history !== undefined) {\n this._logger?.warn(\n \"The variable 'message_history' is reserved by the judge and will be ignored.\",\n );\n }\n if (variables?.response_to_evaluate !== undefined) {\n this._logger?.warn(\n \"The variable 'response_to_evaluate' is reserved by the judge and will be ignored.\",\n );\n }\n\n // Overwrite reserved variables to ensure they remain as placeholders for judge evaluation\n const extendedVariables = {\n ...variables,\n message_history: '{{message_history}}',\n response_to_evaluate: '{{response_to_evaluate}}',\n };\n\n const judgeConfig = await this.judgeConfig(key, context, defaultValue, extendedVariables);\n\n if (!judgeConfig.enabled || !judgeConfig.tracker) {\n this._logger?.info(`Judge configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(judgeConfig, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n return new Judge(judgeConfig, judgeConfig.tracker, provider, this._logger);\n } catch (error) {\n this._logger?.error(`Failed to initialize judge ${key}:`, error);\n return undefined;\n }\n }\n\n /**\n * @deprecated Use `createChat` instead. This method will be removed in a future version.\n */\n async initChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n return this.createChat(key, context, defaultValue, variables, defaultAiProvider);\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAICompletionConfig, LDMessage } from '../config/types';\nimport { Judge } from '../judge/Judge';\nimport { JudgeResponse } from '../judge/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { ChatResponse } from './types';\n\n/**\n * Concrete implementation of TrackedChat that provides chat functionality\n * by delegating to an AIProvider implementation.\n * This class handles conversation management and tracking, while delegating\n * the actual model invocation to the provider.\n */\nexport class TrackedChat {\n protected messages: LDMessage[];\n\n constructor(\n protected readonly aiConfig: LDAICompletionConfig,\n protected readonly tracker: LDAIConfigTracker,\n protected readonly provider: AIProvider,\n protected readonly judges: Record<string, Judge> = {},\n private readonly _logger?: LDLogger,\n ) {\n this.messages = [];\n }\n\n /**\n * Invoke the chat model with a prompt string.\n * This method handles conversation management and tracking, delegating to the provider's invokeModel method.\n */\n async invoke(prompt: string): Promise<ChatResponse> {\n // Convert prompt string to LDMessage with role 'user' and add to conversation history\n const userMessage: LDMessage = {\n role: 'user',\n content: prompt,\n };\n this.messages.push(userMessage);\n\n // Prepend config messages to conversation history for model invocation\n const configMessages = this.aiConfig.messages || [];\n const allMessages = [...configMessages, ...this.messages];\n\n // Delegate to provider-specific implementation with tracking\n const response = await this.tracker.trackMetricsOf(\n (result: ChatResponse) => result.metrics,\n () => this.provider.invokeModel(allMessages),\n );\n\n if (\n this.aiConfig.judgeConfiguration?.judges &&\n this.aiConfig.judgeConfiguration.judges.length > 0\n ) {\n response.evaluations = this._evaluateWithJudges(this.messages, response);\n }\n\n this.messages.push(response.message);\n return response;\n }\n\n /**\n * Evaluates the response with all configured judges.\n * Returns a promise that resolves to an array of evaluation results.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @returns Promise resolving to array of judge evaluation results\n */\n private async _evaluateWithJudges(\n messages: LDMessage[],\n response: ChatResponse,\n ): Promise<Array<JudgeResponse | undefined>> {\n const judgeConfigs = this.aiConfig.judgeConfiguration!.judges;\n\n // Start all judge evaluations in parallel\n const evaluationPromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = this.judges[judgeConfig.key];\n if (!judge) {\n this._logger?.warn(\n `Judge configuration is not enabled: ${judgeConfig.key}`,\n this.tracker.getTrackData(),\n );\n return undefined;\n }\n\n const judgeResponse = await judge.evaluateMessages(\n messages,\n response,\n judgeConfig.samplingRate,\n );\n\n if (judgeResponse && judgeResponse.success) {\n this.tracker.trackJudgeResponse(judgeResponse);\n }\n\n return judgeResponse;\n });\n\n // ensure all evaluations complete even if some fail\n const results = await Promise.allSettled(evaluationPromises);\n\n return results.map((result) => (result.status === 'fulfilled' ? result.value : undefined));\n }\n\n /**\n * Get the underlying AI configuration used to initialize this TrackedChat.\n */\n getConfig(): LDAICompletionConfig {\n return this.aiConfig;\n }\n\n /**\n * Get the underlying AI configuration tracker used to initialize this TrackedChat.\n */\n getTracker(): LDAIConfigTracker {\n return this.tracker;\n }\n\n /**\n * Get the underlying AI provider instance.\n * This provides direct access to the provider for advanced use cases.\n */\n getProvider(): AIProvider {\n return this.provider;\n }\n\n /**\n * Get the judges associated with this TrackedChat.\n * Returns a record of judge instances keyed by their configuration keys.\n */\n getJudges(): Record<string, Judge> {\n return this.judges;\n }\n\n /**\n * Append messages to the conversation history.\n * Adds messages to the conversation history without invoking the model,\n * which is useful for managing multi-turn conversations or injecting context.\n *\n * @param messages Array of messages to append to the conversation history\n */\n appendMessages(messages: LDMessage[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Get all messages in the conversation history.\n *\n * @param includeConfigMessages Whether to include the config messages from the AIConfig.\n * Defaults to false.\n * @returns Array of messages. When includeConfigMessages is true, returns both config\n * messages and conversation history with config messages prepended. When false,\n * returns only the conversation history messages.\n */\n getMessages(includeConfigMessages: boolean = false): LDMessage[] {\n if (includeConfigMessages) {\n const configMessages = this.aiConfig.messages || [];\n return [...configMessages, ...this.messages];\n }\n return [...this.messages];\n }\n}\n","import { LDAIConfigTracker } from './LDAIConfigTracker';\nimport {\n LDAIAgentConfig,\n LDAICompletionConfig,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDJudgeConfiguration,\n LDMessage,\n LDModelConfig,\n LDProviderConfig,\n} from './types';\n\n/**\n * Internal flag value structure returned by LaunchDarkly.\n * This represents the raw data structure that LaunchDarkly returns for AI configuration flags.\n *\n * @internal - Not meant for external use\n */\nexport interface LDAIConfigFlagValue {\n _ldMeta?: {\n variationKey?: string;\n enabled: boolean;\n version?: number;\n mode?: LDAIConfigMode;\n };\n model?: LDModelConfig;\n messages?: LDMessage[];\n provider?: LDProviderConfig;\n instructions?: string;\n evaluationMetricKey?: string;\n evaluationMetricKeys?: string[];\n judgeConfiguration?: LDJudgeConfiguration;\n}\n\n/**\n * Utility class for converting between AI configuration types and LaunchDarkly flag values.\n *\n * @internal - This class and its types are internal implementation details and should not be used by SDK consumers.\n */\nexport class LDAIConfigUtils {\n /**\n * Converts a default AI configuration to a LaunchDarkly flag value format.\n *\n * @param config The default AI configuration to convert\n * @param mode The mode for the configuration\n * @returns The flag value structure for LaunchDarkly\n */\n static toFlagValue(config: LDAIConfigDefaultKind, mode: LDAIConfigMode): LDAIConfigFlagValue {\n const flagValue: LDAIConfigFlagValue = {\n _ldMeta: {\n variationKey: '', // Not available when converting from config\n enabled: config.enabled ?? false,\n mode,\n },\n model: config.model,\n };\n\n if ('messages' in config && config.messages !== undefined) {\n flagValue.messages = config.messages;\n }\n if (config.provider !== undefined) {\n flagValue.provider = config.provider;\n }\n if ('instructions' in config && config.instructions !== undefined) {\n flagValue.instructions = config.instructions;\n }\n if ('evaluationMetricKey' in config && config.evaluationMetricKey !== undefined) {\n flagValue.evaluationMetricKey = config.evaluationMetricKey;\n }\n if ('evaluationMetricKeys' in config && config.evaluationMetricKeys !== undefined) {\n flagValue.evaluationMetricKeys = config.evaluationMetricKeys;\n }\n if ('judgeConfiguration' in config && config.judgeConfiguration !== undefined) {\n flagValue.judgeConfiguration = config.judgeConfiguration;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIConfigKind {\n // Determine the actual mode from flag value\n // eslint-disable-next-line no-underscore-dangle\n const flagValueMode = flagValue._ldMeta?.mode;\n\n switch (flagValueMode) {\n case 'agent':\n return this.toAgentConfig(key, flagValue, tracker);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, tracker);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, tracker);\n }\n }\n\n /**\n * Creates a disabled configuration of the specified mode.\n *\n * @param mode The mode for the disabled config\n * @returns A disabled config of the appropriate type\n */\n static createDisabledConfig(key: string, mode: LDAIConfigMode): LDAIConfigKind {\n switch (mode) {\n case 'agent':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIJudgeConfig;\n case 'completion':\n default:\n // Default to completion config for completion mode or any unexpected mode\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAICompletionConfig;\n }\n }\n\n /**\n * Creates the base configuration that all config types share.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @returns Base configuration object\n */\n private static _toBaseConfig(key: string, flagValue: LDAIConfigFlagValue) {\n return {\n key,\n // eslint-disable-next-line no-underscore-dangle\n enabled: flagValue._ldMeta?.enabled ?? false,\n model: flagValue.model,\n provider: flagValue.provider,\n };\n }\n\n /**\n * Creates a completion config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIJudgeConfig {\n // Prioritize evaluationMetricKey, fallback to first valid (non-empty, non-whitespace) value in evaluationMetricKeys\n let evaluationMetricKey: string | undefined;\n if (flagValue.evaluationMetricKey && flagValue.evaluationMetricKey.trim().length > 0) {\n evaluationMetricKey = flagValue.evaluationMetricKey.trim();\n } else if (flagValue.evaluationMetricKeys && flagValue.evaluationMetricKeys.length > 0) {\n const validKey = flagValue.evaluationMetricKeys.find(\n (metricKey) => metricKey && metricKey.trim().length > 0,\n );\n evaluationMetricKey = validKey ? validKey.trim() : undefined;\n }\n\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import Mustache from 'mustache';\n\nimport { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { EvaluationSchemaBuilder } from './EvaluationSchemaBuilder';\nimport { EvalScore, JudgeResponse, StructuredResponse } from './types';\n\n/**\n * Judge implementation that handles evaluation functionality and conversation management.\n *\n * According to the AIEval spec, judges are AI Configs with mode: \"judge\" that evaluate\n * other AI Configs using structured output.\n */\nexport class Judge {\n private readonly _logger?: LDLogger;\n private readonly _evaluationResponseStructure: Record<string, unknown>;\n\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _aiConfigTracker: LDAIConfigTracker,\n private readonly _aiProvider: AIProvider,\n logger?: LDLogger,\n ) {\n this._logger = logger;\n const evaluationMetricKey = this._getEvaluationMetricKey();\n this._evaluationResponseStructure = EvaluationSchemaBuilder.build(evaluationMetricKey);\n }\n\n /**\n * Gets the evaluation metric key, prioritizing evaluationMetricKey over evaluationMetricKeys.\n * Falls back to the first valid (non-empty, non-whitespace) value in evaluationMetricKeys if evaluationMetricKey is not provided.\n * Treats empty strings and whitespace-only strings as invalid.\n * @returns The evaluation metric key, or undefined if not available\n */\n private _getEvaluationMetricKey(): string | undefined {\n if (\n this._aiConfig.evaluationMetricKey &&\n this._aiConfig.evaluationMetricKey.trim().length > 0\n ) {\n return this._aiConfig.evaluationMetricKey.trim();\n }\n if (this._aiConfig.evaluationMetricKeys && this._aiConfig.evaluationMetricKeys.length > 0) {\n const validKey = this._aiConfig.evaluationMetricKeys.find(\n (key) => key && key.trim().length > 0,\n );\n return validKey ? validKey.trim() : undefined;\n }\n return undefined;\n }\n\n /**\n * Evaluates an AI response using the judge's configuration.\n *\n * @param input The input prompt or question that was provided to the AI\n * @param output The AI-generated response to be evaluated\n * @param samplingRate Sampling rate (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluate(\n input: string,\n output: string,\n samplingRate: number = 1,\n ): Promise<JudgeResponse | undefined> {\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (!this._aiConfig.messages) {\n this._logger?.warn(\n 'Judge configuration must include messages',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (Math.random() > samplingRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${samplingRate}`);\n return undefined;\n }\n\n const messages = this._constructEvaluationMessages(input, output);\n\n const response = await this._aiConfigTracker.trackMetricsOf(\n (result: StructuredResponse) => result.metrics,\n () => this._aiProvider.invokeStructuredModel(messages, this._evaluationResponseStructure),\n );\n\n let { success } = response.metrics;\n\n const evals = this._parseEvaluationResponse(response.data, evaluationMetricKey);\n\n if (!evals[evaluationMetricKey]) {\n this._logger?.warn(\n 'Judge evaluation did not return the expected evaluation',\n this._aiConfigTracker.getTrackData(),\n );\n success = false;\n }\n\n return {\n evals,\n success,\n judgeConfigKey: this._aiConfig.key,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n return {\n evals: {},\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n judgeConfigKey: this._aiConfig.key,\n };\n }\n }\n\n /**\n * Evaluates an AI response from chat messages and response.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @param samplingRatio Sampling ratio (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio: number = 1,\n ): Promise<JudgeResponse | undefined> {\n const input = messages.length === 0 ? '' : messages.map((msg) => msg.content).join('\\r\\n');\n const output = response.message.content;\n\n return this.evaluate(input, output, samplingRatio);\n }\n\n /**\n * Returns the AI Config used by this judge.\n */\n getAIConfig(): LDAIJudgeConfig {\n return this._aiConfig;\n }\n\n /**\n * Returns the tracker associated with this judge.\n */\n getTracker(): LDAIConfigTracker {\n return this._aiConfigTracker;\n }\n\n /**\n * Returns the AI provider used by this judge.\n */\n getProvider(): AIProvider {\n return this._aiProvider;\n }\n\n /**\n * Constructs evaluation messages by combining judge's config messages with input/output.\n */\n private _constructEvaluationMessages(input: string, output: string): LDMessage[] {\n const messages: LDMessage[] = this._aiConfig.messages!.map((msg) => ({\n ...msg,\n content: this._interpolateMessage(msg.content, {\n message_history: input,\n response_to_evaluate: output,\n }),\n }));\n\n return messages;\n }\n\n /**\n * Interpolates message content with variables using Mustache templating.\n */\n private _interpolateMessage(content: string, variables: Record<string, string>): string {\n return Mustache.render(content, variables, undefined, { escape: (item: any) => item });\n }\n\n /**\n * Parses the structured evaluation response from the AI provider.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown>,\n evaluationMetricKey: string,\n ): Record<string, EvalScore> {\n const evaluations = data.evaluations as Record<string, unknown>;\n const results: Record<string, EvalScore> = {};\n\n if (!data.evaluations || typeof data.evaluations !== 'object') {\n this._logger?.warn('Invalid response: missing or invalid evaluations object');\n return results;\n }\n\n const evaluation = evaluations[evaluationMetricKey];\n\n if (!evaluation || typeof evaluation !== 'object') {\n this._logger?.warn(\n `Missing evaluation for metric key: ${evaluationMetricKey}`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n const evalData = evaluation as Record<string, unknown>;\n\n if (typeof evalData.score !== 'number' || evalData.score < 0 || evalData.score > 1) {\n this._logger?.warn(\n `Invalid score evaluated for ${evaluationMetricKey}: ${evalData.score}. Score must be a number between 0 and 1 inclusive`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n if (typeof evalData.reasoning !== 'string') {\n this._logger?.warn(\n `Invalid reasoning evaluated for ${evaluationMetricKey}: ${evalData.reasoning}. Reasoning must be a string`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n results[evaluationMetricKey] = {\n score: evalData.score,\n reasoning: evalData.reasoning,\n };\n\n return results;\n }\n}\n","/**\n * Internal class for building dynamic evaluation response schemas.\n * Not exported - only used internally by TrackedJudge.\n */\nclass EvaluationSchemaBuilder {\n static build(evaluationMetricKey?: string): Record<string, unknown> {\n if (!evaluationMetricKey) {\n return {};\n }\n return {\n type: 'object',\n properties: {\n evaluations: {\n type: 'object',\n description: `Object containing evaluation results for ${evaluationMetricKey} metric`,\n properties: {\n [evaluationMetricKey]: this._buildKeySchema(evaluationMetricKey),\n },\n required: [evaluationMetricKey],\n additionalProperties: false,\n },\n },\n required: ['evaluations'],\n additionalProperties: false,\n } as const;\n }\n\n private static _buildKeySchema(key: string) {\n return {\n type: 'object',\n properties: {\n score: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: `Score between 0.0 and 1.0 for ${key}`,\n },\n reasoning: {\n type: 'string',\n description: `Reasoning behind the score for ${key}`,\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n };\n }\n}\n\nexport { EvaluationSchemaBuilder };\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigKind, LDMessage } from '../config/types';\nimport { StructuredResponse } from '../judge/types';\n\n/**\n * Abstract base class for AI providers that implement chat model functionality.\n * This class provides the contract that all provider implementations must follow\n * to integrate with LaunchDarkly's tracking and configuration capabilities.\n *\n * Following the AICHAT spec recommendation to use base classes with non-abstract methods\n * for better extensibility and backwards compatibility.\n */\nexport abstract class AIProvider {\n protected readonly logger?: LDLogger;\n\n constructor(logger?: LDLogger) {\n this.logger = logger;\n }\n /**\n * Invoke the chat model with an array of messages.\n * This method should convert messages to provider format, invoke the model,\n * and return a ChatResponse with the result and metrics.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @returns Promise that resolves to a ChatResponse containing the model's response\n */\n async invokeModel(_messages: LDMessage[]): Promise<ChatResponse> {\n this.logger?.warn('invokeModel not implemented by this provider');\n return {\n message: {\n role: 'assistant',\n content: '',\n },\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Invoke the chat model with structured output support.\n * This method should convert messages to provider format, invoke the model with\n * structured output configuration, and return a structured response.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @param responseStructure Dictionary of output configurations keyed by output name\n * @returns Promise that resolves to a structured response\n */\n async invokeStructuredModel(\n _messages: LDMessage[],\n _responseStructure: Record<string, unknown>,\n ): Promise<StructuredResponse> {\n this.logger?.warn('invokeStructuredModel not implemented by this provider');\n return {\n data: {},\n rawResponse: '',\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Static method that constructs an instance of the provider.\n * Each provider implementation must provide their own static create method\n * that accepts an AIConfig and returns a configured instance.\n *\n * @param aiConfig The LaunchDarkly AI configuration\n * @param logger Optional logger for the provider\n * @returns Promise that resolves to a configured provider instance\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static async create(aiConfig: LDAIConfigKind, logger?: LDLogger): Promise<AIProvider> {\n throw new Error('Provider implementations must override the static create method');\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigKind } from '../config/types';\nimport { AIProvider } from './AIProvider';\n\n/**\n * List of supported AI providers.\n */\nexport const SUPPORTED_AI_PROVIDERS = [\n 'openai',\n // Multi-provider packages should be last in the list\n 'langchain',\n 'vercel',\n] as const;\n\n/**\n * Type representing the supported AI providers.\n */\nexport type SupportedAIProvider = (typeof SUPPORTED_AI_PROVIDERS)[number];\n\n/**\n * Factory for creating AIProvider instances based on the provider configuration.\n */\nexport class AIProviderFactory {\n /**\n * Create an AIProvider instance based on the AI configuration.\n * This method attempts to load provider-specific implementations dynamically.\n * Returns undefined if the provider is not supported.\n *\n * @param aiConfig The AI configuration\n * @param logger Optional logger for logging provider initialization\n * @param defaultAiProvider Optional default AI provider to use\n */\n static async create(\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<AIProvider | undefined> {\n const providerName = aiConfig.provider?.name?.toLowerCase();\n // Determine which providers to try based on defaultAiProvider\n const providersToTry = this._getProvidersToTry(defaultAiProvider, providerName);\n\n // Try each provider in order\n // eslint-disable-next-line no-restricted-syntax\n for (const providerType of providersToTry) {\n logger?.debug(\n `Attempting to create AIProvider for: ${aiConfig.provider?.name} with provider type: ${providerType}`,\n );\n // eslint-disable-next-line no-await-in-loop\n const provider = await this._tryCreateProvider(providerType, aiConfig, logger);\n if (provider) {\n logger?.debug(`Successfully created AIProvider for: ${aiConfig.provider?.name}`);\n return provider;\n }\n }\n\n // If no provider was successfully created, log a warning\n logger?.warn(\n `Provider is not supported or failed to initialize: ${aiConfig.provider?.name ?? 'unknown'}`,\n );\n return undefined;\n }\n\n /**\n * Determine which providers to try based on defaultAiProvider and providerName.\n */\n private static _getProvidersToTry(\n defaultAiProvider?: SupportedAIProvider,\n providerName?: string,\n ): SupportedAIProvider[] {\n // If defaultAiProvider is set, only try that specific provider\n if (defaultAiProvider) {\n return [defaultAiProvider];\n }\n\n // If no defaultAiProvider is set, try all providers in order\n const providerSet = new Set<SupportedAIProvider>();\n\n // First try the specific provider if it's supported\n if (providerName && SUPPORTED_AI_PROVIDERS.includes(providerName as SupportedAIProvider)) {\n providerSet.add(providerName as SupportedAIProvider);\n }\n\n // Then try multi-provider packages, but avoid duplicates\n const multiProviderPackages: SupportedAIProvider[] = ['langchain', 'vercel'];\n multiProviderPackages.forEach((provider) => {\n providerSet.add(provider);\n });\n\n return Array.from(providerSet);\n }\n\n /**\n * Try to create a provider of the specified type.\n */\n private static async _tryCreateProvider(\n providerType: SupportedAIProvider,\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n ): Promise<AIProvider | undefined> {\n try {\n let module;\n\n switch (providerType) {\n case 'openai': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-openai' as any);\n const provider = (await module.OpenAIProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'langchain': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-langchain' as any);\n const provider = (await module.LangChainProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'vercel': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-vercel' as any);\n const provider = (await module.VercelProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n default:\n return undefined;\n }\n } catch (error: any) {\n logger?.warn(\n `Unable to create AIProvider. Check that you have installed the correct package. ${error.message}`,\n );\n return undefined;\n }\n }\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createBedrockTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens || 0,\n input: data.inputTokens || 0,\n output: data.outputTokens || 0,\n };\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createOpenAiUsage(data: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n}): LDTokenUsage {\n return {\n total: data.total_tokens ?? 0,\n input: data.prompt_tokens ?? 0,\n output: data.completion_tokens ?? 0,\n };\n}\n","/**\n * Feedback about the generated content.\n */\nexport enum LDFeedbackKind {\n /**\n * The sentiment was positive.\n */\n Positive = 'positive',\n /**\n * The sentiment is negative.\n */\n Negative = 'negative',\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createVercelAISDKTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens ?? 0,\n input: data.inputTokens ?? data.promptTokens ?? 0,\n output: data.outputTokens ?? data.completionTokens ?? 0,\n };\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.16.3'; // x-release-please-version\n","import { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from './api/config';\nimport { LDAIMetricSummary } from './api/config/LDAIConfigTracker';\nimport { EvalScore, JudgeResponse } from './api/judge/types';\nimport {\n createBedrockTokenUsage,\n createOpenAiUsage,\n createVercelAISDKTokenUsage,\n LDAIMetrics,\n LDFeedbackKind,\n LDTokenUsage,\n} from './api/metrics';\nimport { LDClientMin } from './LDClientMin';\nimport { aiSdkName, aiSdkVersion } from './sdkInfo';\n\nexport class LDAIConfigTrackerImpl implements LDAIConfigTracker {\n private _trackedMetrics: LDAIMetricSummary = {};\n\n constructor(\n private _ldClient: LDClientMin,\n private _configKey: string,\n private _variationKey: string,\n private _version: number,\n private _modelName: string,\n private _providerName: string,\n private _context: LDContext,\n ) {}\n\n getTrackData(): {\n variationKey: string;\n configKey: string;\n version: number;\n modelName: string;\n providerName: string;\n aiSdkName: string;\n aiSdkVersion: string;\n } {\n return {\n variationKey: this._variationKey,\n configKey: this._configKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n aiSdkName,\n aiSdkVersion,\n };\n }\n\n trackDuration(duration: number): void {\n this._trackedMetrics.durationMs = duration;\n this._ldClient.track('$ld:ai:duration:total', this._context, this.getTrackData(), duration);\n }\n\n async trackDurationOf<TRes>(func: () => Promise<TRes>): Promise<TRes> {\n const startTime = Date.now();\n try {\n // Be sure to await here so that we can track the duration of the function and also handle errors.\n const result = await func();\n return result;\n } finally {\n const endTime = Date.now();\n const duration = endTime - startTime; // duration in milliseconds\n this.trackDuration(duration);\n }\n }\n\n trackTimeToFirstToken(timeToFirstTokenMs: number) {\n this._trackedMetrics.timeToFirstTokenMs = timeToFirstTokenMs;\n this._ldClient.track(\n '$ld:ai:tokens:ttf',\n this._context,\n this.getTrackData(),\n timeToFirstTokenMs,\n );\n }\n\n trackEvalScores(scores: Record<string, EvalScore>) {\n Object.entries(scores).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(metricKey, this._context, this.getTrackData(), evalScore.score);\n });\n }\n\n trackJudgeResponse(response: JudgeResponse) {\n Object.entries(response.evals).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(\n metricKey,\n this._context,\n { ...this.getTrackData(), judgeConfigKey: response.judgeConfigKey },\n evalScore.score,\n );\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n this._trackedMetrics.feedback = feedback;\n if (feedback.kind === LDFeedbackKind.Positive) {\n this._ldClient.track('$ld:ai:feedback:user:positive', this._context, this.getTrackData(), 1);\n } else if (feedback.kind === LDFeedbackKind.Negative) {\n this._ldClient.track('$ld:ai:feedback:user:negative', this._context, this.getTrackData(), 1);\n }\n }\n\n trackSuccess(): void {\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n this._trackedMetrics.success = false;\n this._ldClient.track('$ld:ai:generation:error', this._context, this.getTrackData(), 1);\n }\n\n async trackMetricsOf<TRes>(\n metricsExtractor: (result: TRes) => LDAIMetrics,\n func: () => Promise<TRes>,\n ): Promise<TRes> {\n let result: TRes;\n\n try {\n result = await this.trackDurationOf(func);\n } catch (err) {\n this.trackError();\n throw err;\n }\n\n // Extract metrics after successful AI call\n const metrics = metricsExtractor(result);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n\n return result;\n }\n\n trackStreamMetricsOf<TStream>(\n streamCreator: () => TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n ): TStream {\n const startTime = Date.now();\n\n try {\n // Create the stream synchronously\n const stream = streamCreator();\n\n // Start background metrics tracking (fire and forget)\n this._trackStreamMetricsInBackground(stream, metricsExtractor, startTime);\n\n // Return stream immediately for consumption\n return stream;\n } catch (error) {\n // Track error if stream creation fails\n this.trackDuration(Date.now() - startTime);\n this.trackError();\n throw error;\n }\n }\n\n private async _trackStreamMetricsInBackground<TStream>(\n stream: TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n startTime: number,\n ): Promise<void> {\n try {\n // Wait for metrics to be available\n const metrics = await metricsExtractor(stream);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n } catch (error) {\n // If metrics extraction fails, track error\n this.trackError();\n } finally {\n // Track duration regardless of success/error\n this.trackDuration(Date.now() - startTime);\n }\n }\n\n async trackOpenAIMetrics<\n TRes extends {\n usage?: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createOpenAiUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackBedrockConverseMetrics<\n TRes extends {\n $metadata: { httpStatusCode?: number };\n metrics?: { latencyMs?: number };\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n },\n >(res: TRes): TRes {\n if (res.$metadata?.httpStatusCode === 200) {\n this.trackSuccess();\n } else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {\n this.trackError();\n }\n if (res.metrics && res.metrics.latencyMs) {\n this.trackDuration(res.metrics.latencyMs);\n }\n if (res.usage) {\n this.trackTokens(createBedrockTokenUsage(res.usage));\n }\n return res;\n }\n\n async trackVercelAISDKGenerateTextMetrics<\n TRes extends {\n usage?: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createVercelAISDKTokenUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackTokens(tokens: LDTokenUsage): void {\n this._trackedMetrics.tokens = tokens;\n const trackData = this.getTrackData();\n if (tokens.total > 0) {\n this._ldClient.track('$ld:ai:tokens:total', this._context, trackData, tokens.total);\n }\n if (tokens.input > 0) {\n this._ldClient.track('$ld:ai:tokens:input', this._context, trackData, tokens.input);\n }\n if (tokens.output > 0) {\n this._ldClient.track('$ld:ai:tokens:output', this._context, trackData, tokens.output);\n }\n }\n\n /**\n * Get a summary of the tracked metrics.\n */\n getSummary(): LDAIMetricSummary {\n return { ...this._trackedMetrics };\n }\n}\n"],"mappings":"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","names":["import_mustache","Mustache","module","LDFeedbackKind","Mustache"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/LDAIClientImpl.ts","../src/api/chat/TrackedChat.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/judge/Judge.ts","../src/api/judge/EvaluationSchemaBuilder.ts","../src/api/providers/AIProvider.ts","../src/api/providers/AIProviderFactory.ts","../src/api/metrics/BedrockTokenUsage.ts","../src/api/metrics/OpenAiUsage.ts","../src/api/metrics/LDFeedbackKind.ts","../src/api/metrics/VercelAISDKTokenUsage.ts","../src/LDAIConfigTrackerImpl.ts","../src/sdkInfo.ts"],"sourcesContent":["/**\n * This is the API reference for the LaunchDarkly AI SDK for Server-Side JavaScript.\n *\n * In typical usage, you will call {@link initAi} once at startup time to obtain an instance of\n * {@link LDAIClient}, which provides access to all of the SDK's functionality.\n *\n * @packageDocumentation\n */\n// IMPORTANT: Namespace import required for CJS compatibility. js-server-sdk-common is CommonJS-only;\n// Node.js ESM can't reliably import named exports from CJS. DO NOT change to named imports.\nimport * as common from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIClient } from './api/LDAIClient';\nimport { LDAIClientImpl } from './LDAIClientImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Initialize a new AI client. This client will be used to perform any AI operations.\n * @param ldClient The base LaunchDarkly client.\n * @returns A new AI client.\n */\nexport function initAi(ldClient: LDClientMin): LDAIClient {\n return new LDAIClientImpl(ldClient);\n}\n\nexport type LDLogger = common.LDLogger;\n\nexport * from './api';\n","import Mustache from 'mustache';\n\nimport { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { TrackedChat } from './api/chat';\nimport {\n LDAIAgentConfig,\n LDAIAgentConfigDefault,\n LDAIAgentRequestConfig,\n LDAICompletionConfig,\n LDAICompletionConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { Judge } from './api/judge/Judge';\nimport { LDAIClient } from './api/LDAIClient';\nimport { AIProviderFactory, SupportedAIProvider } from './api/providers';\nimport { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl';\nimport { LDClientMin } from './LDClientMin';\nimport { aiSdkLanguage, aiSdkName, aiSdkVersion } from './sdkInfo';\n\n/**\n * Tracking event keys for AI SDK usage metrics.\n */\nconst TRACK_SDK_INFO = '$ld:ai:sdk:info';\nconst TRACK_USAGE_COMPLETION_CONFIG = '$ld:ai:usage:completion-config';\nconst TRACK_USAGE_CREATE_CHAT = '$ld:ai:usage:create-chat';\nconst TRACK_USAGE_JUDGE_CONFIG = '$ld:ai:usage:judge-config';\nconst TRACK_USAGE_CREATE_JUDGE = '$ld:ai:usage:create-judge';\nconst TRACK_USAGE_AGENT_CONFIG = '$ld:ai:usage:agent-config';\nconst TRACK_USAGE_AGENT_CONFIGS = '$ld:ai:usage:agent-configs';\n\nconst INIT_TRACK_CONTEXT: LDContext = {\n kind: 'ld_ai',\n key: 'ld-internal-tracking',\n anonymous: true,\n};\n\nexport class LDAIClientImpl implements LDAIClient {\n private _logger?: LDLogger;\n\n constructor(private _ldClient: LDClientMin) {\n this._logger = _ldClient.logger;\n this._ldClient.track(\n TRACK_SDK_INFO,\n INIT_TRACK_CONTEXT,\n {\n aiSdkName,\n aiSdkVersion,\n aiSdkLanguage,\n },\n 1,\n );\n }\n\n private _interpolateTemplate(template: string, variables: Record<string, unknown>): string {\n return Mustache.render(template, variables, undefined, { escape: (item: any) => item });\n }\n\n private async _evaluate(\n key: string,\n context: LDContext,\n defaultValue: LDAIConfigDefaultKind,\n mode: LDAIConfigMode,\n variables?: Record<string, unknown>,\n ): Promise<LDAIConfigKind> {\n const ldFlagValue = LDAIConfigUtils.toFlagValue(defaultValue, mode);\n\n const value: LDAIConfigFlagValue = await this._ldClient.variation(key, context, ldFlagValue);\n\n // Validate mode match\n // eslint-disable-next-line no-underscore-dangle\n const flagMode = value._ldMeta?.mode ?? 'completion';\n if (flagMode !== mode) {\n this._logger?.warn(\n `AI Config mode mismatch for ${key}: expected ${mode}, got ${flagMode}. Returning disabled config.`,\n );\n return LDAIConfigUtils.createDisabledConfig(key, mode);\n }\n\n const tracker = new LDAIConfigTrackerImpl(\n this._ldClient,\n key,\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.variationKey ?? '',\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.version ?? 1,\n value.model?.name ?? '',\n value.provider?.name ?? '',\n context,\n );\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, tracker);\n\n // Apply variable interpolation (always needed for ldctx)\n return this._applyInterpolation(config, context, variables);\n }\n\n private _applyInterpolation(\n config: LDAIConfigKind,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): LDAIConfigKind {\n const allVariables = { ...variables, ldctx: context };\n\n if ('messages' in config && config.messages) {\n return {\n ...config,\n messages: config.messages.map((entry: LDMessage) => ({\n ...entry,\n content: this._interpolateTemplate(entry.content, allVariables),\n })),\n };\n }\n\n if ('instructions' in config && config.instructions) {\n return {\n ...config,\n instructions: this._interpolateTemplate(config.instructions, allVariables),\n };\n }\n\n return config;\n }\n\n private async _initializeJudges(\n judgeConfigs: LDJudge[],\n context: LDContext,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Record<string, Judge>> {\n const judges: Record<string, Judge> = {};\n\n const judgePromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = await this.createJudge(\n judgeConfig.key,\n context,\n { enabled: false },\n variables,\n defaultAiProvider,\n );\n return judge ? { key: judgeConfig.key, judge } : null;\n });\n\n const results = await Promise.all(judgePromises);\n results.forEach((result) => {\n if (result) {\n judges[result.key] = result.judge;\n }\n });\n\n return judges;\n }\n\n private async _completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n const config = await this._evaluate(key, context, defaultValue, 'completion', variables);\n return config as LDAICompletionConfig;\n }\n\n async completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1);\n\n return this._completionConfig(key, context, defaultValue, variables);\n }\n\n /**\n * @deprecated Use `completionConfig` instead. This method will be removed in a future version.\n */\n async config(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n return this.completionConfig(key, context, defaultValue, variables);\n }\n\n private async _judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n const config = await this._evaluate(key, context, defaultValue, 'judge', variables);\n return config as LDAIJudgeConfig;\n }\n\n async judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n this._ldClient.track(TRACK_USAGE_JUDGE_CONFIG, context, key, 1);\n\n return this._judgeConfig(key, context, defaultValue, variables);\n }\n\n async agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'agent', variables);\n return config as LDAIAgentConfig;\n }\n\n /**\n * @deprecated Use `agentConfig` instead. This method will be removed in a future version.\n */\n async agent(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n return this.agentConfig(key, context, defaultValue, variables);\n }\n\n async agentConfigs<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n this._ldClient.track(\n TRACK_USAGE_AGENT_CONFIGS,\n context,\n agentConfigs.length,\n agentConfigs.length,\n );\n\n const agents = {} as Record<T[number]['key'], LDAIAgentConfig>;\n\n await Promise.all(\n agentConfigs.map(async (config) => {\n const agent = await this._evaluate(\n config.key,\n context,\n config.defaultValue,\n 'agent',\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent as LDAIAgentConfig;\n }),\n );\n\n return agents;\n }\n\n /**\n * @deprecated Use `agentConfigs` instead. This method will be removed in a future version.\n */\n async agents<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n return this.agentConfigs(agentConfigs, context);\n }\n\n async createChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1);\n\n const config = await this._completionConfig(key, context, defaultValue, variables);\n\n if (!config.enabled || !config.tracker) {\n this._logger?.info(`Chat configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(config, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n const judges = await this._initializeJudges(\n config.judgeConfiguration?.judges ?? [],\n context,\n variables,\n defaultAiProvider,\n );\n\n return new TrackedChat(config, config.tracker, provider, judges, this._logger);\n }\n\n async createJudge(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Judge | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1);\n\n try {\n if (variables?.message_history !== undefined) {\n this._logger?.warn(\n \"The variable 'message_history' is reserved by the judge and will be ignored.\",\n );\n }\n if (variables?.response_to_evaluate !== undefined) {\n this._logger?.warn(\n \"The variable 'response_to_evaluate' is reserved by the judge and will be ignored.\",\n );\n }\n\n // Overwrite reserved variables to ensure they remain as placeholders for judge evaluation\n const extendedVariables = {\n ...variables,\n message_history: '{{message_history}}',\n response_to_evaluate: '{{response_to_evaluate}}',\n };\n\n const judgeConfig = await this._judgeConfig(key, context, defaultValue, extendedVariables);\n\n if (!judgeConfig.enabled || !judgeConfig.tracker) {\n this._logger?.info(`Judge configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(judgeConfig, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n return new Judge(judgeConfig, judgeConfig.tracker, provider, this._logger);\n } catch (error) {\n this._logger?.error(`Failed to initialize judge ${key}:`, error);\n return undefined;\n }\n }\n\n /**\n * @deprecated Use `createChat` instead. This method will be removed in a future version.\n */\n async initChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n return this.createChat(key, context, defaultValue, variables, defaultAiProvider);\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAICompletionConfig, LDMessage } from '../config/types';\nimport { Judge } from '../judge/Judge';\nimport { JudgeResponse } from '../judge/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { ChatResponse } from './types';\n\n/**\n * Concrete implementation of TrackedChat that provides chat functionality\n * by delegating to an AIProvider implementation.\n * This class handles conversation management and tracking, while delegating\n * the actual model invocation to the provider.\n */\nexport class TrackedChat {\n protected messages: LDMessage[];\n\n constructor(\n protected readonly aiConfig: LDAICompletionConfig,\n protected readonly tracker: LDAIConfigTracker,\n protected readonly provider: AIProvider,\n protected readonly judges: Record<string, Judge> = {},\n private readonly _logger?: LDLogger,\n ) {\n this.messages = [];\n }\n\n /**\n * Invoke the chat model with a prompt string.\n * This method handles conversation management and tracking, delegating to the provider's invokeModel method.\n */\n async invoke(prompt: string): Promise<ChatResponse> {\n // Convert prompt string to LDMessage with role 'user' and add to conversation history\n const userMessage: LDMessage = {\n role: 'user',\n content: prompt,\n };\n this.messages.push(userMessage);\n\n // Prepend config messages to conversation history for model invocation\n const configMessages = this.aiConfig.messages || [];\n const allMessages = [...configMessages, ...this.messages];\n\n // Delegate to provider-specific implementation with tracking\n const response = await this.tracker.trackMetricsOf(\n (result: ChatResponse) => result.metrics,\n () => this.provider.invokeModel(allMessages),\n );\n\n if (\n this.aiConfig.judgeConfiguration?.judges &&\n this.aiConfig.judgeConfiguration.judges.length > 0\n ) {\n response.evaluations = this._evaluateWithJudges(this.messages, response);\n }\n\n this.messages.push(response.message);\n return response;\n }\n\n /**\n * Evaluates the response with all configured judges.\n * Returns a promise that resolves to an array of evaluation results.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @returns Promise resolving to array of judge evaluation results\n */\n private async _evaluateWithJudges(\n messages: LDMessage[],\n response: ChatResponse,\n ): Promise<Array<JudgeResponse | undefined>> {\n const judgeConfigs = this.aiConfig.judgeConfiguration!.judges;\n\n // Start all judge evaluations in parallel\n const evaluationPromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = this.judges[judgeConfig.key];\n if (!judge) {\n this._logger?.warn(\n `Judge configuration is not enabled: ${judgeConfig.key}`,\n this.tracker.getTrackData(),\n );\n return undefined;\n }\n\n const judgeResponse = await judge.evaluateMessages(\n messages,\n response,\n judgeConfig.samplingRate,\n );\n\n if (judgeResponse && judgeResponse.success) {\n this.tracker.trackJudgeResponse(judgeResponse);\n }\n\n return judgeResponse;\n });\n\n // ensure all evaluations complete even if some fail\n const results = await Promise.allSettled(evaluationPromises);\n\n return results.map((result) => (result.status === 'fulfilled' ? result.value : undefined));\n }\n\n /**\n * Get the underlying AI configuration used to initialize this TrackedChat.\n */\n getConfig(): LDAICompletionConfig {\n return this.aiConfig;\n }\n\n /**\n * Get the underlying AI configuration tracker used to initialize this TrackedChat.\n */\n getTracker(): LDAIConfigTracker {\n return this.tracker;\n }\n\n /**\n * Get the underlying AI provider instance.\n * This provides direct access to the provider for advanced use cases.\n */\n getProvider(): AIProvider {\n return this.provider;\n }\n\n /**\n * Get the judges associated with this TrackedChat.\n * Returns a record of judge instances keyed by their configuration keys.\n */\n getJudges(): Record<string, Judge> {\n return this.judges;\n }\n\n /**\n * Append messages to the conversation history.\n * Adds messages to the conversation history without invoking the model,\n * which is useful for managing multi-turn conversations or injecting context.\n *\n * @param messages Array of messages to append to the conversation history\n */\n appendMessages(messages: LDMessage[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Get all messages in the conversation history.\n *\n * @param includeConfigMessages Whether to include the config messages from the AIConfig.\n * Defaults to false.\n * @returns Array of messages. When includeConfigMessages is true, returns both config\n * messages and conversation history with config messages prepended. When false,\n * returns only the conversation history messages.\n */\n getMessages(includeConfigMessages: boolean = false): LDMessage[] {\n if (includeConfigMessages) {\n const configMessages = this.aiConfig.messages || [];\n return [...configMessages, ...this.messages];\n }\n return [...this.messages];\n }\n}\n","import { LDAIConfigTracker } from './LDAIConfigTracker';\nimport {\n LDAIAgentConfig,\n LDAICompletionConfig,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDJudgeConfiguration,\n LDMessage,\n LDModelConfig,\n LDProviderConfig,\n} from './types';\n\n/**\n * Internal flag value structure returned by LaunchDarkly.\n * This represents the raw data structure that LaunchDarkly returns for AI configuration flags.\n *\n * @internal - Not meant for external use\n */\nexport interface LDAIConfigFlagValue {\n _ldMeta?: {\n variationKey?: string;\n enabled: boolean;\n version?: number;\n mode?: LDAIConfigMode;\n };\n model?: LDModelConfig;\n messages?: LDMessage[];\n provider?: LDProviderConfig;\n instructions?: string;\n evaluationMetricKey?: string;\n evaluationMetricKeys?: string[];\n judgeConfiguration?: LDJudgeConfiguration;\n}\n\n/**\n * Utility class for converting between AI configuration types and LaunchDarkly flag values.\n *\n * @internal - This class and its types are internal implementation details and should not be used by SDK consumers.\n */\nexport class LDAIConfigUtils {\n /**\n * Converts a default AI configuration to a LaunchDarkly flag value format.\n *\n * @param config The default AI configuration to convert\n * @param mode The mode for the configuration\n * @returns The flag value structure for LaunchDarkly\n */\n static toFlagValue(config: LDAIConfigDefaultKind, mode: LDAIConfigMode): LDAIConfigFlagValue {\n const flagValue: LDAIConfigFlagValue = {\n _ldMeta: {\n variationKey: '', // Not available when converting from config\n enabled: config.enabled ?? false,\n mode,\n },\n model: config.model,\n };\n\n if ('messages' in config && config.messages !== undefined) {\n flagValue.messages = config.messages;\n }\n if (config.provider !== undefined) {\n flagValue.provider = config.provider;\n }\n if ('instructions' in config && config.instructions !== undefined) {\n flagValue.instructions = config.instructions;\n }\n if ('evaluationMetricKey' in config && config.evaluationMetricKey !== undefined) {\n flagValue.evaluationMetricKey = config.evaluationMetricKey;\n }\n if ('evaluationMetricKeys' in config && config.evaluationMetricKeys !== undefined) {\n flagValue.evaluationMetricKeys = config.evaluationMetricKeys;\n }\n if ('judgeConfiguration' in config && config.judgeConfiguration !== undefined) {\n flagValue.judgeConfiguration = config.judgeConfiguration;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIConfigKind {\n // Determine the actual mode from flag value\n // eslint-disable-next-line no-underscore-dangle\n const flagValueMode = flagValue._ldMeta?.mode;\n\n switch (flagValueMode) {\n case 'agent':\n return this.toAgentConfig(key, flagValue, tracker);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, tracker);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, tracker);\n }\n }\n\n /**\n * Creates a disabled configuration of the specified mode.\n *\n * @param mode The mode for the disabled config\n * @returns A disabled config of the appropriate type\n */\n static createDisabledConfig(key: string, mode: LDAIConfigMode): LDAIConfigKind {\n switch (mode) {\n case 'agent':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIJudgeConfig;\n case 'completion':\n default:\n // Default to completion config for completion mode or any unexpected mode\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAICompletionConfig;\n }\n }\n\n /**\n * Creates the base configuration that all config types share.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @returns Base configuration object\n */\n private static _toBaseConfig(key: string, flagValue: LDAIConfigFlagValue) {\n return {\n key,\n // eslint-disable-next-line no-underscore-dangle\n enabled: flagValue._ldMeta?.enabled ?? false,\n model: flagValue.model,\n provider: flagValue.provider,\n };\n }\n\n /**\n * Creates a completion config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIJudgeConfig {\n // Prioritize evaluationMetricKey, fallback to first valid (non-empty, non-whitespace) value in evaluationMetricKeys\n let evaluationMetricKey: string | undefined;\n if (flagValue.evaluationMetricKey && flagValue.evaluationMetricKey.trim().length > 0) {\n evaluationMetricKey = flagValue.evaluationMetricKey.trim();\n } else if (flagValue.evaluationMetricKeys && flagValue.evaluationMetricKeys.length > 0) {\n const validKey = flagValue.evaluationMetricKeys.find(\n (metricKey) => metricKey && metricKey.trim().length > 0,\n );\n evaluationMetricKey = validKey ? validKey.trim() : undefined;\n }\n\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import Mustache from 'mustache';\n\nimport { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { EvaluationSchemaBuilder } from './EvaluationSchemaBuilder';\nimport { EvalScore, JudgeResponse, StructuredResponse } from './types';\n\n/**\n * Judge implementation that handles evaluation functionality and conversation management.\n *\n * According to the AIEval spec, judges are AI Configs with mode: \"judge\" that evaluate\n * other AI Configs using structured output.\n */\nexport class Judge {\n private readonly _logger?: LDLogger;\n private readonly _evaluationResponseStructure: Record<string, unknown>;\n\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _aiConfigTracker: LDAIConfigTracker,\n private readonly _aiProvider: AIProvider,\n logger?: LDLogger,\n ) {\n this._logger = logger;\n const evaluationMetricKey = this._getEvaluationMetricKey();\n this._evaluationResponseStructure = EvaluationSchemaBuilder.build(evaluationMetricKey);\n }\n\n /**\n * Gets the evaluation metric key, prioritizing evaluationMetricKey over evaluationMetricKeys.\n * Falls back to the first valid (non-empty, non-whitespace) value in evaluationMetricKeys if evaluationMetricKey is not provided.\n * Treats empty strings and whitespace-only strings as invalid.\n * @returns The evaluation metric key, or undefined if not available\n */\n private _getEvaluationMetricKey(): string | undefined {\n if (\n this._aiConfig.evaluationMetricKey &&\n this._aiConfig.evaluationMetricKey.trim().length > 0\n ) {\n return this._aiConfig.evaluationMetricKey.trim();\n }\n if (this._aiConfig.evaluationMetricKeys && this._aiConfig.evaluationMetricKeys.length > 0) {\n const validKey = this._aiConfig.evaluationMetricKeys.find(\n (key) => key && key.trim().length > 0,\n );\n return validKey ? validKey.trim() : undefined;\n }\n return undefined;\n }\n\n /**\n * Evaluates an AI response using the judge's configuration.\n *\n * @param input The input prompt or question that was provided to the AI\n * @param output The AI-generated response to be evaluated\n * @param samplingRate Sampling rate (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluate(\n input: string,\n output: string,\n samplingRate: number = 1,\n ): Promise<JudgeResponse | undefined> {\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (!this._aiConfig.messages) {\n this._logger?.warn(\n 'Judge configuration must include messages',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (Math.random() > samplingRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${samplingRate}`);\n return undefined;\n }\n\n const messages = this._constructEvaluationMessages(input, output);\n\n const response = await this._aiConfigTracker.trackMetricsOf(\n (result: StructuredResponse) => result.metrics,\n () => this._aiProvider.invokeStructuredModel(messages, this._evaluationResponseStructure),\n );\n\n let { success } = response.metrics;\n\n const evals = this._parseEvaluationResponse(response.data, evaluationMetricKey);\n\n if (!evals[evaluationMetricKey]) {\n this._logger?.warn(\n 'Judge evaluation did not return the expected evaluation',\n this._aiConfigTracker.getTrackData(),\n );\n success = false;\n }\n\n return {\n evals,\n success,\n judgeConfigKey: this._aiConfig.key,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n return {\n evals: {},\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n judgeConfigKey: this._aiConfig.key,\n };\n }\n }\n\n /**\n * Evaluates an AI response from chat messages and response.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @param samplingRatio Sampling ratio (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio: number = 1,\n ): Promise<JudgeResponse | undefined> {\n const input = messages.length === 0 ? '' : messages.map((msg) => msg.content).join('\\r\\n');\n const output = response.message.content;\n\n return this.evaluate(input, output, samplingRatio);\n }\n\n /**\n * Returns the AI Config used by this judge.\n */\n getAIConfig(): LDAIJudgeConfig {\n return this._aiConfig;\n }\n\n /**\n * Returns the tracker associated with this judge.\n */\n getTracker(): LDAIConfigTracker {\n return this._aiConfigTracker;\n }\n\n /**\n * Returns the AI provider used by this judge.\n */\n getProvider(): AIProvider {\n return this._aiProvider;\n }\n\n /**\n * Constructs evaluation messages by combining judge's config messages with input/output.\n */\n private _constructEvaluationMessages(input: string, output: string): LDMessage[] {\n const messages: LDMessage[] = this._aiConfig.messages!.map((msg) => ({\n ...msg,\n content: this._interpolateMessage(msg.content, {\n message_history: input,\n response_to_evaluate: output,\n }),\n }));\n\n return messages;\n }\n\n /**\n * Interpolates message content with variables using Mustache templating.\n */\n private _interpolateMessage(content: string, variables: Record<string, string>): string {\n return Mustache.render(content, variables, undefined, { escape: (item: any) => item });\n }\n\n /**\n * Parses the structured evaluation response from the AI provider.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown>,\n evaluationMetricKey: string,\n ): Record<string, EvalScore> {\n const evaluations = data.evaluations as Record<string, unknown>;\n const results: Record<string, EvalScore> = {};\n\n if (!data.evaluations || typeof data.evaluations !== 'object') {\n this._logger?.warn('Invalid response: missing or invalid evaluations object');\n return results;\n }\n\n const evaluation = evaluations[evaluationMetricKey];\n\n if (!evaluation || typeof evaluation !== 'object') {\n this._logger?.warn(\n `Missing evaluation for metric key: ${evaluationMetricKey}`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n const evalData = evaluation as Record<string, unknown>;\n\n if (typeof evalData.score !== 'number' || evalData.score < 0 || evalData.score > 1) {\n this._logger?.warn(\n `Invalid score evaluated for ${evaluationMetricKey}: ${evalData.score}. Score must be a number between 0 and 1 inclusive`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n if (typeof evalData.reasoning !== 'string') {\n this._logger?.warn(\n `Invalid reasoning evaluated for ${evaluationMetricKey}: ${evalData.reasoning}. Reasoning must be a string`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n results[evaluationMetricKey] = {\n score: evalData.score,\n reasoning: evalData.reasoning,\n };\n\n return results;\n }\n}\n","/**\n * Internal class for building dynamic evaluation response schemas.\n * Not exported - only used internally by TrackedJudge.\n */\nclass EvaluationSchemaBuilder {\n static build(evaluationMetricKey?: string): Record<string, unknown> {\n if (!evaluationMetricKey) {\n return {};\n }\n return {\n type: 'object',\n properties: {\n evaluations: {\n type: 'object',\n description: `Object containing evaluation results for ${evaluationMetricKey} metric`,\n properties: {\n [evaluationMetricKey]: this._buildKeySchema(evaluationMetricKey),\n },\n required: [evaluationMetricKey],\n additionalProperties: false,\n },\n },\n required: ['evaluations'],\n additionalProperties: false,\n } as const;\n }\n\n private static _buildKeySchema(key: string) {\n return {\n type: 'object',\n properties: {\n score: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: `Score between 0.0 and 1.0 for ${key}`,\n },\n reasoning: {\n type: 'string',\n description: `Reasoning behind the score for ${key}`,\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n };\n }\n}\n\nexport { EvaluationSchemaBuilder };\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigKind, LDMessage } from '../config/types';\nimport { StructuredResponse } from '../judge/types';\n\n/**\n * Abstract base class for AI providers that implement chat model functionality.\n * This class provides the contract that all provider implementations must follow\n * to integrate with LaunchDarkly's tracking and configuration capabilities.\n *\n * Following the AICHAT spec recommendation to use base classes with non-abstract methods\n * for better extensibility and backwards compatibility.\n */\nexport abstract class AIProvider {\n protected readonly logger?: LDLogger;\n\n constructor(logger?: LDLogger) {\n this.logger = logger;\n }\n /**\n * Invoke the chat model with an array of messages.\n * This method should convert messages to provider format, invoke the model,\n * and return a ChatResponse with the result and metrics.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @returns Promise that resolves to a ChatResponse containing the model's response\n */\n async invokeModel(_messages: LDMessage[]): Promise<ChatResponse> {\n this.logger?.warn('invokeModel not implemented by this provider');\n return {\n message: {\n role: 'assistant',\n content: '',\n },\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Invoke the chat model with structured output support.\n * This method should convert messages to provider format, invoke the model with\n * structured output configuration, and return a structured response.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @param responseStructure Dictionary of output configurations keyed by output name\n * @returns Promise that resolves to a structured response\n */\n async invokeStructuredModel(\n _messages: LDMessage[],\n _responseStructure: Record<string, unknown>,\n ): Promise<StructuredResponse> {\n this.logger?.warn('invokeStructuredModel not implemented by this provider');\n return {\n data: {},\n rawResponse: '',\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Static method that constructs an instance of the provider.\n * Each provider implementation must provide their own static create method\n * that accepts an AIConfig and returns a configured instance.\n *\n * @param aiConfig The LaunchDarkly AI configuration\n * @param logger Optional logger for the provider\n * @returns Promise that resolves to a configured provider instance\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static async create(aiConfig: LDAIConfigKind, logger?: LDLogger): Promise<AIProvider> {\n throw new Error('Provider implementations must override the static create method');\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigKind } from '../config/types';\nimport { AIProvider } from './AIProvider';\n\n/**\n * List of supported AI providers.\n */\nexport const SUPPORTED_AI_PROVIDERS = [\n 'openai',\n // Multi-provider packages should be last in the list\n 'langchain',\n 'vercel',\n] as const;\n\n/**\n * Type representing the supported AI providers.\n */\nexport type SupportedAIProvider = (typeof SUPPORTED_AI_PROVIDERS)[number];\n\n/**\n * Factory for creating AIProvider instances based on the provider configuration.\n */\nexport class AIProviderFactory {\n /**\n * Create an AIProvider instance based on the AI configuration.\n * This method attempts to load provider-specific implementations dynamically.\n * Returns undefined if the provider is not supported.\n *\n * @param aiConfig The AI configuration\n * @param logger Optional logger for logging provider initialization\n * @param defaultAiProvider Optional default AI provider to use\n */\n static async create(\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<AIProvider | undefined> {\n const providerName = aiConfig.provider?.name?.toLowerCase();\n // Determine which providers to try based on defaultAiProvider\n const providersToTry = this._getProvidersToTry(defaultAiProvider, providerName);\n\n // Try each provider in order\n // eslint-disable-next-line no-restricted-syntax\n for (const providerType of providersToTry) {\n logger?.debug(\n `Attempting to create AIProvider for: ${aiConfig.provider?.name} with provider type: ${providerType}`,\n );\n // eslint-disable-next-line no-await-in-loop\n const provider = await this._tryCreateProvider(providerType, aiConfig, logger);\n if (provider) {\n logger?.debug(`Successfully created AIProvider for: ${aiConfig.provider?.name}`);\n return provider;\n }\n }\n\n // If no provider was successfully created, log a warning\n logger?.warn(\n `Provider is not supported or failed to initialize: ${aiConfig.provider?.name ?? 'unknown'}`,\n );\n return undefined;\n }\n\n /**\n * Determine which providers to try based on defaultAiProvider and providerName.\n */\n private static _getProvidersToTry(\n defaultAiProvider?: SupportedAIProvider,\n providerName?: string,\n ): SupportedAIProvider[] {\n // If defaultAiProvider is set, only try that specific provider\n if (defaultAiProvider) {\n return [defaultAiProvider];\n }\n\n // If no defaultAiProvider is set, try all providers in order\n const providerSet = new Set<SupportedAIProvider>();\n\n // First try the specific provider if it's supported\n if (providerName && SUPPORTED_AI_PROVIDERS.includes(providerName as SupportedAIProvider)) {\n providerSet.add(providerName as SupportedAIProvider);\n }\n\n // Then try multi-provider packages, but avoid duplicates\n const multiProviderPackages: SupportedAIProvider[] = ['langchain', 'vercel'];\n multiProviderPackages.forEach((provider) => {\n providerSet.add(provider);\n });\n\n return Array.from(providerSet);\n }\n\n /**\n * Try to create a provider of the specified type.\n */\n private static async _tryCreateProvider(\n providerType: SupportedAIProvider,\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n ): Promise<AIProvider | undefined> {\n try {\n let module;\n\n switch (providerType) {\n case 'openai': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-openai' as any);\n const provider = (await module.OpenAIProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'langchain': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-langchain' as any);\n const provider = (await module.LangChainProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'vercel': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-vercel' as any);\n const provider = (await module.VercelProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n default:\n return undefined;\n }\n } catch (error: any) {\n logger?.warn(\n `Unable to create AIProvider. Check that you have installed the correct package. ${error.message}`,\n );\n return undefined;\n }\n }\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createBedrockTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens || 0,\n input: data.inputTokens || 0,\n output: data.outputTokens || 0,\n };\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createOpenAiUsage(data: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n}): LDTokenUsage {\n return {\n total: data.total_tokens ?? 0,\n input: data.prompt_tokens ?? 0,\n output: data.completion_tokens ?? 0,\n };\n}\n","/**\n * Feedback about the generated content.\n */\nexport enum LDFeedbackKind {\n /**\n * The sentiment was positive.\n */\n Positive = 'positive',\n /**\n * The sentiment is negative.\n */\n Negative = 'negative',\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createVercelAISDKTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens ?? 0,\n input: data.inputTokens ?? data.promptTokens ?? 0,\n output: data.outputTokens ?? data.completionTokens ?? 0,\n };\n}\n","import { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from './api/config';\nimport { LDAIMetricSummary } from './api/config/LDAIConfigTracker';\nimport { EvalScore, JudgeResponse } from './api/judge/types';\nimport {\n createBedrockTokenUsage,\n createOpenAiUsage,\n createVercelAISDKTokenUsage,\n LDAIMetrics,\n LDFeedbackKind,\n LDTokenUsage,\n} from './api/metrics';\nimport { LDClientMin } from './LDClientMin';\n\nexport class LDAIConfigTrackerImpl implements LDAIConfigTracker {\n private _trackedMetrics: LDAIMetricSummary = {};\n\n constructor(\n private _ldClient: LDClientMin,\n private _configKey: string,\n private _variationKey: string,\n private _version: number,\n private _modelName: string,\n private _providerName: string,\n private _context: LDContext,\n ) {}\n\n getTrackData(): {\n variationKey: string;\n configKey: string;\n version: number;\n modelName: string;\n providerName: string;\n } {\n return {\n variationKey: this._variationKey,\n configKey: this._configKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n };\n }\n\n trackDuration(duration: number): void {\n this._trackedMetrics.durationMs = duration;\n this._ldClient.track('$ld:ai:duration:total', this._context, this.getTrackData(), duration);\n }\n\n async trackDurationOf<TRes>(func: () => Promise<TRes>): Promise<TRes> {\n const startTime = Date.now();\n try {\n // Be sure to await here so that we can track the duration of the function and also handle errors.\n const result = await func();\n return result;\n } finally {\n const endTime = Date.now();\n const duration = endTime - startTime; // duration in milliseconds\n this.trackDuration(duration);\n }\n }\n\n trackTimeToFirstToken(timeToFirstTokenMs: number) {\n this._trackedMetrics.timeToFirstTokenMs = timeToFirstTokenMs;\n this._ldClient.track(\n '$ld:ai:tokens:ttf',\n this._context,\n this.getTrackData(),\n timeToFirstTokenMs,\n );\n }\n\n trackEvalScores(scores: Record<string, EvalScore>) {\n Object.entries(scores).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(metricKey, this._context, this.getTrackData(), evalScore.score);\n });\n }\n\n trackJudgeResponse(response: JudgeResponse) {\n Object.entries(response.evals).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(\n metricKey,\n this._context,\n { ...this.getTrackData(), judgeConfigKey: response.judgeConfigKey },\n evalScore.score,\n );\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n this._trackedMetrics.feedback = feedback;\n if (feedback.kind === LDFeedbackKind.Positive) {\n this._ldClient.track('$ld:ai:feedback:user:positive', this._context, this.getTrackData(), 1);\n } else if (feedback.kind === LDFeedbackKind.Negative) {\n this._ldClient.track('$ld:ai:feedback:user:negative', this._context, this.getTrackData(), 1);\n }\n }\n\n trackSuccess(): void {\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n this._trackedMetrics.success = false;\n this._ldClient.track('$ld:ai:generation:error', this._context, this.getTrackData(), 1);\n }\n\n async trackMetricsOf<TRes>(\n metricsExtractor: (result: TRes) => LDAIMetrics,\n func: () => Promise<TRes>,\n ): Promise<TRes> {\n let result: TRes;\n\n try {\n result = await this.trackDurationOf(func);\n } catch (err) {\n this.trackError();\n throw err;\n }\n\n // Extract metrics after successful AI call\n const metrics = metricsExtractor(result);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n\n return result;\n }\n\n trackStreamMetricsOf<TStream>(\n streamCreator: () => TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n ): TStream {\n const startTime = Date.now();\n\n try {\n // Create the stream synchronously\n const stream = streamCreator();\n\n // Start background metrics tracking (fire and forget)\n this._trackStreamMetricsInBackground(stream, metricsExtractor, startTime);\n\n // Return stream immediately for consumption\n return stream;\n } catch (error) {\n // Track error if stream creation fails\n this.trackDuration(Date.now() - startTime);\n this.trackError();\n throw error;\n }\n }\n\n private async _trackStreamMetricsInBackground<TStream>(\n stream: TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n startTime: number,\n ): Promise<void> {\n try {\n // Wait for metrics to be available\n const metrics = await metricsExtractor(stream);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n } catch (error) {\n // If metrics extraction fails, track error\n this.trackError();\n } finally {\n // Track duration regardless of success/error\n this.trackDuration(Date.now() - startTime);\n }\n }\n\n async trackOpenAIMetrics<\n TRes extends {\n usage?: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createOpenAiUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackBedrockConverseMetrics<\n TRes extends {\n $metadata: { httpStatusCode?: number };\n metrics?: { latencyMs?: number };\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n },\n >(res: TRes): TRes {\n if (res.$metadata?.httpStatusCode === 200) {\n this.trackSuccess();\n } else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {\n this.trackError();\n }\n if (res.metrics && res.metrics.latencyMs) {\n this.trackDuration(res.metrics.latencyMs);\n }\n if (res.usage) {\n this.trackTokens(createBedrockTokenUsage(res.usage));\n }\n return res;\n }\n\n async trackVercelAISDKGenerateTextMetrics<\n TRes extends {\n usage?: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createVercelAISDKTokenUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackTokens(tokens: LDTokenUsage): void {\n this._trackedMetrics.tokens = tokens;\n const trackData = this.getTrackData();\n if (tokens.total > 0) {\n this._ldClient.track('$ld:ai:tokens:total', this._context, trackData, tokens.total);\n }\n if (tokens.input > 0) {\n this._ldClient.track('$ld:ai:tokens:input', this._context, trackData, tokens.input);\n }\n if (tokens.output > 0) {\n this._ldClient.track('$ld:ai:tokens:output', this._context, trackData, tokens.output);\n }\n }\n\n /**\n * Get a summary of the tracked metrics.\n */\n getSummary(): LDAIMetricSummary {\n return { ...this._trackedMetrics };\n }\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.16.5'; // x-release-please-version\nexport const aiSdkLanguage = 'javascript';\n"],"mappings":"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","names":["import_mustache","Mustache","module","LDFeedbackKind","Mustache"]}
package/dist/index.d.cts CHANGED
@@ -145,8 +145,6 @@ interface LDAIConfigTracker {
145
145
  version: number;
146
146
  modelName: string;
147
147
  providerName: string;
148
- aiSdkName: string;
149
- aiSdkVersion: string;
150
148
  };
151
149
  /**
152
150
  * Track the duration of generation.
package/dist/index.d.ts CHANGED
@@ -145,8 +145,6 @@ interface LDAIConfigTracker {
145
145
  version: number;
146
146
  modelName: string;
147
147
  providerName: string;
148
- aiSdkName: string;
149
- aiSdkVersion: string;
150
148
  };
151
149
  /**
152
150
  * Track the duration of generation.
package/dist/index.js CHANGED
@@ -696,10 +696,6 @@ function createVercelAISDKTokenUsage(data) {
696
696
  };
697
697
  }
698
698
 
699
- // src/sdkInfo.ts
700
- var aiSdkName = "@launchdarkly/server-sdk-ai";
701
- var aiSdkVersion = "0.16.3";
702
-
703
699
  // src/LDAIConfigTrackerImpl.ts
704
700
  var LDAIConfigTrackerImpl = class {
705
701
  constructor(_ldClient, _configKey, _variationKey, _version, _modelName, _providerName, _context) {
@@ -718,9 +714,7 @@ var LDAIConfigTrackerImpl = class {
718
714
  configKey: this._configKey,
719
715
  version: this._version,
720
716
  modelName: this._modelName,
721
- providerName: this._providerName,
722
- aiSdkName,
723
- aiSdkVersion
717
+ providerName: this._providerName
724
718
  };
725
719
  }
726
720
  trackDuration(duration) {
@@ -887,17 +881,38 @@ var LDAIConfigTrackerImpl = class {
887
881
  }
888
882
  };
889
883
 
884
+ // src/sdkInfo.ts
885
+ var aiSdkName = "@launchdarkly/server-sdk-ai";
886
+ var aiSdkVersion = "0.16.5";
887
+ var aiSdkLanguage = "javascript";
888
+
890
889
  // src/LDAIClientImpl.ts
891
- var TRACK_CONFIG_SINGLE = "$ld:ai:config:function:single";
892
- var TRACK_CONFIG_CREATE_CHAT = "$ld:ai:config:function:createChat";
893
- var TRACK_JUDGE_SINGLE = "$ld:ai:judge:function:single";
894
- var TRACK_JUDGE_CREATE = "$ld:ai:judge:function:createJudge";
895
- var TRACK_AGENT_SINGLE = "$ld:ai:agent:function:single";
896
- var TRACK_AGENT_MULTIPLE = "$ld:ai:agent:function:multiple";
890
+ var TRACK_SDK_INFO = "$ld:ai:sdk:info";
891
+ var TRACK_USAGE_COMPLETION_CONFIG = "$ld:ai:usage:completion-config";
892
+ var TRACK_USAGE_CREATE_CHAT = "$ld:ai:usage:create-chat";
893
+ var TRACK_USAGE_JUDGE_CONFIG = "$ld:ai:usage:judge-config";
894
+ var TRACK_USAGE_CREATE_JUDGE = "$ld:ai:usage:create-judge";
895
+ var TRACK_USAGE_AGENT_CONFIG = "$ld:ai:usage:agent-config";
896
+ var TRACK_USAGE_AGENT_CONFIGS = "$ld:ai:usage:agent-configs";
897
+ var INIT_TRACK_CONTEXT = {
898
+ kind: "ld_ai",
899
+ key: "ld-internal-tracking",
900
+ anonymous: true
901
+ };
897
902
  var LDAIClientImpl = class {
898
903
  constructor(_ldClient) {
899
904
  this._ldClient = _ldClient;
900
905
  this._logger = _ldClient.logger;
906
+ this._ldClient.track(
907
+ TRACK_SDK_INFO,
908
+ INIT_TRACK_CONTEXT,
909
+ {
910
+ aiSdkName,
911
+ aiSdkVersion,
912
+ aiSdkLanguage
913
+ },
914
+ 1
915
+ );
901
916
  }
902
917
  _interpolateTemplate(template, variables) {
903
918
  return Mustache2.render(template, variables, void 0, { escape: (item) => item });
@@ -965,24 +980,30 @@ var LDAIClientImpl = class {
965
980
  });
966
981
  return judges;
967
982
  }
968
- async completionConfig(key, context, defaultValue, variables) {
969
- this._ldClient.track(TRACK_CONFIG_SINGLE, context, key, 1);
983
+ async _completionConfig(key, context, defaultValue, variables) {
970
984
  const config = await this._evaluate(key, context, defaultValue, "completion", variables);
971
985
  return config;
972
986
  }
987
+ async completionConfig(key, context, defaultValue, variables) {
988
+ this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1);
989
+ return this._completionConfig(key, context, defaultValue, variables);
990
+ }
973
991
  /**
974
992
  * @deprecated Use `completionConfig` instead. This method will be removed in a future version.
975
993
  */
976
994
  async config(key, context, defaultValue, variables) {
977
995
  return this.completionConfig(key, context, defaultValue, variables);
978
996
  }
979
- async judgeConfig(key, context, defaultValue, variables) {
980
- this._ldClient.track(TRACK_JUDGE_SINGLE, context, key, 1);
997
+ async _judgeConfig(key, context, defaultValue, variables) {
981
998
  const config = await this._evaluate(key, context, defaultValue, "judge", variables);
982
999
  return config;
983
1000
  }
1001
+ async judgeConfig(key, context, defaultValue, variables) {
1002
+ this._ldClient.track(TRACK_USAGE_JUDGE_CONFIG, context, key, 1);
1003
+ return this._judgeConfig(key, context, defaultValue, variables);
1004
+ }
984
1005
  async agentConfig(key, context, defaultValue, variables) {
985
- this._ldClient.track(TRACK_AGENT_SINGLE, context, key, 1);
1006
+ this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1);
986
1007
  const config = await this._evaluate(key, context, defaultValue, "agent", variables);
987
1008
  return config;
988
1009
  }
@@ -993,7 +1014,12 @@ var LDAIClientImpl = class {
993
1014
  return this.agentConfig(key, context, defaultValue, variables);
994
1015
  }
995
1016
  async agentConfigs(agentConfigs, context) {
996
- this._ldClient.track(TRACK_AGENT_MULTIPLE, context, agentConfigs.length, agentConfigs.length);
1017
+ this._ldClient.track(
1018
+ TRACK_USAGE_AGENT_CONFIGS,
1019
+ context,
1020
+ agentConfigs.length,
1021
+ agentConfigs.length
1022
+ );
997
1023
  const agents = {};
998
1024
  await Promise.all(
999
1025
  agentConfigs.map(async (config) => {
@@ -1016,8 +1042,8 @@ var LDAIClientImpl = class {
1016
1042
  return this.agentConfigs(agentConfigs, context);
1017
1043
  }
1018
1044
  async createChat(key, context, defaultValue, variables, defaultAiProvider) {
1019
- this._ldClient.track(TRACK_CONFIG_CREATE_CHAT, context, key, 1);
1020
- const config = await this.completionConfig(key, context, defaultValue, variables);
1045
+ this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1);
1046
+ const config = await this._completionConfig(key, context, defaultValue, variables);
1021
1047
  if (!config.enabled || !config.tracker) {
1022
1048
  this._logger?.info(`Chat configuration is disabled: ${key}`);
1023
1049
  return void 0;
@@ -1035,7 +1061,7 @@ var LDAIClientImpl = class {
1035
1061
  return new TrackedChat(config, config.tracker, provider, judges, this._logger);
1036
1062
  }
1037
1063
  async createJudge(key, context, defaultValue, variables, defaultAiProvider) {
1038
- this._ldClient.track(TRACK_JUDGE_CREATE, context, key, 1);
1064
+ this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1);
1039
1065
  try {
1040
1066
  if (variables?.message_history !== void 0) {
1041
1067
  this._logger?.warn(
@@ -1052,7 +1078,7 @@ var LDAIClientImpl = class {
1052
1078
  message_history: "{{message_history}}",
1053
1079
  response_to_evaluate: "{{response_to_evaluate}}"
1054
1080
  };
1055
- const judgeConfig = await this.judgeConfig(key, context, defaultValue, extendedVariables);
1081
+ const judgeConfig = await this._judgeConfig(key, context, defaultValue, extendedVariables);
1056
1082
  if (!judgeConfig.enabled || !judgeConfig.tracker) {
1057
1083
  this._logger?.info(`Judge configuration is disabled: ${key}`);
1058
1084
  return void 0;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/LDAIClientImpl.ts","../src/api/chat/TrackedChat.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/judge/Judge.ts","../src/api/judge/EvaluationSchemaBuilder.ts","../src/api/providers/AIProvider.ts","../src/api/providers/AIProviderFactory.ts","../src/api/metrics/BedrockTokenUsage.ts","../src/api/metrics/OpenAiUsage.ts","../src/api/metrics/LDFeedbackKind.ts","../src/api/metrics/VercelAISDKTokenUsage.ts","../src/sdkInfo.ts","../src/LDAIConfigTrackerImpl.ts","../src/index.ts"],"sourcesContent":["import Mustache from 'mustache';\n\nimport { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { TrackedChat } from './api/chat';\nimport {\n LDAIAgentConfig,\n LDAIAgentConfigDefault,\n LDAIAgentRequestConfig,\n LDAICompletionConfig,\n LDAICompletionConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { Judge } from './api/judge/Judge';\nimport { LDAIClient } from './api/LDAIClient';\nimport { AIProviderFactory, SupportedAIProvider } from './api/providers';\nimport { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Tracking event keys for AI SDK usage metrics.\n */\nconst TRACK_CONFIG_SINGLE = '$ld:ai:config:function:single';\nconst TRACK_CONFIG_CREATE_CHAT = '$ld:ai:config:function:createChat';\nconst TRACK_JUDGE_SINGLE = '$ld:ai:judge:function:single';\nconst TRACK_JUDGE_CREATE = '$ld:ai:judge:function:createJudge';\nconst TRACK_AGENT_SINGLE = '$ld:ai:agent:function:single';\nconst TRACK_AGENT_MULTIPLE = '$ld:ai:agent:function:multiple';\n\nexport class LDAIClientImpl implements LDAIClient {\n private _logger?: LDLogger;\n\n constructor(private _ldClient: LDClientMin) {\n this._logger = _ldClient.logger;\n }\n\n private _interpolateTemplate(template: string, variables: Record<string, unknown>): string {\n return Mustache.render(template, variables, undefined, { escape: (item: any) => item });\n }\n\n private async _evaluate(\n key: string,\n context: LDContext,\n defaultValue: LDAIConfigDefaultKind,\n mode: LDAIConfigMode,\n variables?: Record<string, unknown>,\n ): Promise<LDAIConfigKind> {\n const ldFlagValue = LDAIConfigUtils.toFlagValue(defaultValue, mode);\n\n const value: LDAIConfigFlagValue = await this._ldClient.variation(key, context, ldFlagValue);\n\n // Validate mode match\n // eslint-disable-next-line no-underscore-dangle\n const flagMode = value._ldMeta?.mode ?? 'completion';\n if (flagMode !== mode) {\n this._logger?.warn(\n `AI Config mode mismatch for ${key}: expected ${mode}, got ${flagMode}. Returning disabled config.`,\n );\n return LDAIConfigUtils.createDisabledConfig(key, mode);\n }\n\n const tracker = new LDAIConfigTrackerImpl(\n this._ldClient,\n key,\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.variationKey ?? '',\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.version ?? 1,\n value.model?.name ?? '',\n value.provider?.name ?? '',\n context,\n );\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, tracker);\n\n // Apply variable interpolation (always needed for ldctx)\n return this._applyInterpolation(config, context, variables);\n }\n\n private _applyInterpolation(\n config: LDAIConfigKind,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): LDAIConfigKind {\n const allVariables = { ...variables, ldctx: context };\n\n if ('messages' in config && config.messages) {\n return {\n ...config,\n messages: config.messages.map((entry: LDMessage) => ({\n ...entry,\n content: this._interpolateTemplate(entry.content, allVariables),\n })),\n };\n }\n\n if ('instructions' in config && config.instructions) {\n return {\n ...config,\n instructions: this._interpolateTemplate(config.instructions, allVariables),\n };\n }\n\n return config;\n }\n\n private async _initializeJudges(\n judgeConfigs: LDJudge[],\n context: LDContext,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Record<string, Judge>> {\n const judges: Record<string, Judge> = {};\n\n const judgePromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = await this.createJudge(\n judgeConfig.key,\n context,\n { enabled: false },\n variables,\n defaultAiProvider,\n );\n return judge ? { key: judgeConfig.key, judge } : null;\n });\n\n const results = await Promise.all(judgePromises);\n results.forEach((result) => {\n if (result) {\n judges[result.key] = result.judge;\n }\n });\n\n return judges;\n }\n\n async completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n this._ldClient.track(TRACK_CONFIG_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'completion', variables);\n return config as LDAICompletionConfig;\n }\n\n /**\n * @deprecated Use `completionConfig` instead. This method will be removed in a future version.\n */\n async config(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n return this.completionConfig(key, context, defaultValue, variables);\n }\n\n async judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n this._ldClient.track(TRACK_JUDGE_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'judge', variables);\n return config as LDAIJudgeConfig;\n }\n\n async agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n this._ldClient.track(TRACK_AGENT_SINGLE, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'agent', variables);\n return config as LDAIAgentConfig;\n }\n\n /**\n * @deprecated Use `agentConfig` instead. This method will be removed in a future version.\n */\n async agent(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n return this.agentConfig(key, context, defaultValue, variables);\n }\n\n async agentConfigs<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n this._ldClient.track(TRACK_AGENT_MULTIPLE, context, agentConfigs.length, agentConfigs.length);\n\n const agents = {} as Record<T[number]['key'], LDAIAgentConfig>;\n\n await Promise.all(\n agentConfigs.map(async (config) => {\n const agent = await this._evaluate(\n config.key,\n context,\n config.defaultValue,\n 'agent',\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent as LDAIAgentConfig;\n }),\n );\n\n return agents;\n }\n\n /**\n * @deprecated Use `agentConfigs` instead. This method will be removed in a future version.\n */\n async agents<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n return this.agentConfigs(agentConfigs, context);\n }\n\n async createChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n this._ldClient.track(TRACK_CONFIG_CREATE_CHAT, context, key, 1);\n\n const config = await this.completionConfig(key, context, defaultValue, variables);\n\n if (!config.enabled || !config.tracker) {\n this._logger?.info(`Chat configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(config, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n const judges = await this._initializeJudges(\n config.judgeConfiguration?.judges ?? [],\n context,\n variables,\n defaultAiProvider,\n );\n\n return new TrackedChat(config, config.tracker, provider, judges, this._logger);\n }\n\n async createJudge(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Judge | undefined> {\n this._ldClient.track(TRACK_JUDGE_CREATE, context, key, 1);\n\n try {\n if (variables?.message_history !== undefined) {\n this._logger?.warn(\n \"The variable 'message_history' is reserved by the judge and will be ignored.\",\n );\n }\n if (variables?.response_to_evaluate !== undefined) {\n this._logger?.warn(\n \"The variable 'response_to_evaluate' is reserved by the judge and will be ignored.\",\n );\n }\n\n // Overwrite reserved variables to ensure they remain as placeholders for judge evaluation\n const extendedVariables = {\n ...variables,\n message_history: '{{message_history}}',\n response_to_evaluate: '{{response_to_evaluate}}',\n };\n\n const judgeConfig = await this.judgeConfig(key, context, defaultValue, extendedVariables);\n\n if (!judgeConfig.enabled || !judgeConfig.tracker) {\n this._logger?.info(`Judge configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(judgeConfig, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n return new Judge(judgeConfig, judgeConfig.tracker, provider, this._logger);\n } catch (error) {\n this._logger?.error(`Failed to initialize judge ${key}:`, error);\n return undefined;\n }\n }\n\n /**\n * @deprecated Use `createChat` instead. This method will be removed in a future version.\n */\n async initChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n return this.createChat(key, context, defaultValue, variables, defaultAiProvider);\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAICompletionConfig, LDMessage } from '../config/types';\nimport { Judge } from '../judge/Judge';\nimport { JudgeResponse } from '../judge/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { ChatResponse } from './types';\n\n/**\n * Concrete implementation of TrackedChat that provides chat functionality\n * by delegating to an AIProvider implementation.\n * This class handles conversation management and tracking, while delegating\n * the actual model invocation to the provider.\n */\nexport class TrackedChat {\n protected messages: LDMessage[];\n\n constructor(\n protected readonly aiConfig: LDAICompletionConfig,\n protected readonly tracker: LDAIConfigTracker,\n protected readonly provider: AIProvider,\n protected readonly judges: Record<string, Judge> = {},\n private readonly _logger?: LDLogger,\n ) {\n this.messages = [];\n }\n\n /**\n * Invoke the chat model with a prompt string.\n * This method handles conversation management and tracking, delegating to the provider's invokeModel method.\n */\n async invoke(prompt: string): Promise<ChatResponse> {\n // Convert prompt string to LDMessage with role 'user' and add to conversation history\n const userMessage: LDMessage = {\n role: 'user',\n content: prompt,\n };\n this.messages.push(userMessage);\n\n // Prepend config messages to conversation history for model invocation\n const configMessages = this.aiConfig.messages || [];\n const allMessages = [...configMessages, ...this.messages];\n\n // Delegate to provider-specific implementation with tracking\n const response = await this.tracker.trackMetricsOf(\n (result: ChatResponse) => result.metrics,\n () => this.provider.invokeModel(allMessages),\n );\n\n if (\n this.aiConfig.judgeConfiguration?.judges &&\n this.aiConfig.judgeConfiguration.judges.length > 0\n ) {\n response.evaluations = this._evaluateWithJudges(this.messages, response);\n }\n\n this.messages.push(response.message);\n return response;\n }\n\n /**\n * Evaluates the response with all configured judges.\n * Returns a promise that resolves to an array of evaluation results.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @returns Promise resolving to array of judge evaluation results\n */\n private async _evaluateWithJudges(\n messages: LDMessage[],\n response: ChatResponse,\n ): Promise<Array<JudgeResponse | undefined>> {\n const judgeConfigs = this.aiConfig.judgeConfiguration!.judges;\n\n // Start all judge evaluations in parallel\n const evaluationPromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = this.judges[judgeConfig.key];\n if (!judge) {\n this._logger?.warn(\n `Judge configuration is not enabled: ${judgeConfig.key}`,\n this.tracker.getTrackData(),\n );\n return undefined;\n }\n\n const judgeResponse = await judge.evaluateMessages(\n messages,\n response,\n judgeConfig.samplingRate,\n );\n\n if (judgeResponse && judgeResponse.success) {\n this.tracker.trackJudgeResponse(judgeResponse);\n }\n\n return judgeResponse;\n });\n\n // ensure all evaluations complete even if some fail\n const results = await Promise.allSettled(evaluationPromises);\n\n return results.map((result) => (result.status === 'fulfilled' ? result.value : undefined));\n }\n\n /**\n * Get the underlying AI configuration used to initialize this TrackedChat.\n */\n getConfig(): LDAICompletionConfig {\n return this.aiConfig;\n }\n\n /**\n * Get the underlying AI configuration tracker used to initialize this TrackedChat.\n */\n getTracker(): LDAIConfigTracker {\n return this.tracker;\n }\n\n /**\n * Get the underlying AI provider instance.\n * This provides direct access to the provider for advanced use cases.\n */\n getProvider(): AIProvider {\n return this.provider;\n }\n\n /**\n * Get the judges associated with this TrackedChat.\n * Returns a record of judge instances keyed by their configuration keys.\n */\n getJudges(): Record<string, Judge> {\n return this.judges;\n }\n\n /**\n * Append messages to the conversation history.\n * Adds messages to the conversation history without invoking the model,\n * which is useful for managing multi-turn conversations or injecting context.\n *\n * @param messages Array of messages to append to the conversation history\n */\n appendMessages(messages: LDMessage[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Get all messages in the conversation history.\n *\n * @param includeConfigMessages Whether to include the config messages from the AIConfig.\n * Defaults to false.\n * @returns Array of messages. When includeConfigMessages is true, returns both config\n * messages and conversation history with config messages prepended. When false,\n * returns only the conversation history messages.\n */\n getMessages(includeConfigMessages: boolean = false): LDMessage[] {\n if (includeConfigMessages) {\n const configMessages = this.aiConfig.messages || [];\n return [...configMessages, ...this.messages];\n }\n return [...this.messages];\n }\n}\n","import { LDAIConfigTracker } from './LDAIConfigTracker';\nimport {\n LDAIAgentConfig,\n LDAICompletionConfig,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDJudgeConfiguration,\n LDMessage,\n LDModelConfig,\n LDProviderConfig,\n} from './types';\n\n/**\n * Internal flag value structure returned by LaunchDarkly.\n * This represents the raw data structure that LaunchDarkly returns for AI configuration flags.\n *\n * @internal - Not meant for external use\n */\nexport interface LDAIConfigFlagValue {\n _ldMeta?: {\n variationKey?: string;\n enabled: boolean;\n version?: number;\n mode?: LDAIConfigMode;\n };\n model?: LDModelConfig;\n messages?: LDMessage[];\n provider?: LDProviderConfig;\n instructions?: string;\n evaluationMetricKey?: string;\n evaluationMetricKeys?: string[];\n judgeConfiguration?: LDJudgeConfiguration;\n}\n\n/**\n * Utility class for converting between AI configuration types and LaunchDarkly flag values.\n *\n * @internal - This class and its types are internal implementation details and should not be used by SDK consumers.\n */\nexport class LDAIConfigUtils {\n /**\n * Converts a default AI configuration to a LaunchDarkly flag value format.\n *\n * @param config The default AI configuration to convert\n * @param mode The mode for the configuration\n * @returns The flag value structure for LaunchDarkly\n */\n static toFlagValue(config: LDAIConfigDefaultKind, mode: LDAIConfigMode): LDAIConfigFlagValue {\n const flagValue: LDAIConfigFlagValue = {\n _ldMeta: {\n variationKey: '', // Not available when converting from config\n enabled: config.enabled ?? false,\n mode,\n },\n model: config.model,\n };\n\n if ('messages' in config && config.messages !== undefined) {\n flagValue.messages = config.messages;\n }\n if (config.provider !== undefined) {\n flagValue.provider = config.provider;\n }\n if ('instructions' in config && config.instructions !== undefined) {\n flagValue.instructions = config.instructions;\n }\n if ('evaluationMetricKey' in config && config.evaluationMetricKey !== undefined) {\n flagValue.evaluationMetricKey = config.evaluationMetricKey;\n }\n if ('evaluationMetricKeys' in config && config.evaluationMetricKeys !== undefined) {\n flagValue.evaluationMetricKeys = config.evaluationMetricKeys;\n }\n if ('judgeConfiguration' in config && config.judgeConfiguration !== undefined) {\n flagValue.judgeConfiguration = config.judgeConfiguration;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIConfigKind {\n // Determine the actual mode from flag value\n // eslint-disable-next-line no-underscore-dangle\n const flagValueMode = flagValue._ldMeta?.mode;\n\n switch (flagValueMode) {\n case 'agent':\n return this.toAgentConfig(key, flagValue, tracker);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, tracker);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, tracker);\n }\n }\n\n /**\n * Creates a disabled configuration of the specified mode.\n *\n * @param mode The mode for the disabled config\n * @returns A disabled config of the appropriate type\n */\n static createDisabledConfig(key: string, mode: LDAIConfigMode): LDAIConfigKind {\n switch (mode) {\n case 'agent':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIJudgeConfig;\n case 'completion':\n default:\n // Default to completion config for completion mode or any unexpected mode\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAICompletionConfig;\n }\n }\n\n /**\n * Creates the base configuration that all config types share.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @returns Base configuration object\n */\n private static _toBaseConfig(key: string, flagValue: LDAIConfigFlagValue) {\n return {\n key,\n // eslint-disable-next-line no-underscore-dangle\n enabled: flagValue._ldMeta?.enabled ?? false,\n model: flagValue.model,\n provider: flagValue.provider,\n };\n }\n\n /**\n * Creates a completion config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIJudgeConfig {\n // Prioritize evaluationMetricKey, fallback to first valid (non-empty, non-whitespace) value in evaluationMetricKeys\n let evaluationMetricKey: string | undefined;\n if (flagValue.evaluationMetricKey && flagValue.evaluationMetricKey.trim().length > 0) {\n evaluationMetricKey = flagValue.evaluationMetricKey.trim();\n } else if (flagValue.evaluationMetricKeys && flagValue.evaluationMetricKeys.length > 0) {\n const validKey = flagValue.evaluationMetricKeys.find(\n (metricKey) => metricKey && metricKey.trim().length > 0,\n );\n evaluationMetricKey = validKey ? validKey.trim() : undefined;\n }\n\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import Mustache from 'mustache';\n\nimport { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { EvaluationSchemaBuilder } from './EvaluationSchemaBuilder';\nimport { EvalScore, JudgeResponse, StructuredResponse } from './types';\n\n/**\n * Judge implementation that handles evaluation functionality and conversation management.\n *\n * According to the AIEval spec, judges are AI Configs with mode: \"judge\" that evaluate\n * other AI Configs using structured output.\n */\nexport class Judge {\n private readonly _logger?: LDLogger;\n private readonly _evaluationResponseStructure: Record<string, unknown>;\n\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _aiConfigTracker: LDAIConfigTracker,\n private readonly _aiProvider: AIProvider,\n logger?: LDLogger,\n ) {\n this._logger = logger;\n const evaluationMetricKey = this._getEvaluationMetricKey();\n this._evaluationResponseStructure = EvaluationSchemaBuilder.build(evaluationMetricKey);\n }\n\n /**\n * Gets the evaluation metric key, prioritizing evaluationMetricKey over evaluationMetricKeys.\n * Falls back to the first valid (non-empty, non-whitespace) value in evaluationMetricKeys if evaluationMetricKey is not provided.\n * Treats empty strings and whitespace-only strings as invalid.\n * @returns The evaluation metric key, or undefined if not available\n */\n private _getEvaluationMetricKey(): string | undefined {\n if (\n this._aiConfig.evaluationMetricKey &&\n this._aiConfig.evaluationMetricKey.trim().length > 0\n ) {\n return this._aiConfig.evaluationMetricKey.trim();\n }\n if (this._aiConfig.evaluationMetricKeys && this._aiConfig.evaluationMetricKeys.length > 0) {\n const validKey = this._aiConfig.evaluationMetricKeys.find(\n (key) => key && key.trim().length > 0,\n );\n return validKey ? validKey.trim() : undefined;\n }\n return undefined;\n }\n\n /**\n * Evaluates an AI response using the judge's configuration.\n *\n * @param input The input prompt or question that was provided to the AI\n * @param output The AI-generated response to be evaluated\n * @param samplingRate Sampling rate (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluate(\n input: string,\n output: string,\n samplingRate: number = 1,\n ): Promise<JudgeResponse | undefined> {\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (!this._aiConfig.messages) {\n this._logger?.warn(\n 'Judge configuration must include messages',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (Math.random() > samplingRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${samplingRate}`);\n return undefined;\n }\n\n const messages = this._constructEvaluationMessages(input, output);\n\n const response = await this._aiConfigTracker.trackMetricsOf(\n (result: StructuredResponse) => result.metrics,\n () => this._aiProvider.invokeStructuredModel(messages, this._evaluationResponseStructure),\n );\n\n let { success } = response.metrics;\n\n const evals = this._parseEvaluationResponse(response.data, evaluationMetricKey);\n\n if (!evals[evaluationMetricKey]) {\n this._logger?.warn(\n 'Judge evaluation did not return the expected evaluation',\n this._aiConfigTracker.getTrackData(),\n );\n success = false;\n }\n\n return {\n evals,\n success,\n judgeConfigKey: this._aiConfig.key,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n return {\n evals: {},\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n judgeConfigKey: this._aiConfig.key,\n };\n }\n }\n\n /**\n * Evaluates an AI response from chat messages and response.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @param samplingRatio Sampling ratio (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio: number = 1,\n ): Promise<JudgeResponse | undefined> {\n const input = messages.length === 0 ? '' : messages.map((msg) => msg.content).join('\\r\\n');\n const output = response.message.content;\n\n return this.evaluate(input, output, samplingRatio);\n }\n\n /**\n * Returns the AI Config used by this judge.\n */\n getAIConfig(): LDAIJudgeConfig {\n return this._aiConfig;\n }\n\n /**\n * Returns the tracker associated with this judge.\n */\n getTracker(): LDAIConfigTracker {\n return this._aiConfigTracker;\n }\n\n /**\n * Returns the AI provider used by this judge.\n */\n getProvider(): AIProvider {\n return this._aiProvider;\n }\n\n /**\n * Constructs evaluation messages by combining judge's config messages with input/output.\n */\n private _constructEvaluationMessages(input: string, output: string): LDMessage[] {\n const messages: LDMessage[] = this._aiConfig.messages!.map((msg) => ({\n ...msg,\n content: this._interpolateMessage(msg.content, {\n message_history: input,\n response_to_evaluate: output,\n }),\n }));\n\n return messages;\n }\n\n /**\n * Interpolates message content with variables using Mustache templating.\n */\n private _interpolateMessage(content: string, variables: Record<string, string>): string {\n return Mustache.render(content, variables, undefined, { escape: (item: any) => item });\n }\n\n /**\n * Parses the structured evaluation response from the AI provider.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown>,\n evaluationMetricKey: string,\n ): Record<string, EvalScore> {\n const evaluations = data.evaluations as Record<string, unknown>;\n const results: Record<string, EvalScore> = {};\n\n if (!data.evaluations || typeof data.evaluations !== 'object') {\n this._logger?.warn('Invalid response: missing or invalid evaluations object');\n return results;\n }\n\n const evaluation = evaluations[evaluationMetricKey];\n\n if (!evaluation || typeof evaluation !== 'object') {\n this._logger?.warn(\n `Missing evaluation for metric key: ${evaluationMetricKey}`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n const evalData = evaluation as Record<string, unknown>;\n\n if (typeof evalData.score !== 'number' || evalData.score < 0 || evalData.score > 1) {\n this._logger?.warn(\n `Invalid score evaluated for ${evaluationMetricKey}: ${evalData.score}. Score must be a number between 0 and 1 inclusive`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n if (typeof evalData.reasoning !== 'string') {\n this._logger?.warn(\n `Invalid reasoning evaluated for ${evaluationMetricKey}: ${evalData.reasoning}. Reasoning must be a string`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n results[evaluationMetricKey] = {\n score: evalData.score,\n reasoning: evalData.reasoning,\n };\n\n return results;\n }\n}\n","/**\n * Internal class for building dynamic evaluation response schemas.\n * Not exported - only used internally by TrackedJudge.\n */\nclass EvaluationSchemaBuilder {\n static build(evaluationMetricKey?: string): Record<string, unknown> {\n if (!evaluationMetricKey) {\n return {};\n }\n return {\n type: 'object',\n properties: {\n evaluations: {\n type: 'object',\n description: `Object containing evaluation results for ${evaluationMetricKey} metric`,\n properties: {\n [evaluationMetricKey]: this._buildKeySchema(evaluationMetricKey),\n },\n required: [evaluationMetricKey],\n additionalProperties: false,\n },\n },\n required: ['evaluations'],\n additionalProperties: false,\n } as const;\n }\n\n private static _buildKeySchema(key: string) {\n return {\n type: 'object',\n properties: {\n score: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: `Score between 0.0 and 1.0 for ${key}`,\n },\n reasoning: {\n type: 'string',\n description: `Reasoning behind the score for ${key}`,\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n };\n }\n}\n\nexport { EvaluationSchemaBuilder };\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigKind, LDMessage } from '../config/types';\nimport { StructuredResponse } from '../judge/types';\n\n/**\n * Abstract base class for AI providers that implement chat model functionality.\n * This class provides the contract that all provider implementations must follow\n * to integrate with LaunchDarkly's tracking and configuration capabilities.\n *\n * Following the AICHAT spec recommendation to use base classes with non-abstract methods\n * for better extensibility and backwards compatibility.\n */\nexport abstract class AIProvider {\n protected readonly logger?: LDLogger;\n\n constructor(logger?: LDLogger) {\n this.logger = logger;\n }\n /**\n * Invoke the chat model with an array of messages.\n * This method should convert messages to provider format, invoke the model,\n * and return a ChatResponse with the result and metrics.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @returns Promise that resolves to a ChatResponse containing the model's response\n */\n async invokeModel(_messages: LDMessage[]): Promise<ChatResponse> {\n this.logger?.warn('invokeModel not implemented by this provider');\n return {\n message: {\n role: 'assistant',\n content: '',\n },\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Invoke the chat model with structured output support.\n * This method should convert messages to provider format, invoke the model with\n * structured output configuration, and return a structured response.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @param responseStructure Dictionary of output configurations keyed by output name\n * @returns Promise that resolves to a structured response\n */\n async invokeStructuredModel(\n _messages: LDMessage[],\n _responseStructure: Record<string, unknown>,\n ): Promise<StructuredResponse> {\n this.logger?.warn('invokeStructuredModel not implemented by this provider');\n return {\n data: {},\n rawResponse: '',\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Static method that constructs an instance of the provider.\n * Each provider implementation must provide their own static create method\n * that accepts an AIConfig and returns a configured instance.\n *\n * @param aiConfig The LaunchDarkly AI configuration\n * @param logger Optional logger for the provider\n * @returns Promise that resolves to a configured provider instance\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static async create(aiConfig: LDAIConfigKind, logger?: LDLogger): Promise<AIProvider> {\n throw new Error('Provider implementations must override the static create method');\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigKind } from '../config/types';\nimport { AIProvider } from './AIProvider';\n\n/**\n * List of supported AI providers.\n */\nexport const SUPPORTED_AI_PROVIDERS = [\n 'openai',\n // Multi-provider packages should be last in the list\n 'langchain',\n 'vercel',\n] as const;\n\n/**\n * Type representing the supported AI providers.\n */\nexport type SupportedAIProvider = (typeof SUPPORTED_AI_PROVIDERS)[number];\n\n/**\n * Factory for creating AIProvider instances based on the provider configuration.\n */\nexport class AIProviderFactory {\n /**\n * Create an AIProvider instance based on the AI configuration.\n * This method attempts to load provider-specific implementations dynamically.\n * Returns undefined if the provider is not supported.\n *\n * @param aiConfig The AI configuration\n * @param logger Optional logger for logging provider initialization\n * @param defaultAiProvider Optional default AI provider to use\n */\n static async create(\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<AIProvider | undefined> {\n const providerName = aiConfig.provider?.name?.toLowerCase();\n // Determine which providers to try based on defaultAiProvider\n const providersToTry = this._getProvidersToTry(defaultAiProvider, providerName);\n\n // Try each provider in order\n // eslint-disable-next-line no-restricted-syntax\n for (const providerType of providersToTry) {\n logger?.debug(\n `Attempting to create AIProvider for: ${aiConfig.provider?.name} with provider type: ${providerType}`,\n );\n // eslint-disable-next-line no-await-in-loop\n const provider = await this._tryCreateProvider(providerType, aiConfig, logger);\n if (provider) {\n logger?.debug(`Successfully created AIProvider for: ${aiConfig.provider?.name}`);\n return provider;\n }\n }\n\n // If no provider was successfully created, log a warning\n logger?.warn(\n `Provider is not supported or failed to initialize: ${aiConfig.provider?.name ?? 'unknown'}`,\n );\n return undefined;\n }\n\n /**\n * Determine which providers to try based on defaultAiProvider and providerName.\n */\n private static _getProvidersToTry(\n defaultAiProvider?: SupportedAIProvider,\n providerName?: string,\n ): SupportedAIProvider[] {\n // If defaultAiProvider is set, only try that specific provider\n if (defaultAiProvider) {\n return [defaultAiProvider];\n }\n\n // If no defaultAiProvider is set, try all providers in order\n const providerSet = new Set<SupportedAIProvider>();\n\n // First try the specific provider if it's supported\n if (providerName && SUPPORTED_AI_PROVIDERS.includes(providerName as SupportedAIProvider)) {\n providerSet.add(providerName as SupportedAIProvider);\n }\n\n // Then try multi-provider packages, but avoid duplicates\n const multiProviderPackages: SupportedAIProvider[] = ['langchain', 'vercel'];\n multiProviderPackages.forEach((provider) => {\n providerSet.add(provider);\n });\n\n return Array.from(providerSet);\n }\n\n /**\n * Try to create a provider of the specified type.\n */\n private static async _tryCreateProvider(\n providerType: SupportedAIProvider,\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n ): Promise<AIProvider | undefined> {\n try {\n let module;\n\n switch (providerType) {\n case 'openai': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-openai' as any);\n const provider = (await module.OpenAIProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'langchain': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-langchain' as any);\n const provider = (await module.LangChainProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'vercel': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-vercel' as any);\n const provider = (await module.VercelProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n default:\n return undefined;\n }\n } catch (error: any) {\n logger?.warn(\n `Unable to create AIProvider. Check that you have installed the correct package. ${error.message}`,\n );\n return undefined;\n }\n }\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createBedrockTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens || 0,\n input: data.inputTokens || 0,\n output: data.outputTokens || 0,\n };\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createOpenAiUsage(data: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n}): LDTokenUsage {\n return {\n total: data.total_tokens ?? 0,\n input: data.prompt_tokens ?? 0,\n output: data.completion_tokens ?? 0,\n };\n}\n","/**\n * Feedback about the generated content.\n */\nexport enum LDFeedbackKind {\n /**\n * The sentiment was positive.\n */\n Positive = 'positive',\n /**\n * The sentiment is negative.\n */\n Negative = 'negative',\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createVercelAISDKTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens ?? 0,\n input: data.inputTokens ?? data.promptTokens ?? 0,\n output: data.outputTokens ?? data.completionTokens ?? 0,\n };\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.16.3'; // x-release-please-version\n","import { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from './api/config';\nimport { LDAIMetricSummary } from './api/config/LDAIConfigTracker';\nimport { EvalScore, JudgeResponse } from './api/judge/types';\nimport {\n createBedrockTokenUsage,\n createOpenAiUsage,\n createVercelAISDKTokenUsage,\n LDAIMetrics,\n LDFeedbackKind,\n LDTokenUsage,\n} from './api/metrics';\nimport { LDClientMin } from './LDClientMin';\nimport { aiSdkName, aiSdkVersion } from './sdkInfo';\n\nexport class LDAIConfigTrackerImpl implements LDAIConfigTracker {\n private _trackedMetrics: LDAIMetricSummary = {};\n\n constructor(\n private _ldClient: LDClientMin,\n private _configKey: string,\n private _variationKey: string,\n private _version: number,\n private _modelName: string,\n private _providerName: string,\n private _context: LDContext,\n ) {}\n\n getTrackData(): {\n variationKey: string;\n configKey: string;\n version: number;\n modelName: string;\n providerName: string;\n aiSdkName: string;\n aiSdkVersion: string;\n } {\n return {\n variationKey: this._variationKey,\n configKey: this._configKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n aiSdkName,\n aiSdkVersion,\n };\n }\n\n trackDuration(duration: number): void {\n this._trackedMetrics.durationMs = duration;\n this._ldClient.track('$ld:ai:duration:total', this._context, this.getTrackData(), duration);\n }\n\n async trackDurationOf<TRes>(func: () => Promise<TRes>): Promise<TRes> {\n const startTime = Date.now();\n try {\n // Be sure to await here so that we can track the duration of the function and also handle errors.\n const result = await func();\n return result;\n } finally {\n const endTime = Date.now();\n const duration = endTime - startTime; // duration in milliseconds\n this.trackDuration(duration);\n }\n }\n\n trackTimeToFirstToken(timeToFirstTokenMs: number) {\n this._trackedMetrics.timeToFirstTokenMs = timeToFirstTokenMs;\n this._ldClient.track(\n '$ld:ai:tokens:ttf',\n this._context,\n this.getTrackData(),\n timeToFirstTokenMs,\n );\n }\n\n trackEvalScores(scores: Record<string, EvalScore>) {\n Object.entries(scores).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(metricKey, this._context, this.getTrackData(), evalScore.score);\n });\n }\n\n trackJudgeResponse(response: JudgeResponse) {\n Object.entries(response.evals).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(\n metricKey,\n this._context,\n { ...this.getTrackData(), judgeConfigKey: response.judgeConfigKey },\n evalScore.score,\n );\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n this._trackedMetrics.feedback = feedback;\n if (feedback.kind === LDFeedbackKind.Positive) {\n this._ldClient.track('$ld:ai:feedback:user:positive', this._context, this.getTrackData(), 1);\n } else if (feedback.kind === LDFeedbackKind.Negative) {\n this._ldClient.track('$ld:ai:feedback:user:negative', this._context, this.getTrackData(), 1);\n }\n }\n\n trackSuccess(): void {\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n this._trackedMetrics.success = false;\n this._ldClient.track('$ld:ai:generation:error', this._context, this.getTrackData(), 1);\n }\n\n async trackMetricsOf<TRes>(\n metricsExtractor: (result: TRes) => LDAIMetrics,\n func: () => Promise<TRes>,\n ): Promise<TRes> {\n let result: TRes;\n\n try {\n result = await this.trackDurationOf(func);\n } catch (err) {\n this.trackError();\n throw err;\n }\n\n // Extract metrics after successful AI call\n const metrics = metricsExtractor(result);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n\n return result;\n }\n\n trackStreamMetricsOf<TStream>(\n streamCreator: () => TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n ): TStream {\n const startTime = Date.now();\n\n try {\n // Create the stream synchronously\n const stream = streamCreator();\n\n // Start background metrics tracking (fire and forget)\n this._trackStreamMetricsInBackground(stream, metricsExtractor, startTime);\n\n // Return stream immediately for consumption\n return stream;\n } catch (error) {\n // Track error if stream creation fails\n this.trackDuration(Date.now() - startTime);\n this.trackError();\n throw error;\n }\n }\n\n private async _trackStreamMetricsInBackground<TStream>(\n stream: TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n startTime: number,\n ): Promise<void> {\n try {\n // Wait for metrics to be available\n const metrics = await metricsExtractor(stream);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n } catch (error) {\n // If metrics extraction fails, track error\n this.trackError();\n } finally {\n // Track duration regardless of success/error\n this.trackDuration(Date.now() - startTime);\n }\n }\n\n async trackOpenAIMetrics<\n TRes extends {\n usage?: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createOpenAiUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackBedrockConverseMetrics<\n TRes extends {\n $metadata: { httpStatusCode?: number };\n metrics?: { latencyMs?: number };\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n },\n >(res: TRes): TRes {\n if (res.$metadata?.httpStatusCode === 200) {\n this.trackSuccess();\n } else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {\n this.trackError();\n }\n if (res.metrics && res.metrics.latencyMs) {\n this.trackDuration(res.metrics.latencyMs);\n }\n if (res.usage) {\n this.trackTokens(createBedrockTokenUsage(res.usage));\n }\n return res;\n }\n\n async trackVercelAISDKGenerateTextMetrics<\n TRes extends {\n usage?: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createVercelAISDKTokenUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackTokens(tokens: LDTokenUsage): void {\n this._trackedMetrics.tokens = tokens;\n const trackData = this.getTrackData();\n if (tokens.total > 0) {\n this._ldClient.track('$ld:ai:tokens:total', this._context, trackData, tokens.total);\n }\n if (tokens.input > 0) {\n this._ldClient.track('$ld:ai:tokens:input', this._context, trackData, tokens.input);\n }\n if (tokens.output > 0) {\n this._ldClient.track('$ld:ai:tokens:output', this._context, trackData, tokens.output);\n }\n }\n\n /**\n * Get a summary of the tracked metrics.\n */\n getSummary(): LDAIMetricSummary {\n return { ...this._trackedMetrics };\n }\n}\n","/**\n * This is the API reference for the LaunchDarkly AI SDK for Server-Side JavaScript.\n *\n * In typical usage, you will call {@link initAi} once at startup time to obtain an instance of\n * {@link LDAIClient}, which provides access to all of the SDK's functionality.\n *\n * @packageDocumentation\n */\n// IMPORTANT: Namespace import required for CJS compatibility. js-server-sdk-common is CommonJS-only;\n// Node.js ESM can't reliably import named exports from CJS. DO NOT change to named imports.\nimport * as common from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIClient } from './api/LDAIClient';\nimport { LDAIClientImpl } from './LDAIClientImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Initialize a new AI client. This client will be used to perform any AI operations.\n * @param ldClient The base LaunchDarkly client.\n * @returns A new AI client.\n */\nexport function initAi(ldClient: LDClientMin): LDAIClient {\n return new LDAIClientImpl(ldClient);\n}\n\nexport type LDLogger = common.LDLogger;\n\nexport * from './api';\n"],"mappings":";AAAA,OAAOA,eAAc;;;ACed,IAAM,cAAN,MAAkB;AAAA,EAGvB,YACqB,UACA,SACA,UACA,SAAgC,CAAC,GACnC,SACjB;AALmB;AACA;AACA;AACA;AACF;AAEjB,SAAK,WAAW,CAAC;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,QAAuC;AAElD,UAAM,cAAyB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AACA,SAAK,SAAS,KAAK,WAAW;AAG9B,UAAM,iBAAiB,KAAK,SAAS,YAAY,CAAC;AAClD,UAAM,cAAc,CAAC,GAAG,gBAAgB,GAAG,KAAK,QAAQ;AAGxD,UAAM,WAAW,MAAM,KAAK,QAAQ;AAAA,MAClC,CAAC,WAAyB,OAAO;AAAA,MACjC,MAAM,KAAK,SAAS,YAAY,WAAW;AAAA,IAC7C;AAEA,QACE,KAAK,SAAS,oBAAoB,UAClC,KAAK,SAAS,mBAAmB,OAAO,SAAS,GACjD;AACA,eAAS,cAAc,KAAK,oBAAoB,KAAK,UAAU,QAAQ;AAAA,IACzE;AAEA,SAAK,SAAS,KAAK,SAAS,OAAO;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,oBACZ,UACA,UAC2C;AAC3C,UAAM,eAAe,KAAK,SAAS,mBAAoB;AAGvD,UAAM,qBAAqB,aAAa,IAAI,OAAO,gBAAgB;AACjE,YAAM,QAAQ,KAAK,OAAO,YAAY,GAAG;AACzC,UAAI,CAAC,OAAO;AACV,aAAK,SAAS;AAAA,UACZ,uCAAuC,YAAY,GAAG;AAAA,UACtD,KAAK,QAAQ,aAAa;AAAA,QAC5B;AACA,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,MAAM,MAAM;AAAA,QAChC;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd;AAEA,UAAI,iBAAiB,cAAc,SAAS;AAC1C,aAAK,QAAQ,mBAAmB,aAAa;AAAA,MAC/C;AAEA,aAAO;AAAA,IACT,CAAC;AAGD,UAAM,UAAU,MAAM,QAAQ,WAAW,kBAAkB;AAE3D,WAAO,QAAQ,IAAI,CAAC,WAAY,OAAO,WAAW,cAAc,OAAO,QAAQ,MAAU;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkC;AAChC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,eAAe,UAA6B;AAC1C,SAAK,SAAS,KAAK,GAAG,QAAQ;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YAAY,wBAAiC,OAAoB;AAC/D,QAAI,uBAAuB;AACzB,YAAM,iBAAiB,KAAK,SAAS,YAAY,CAAC;AAClD,aAAO,CAAC,GAAG,gBAAgB,GAAG,KAAK,QAAQ;AAAA,IAC7C;AACA,WAAO,CAAC,GAAG,KAAK,QAAQ;AAAA,EAC1B;AACF;;;ACzHO,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3B,OAAO,YAAY,QAA+B,MAA2C;AAC3F,UAAM,YAAiC;AAAA,MACrC,SAAS;AAAA,QACP,cAAc;AAAA;AAAA,QACd,SAAS,OAAO,WAAW;AAAA,QAC3B;AAAA,MACF;AAAA,MACA,OAAO,OAAO;AAAA,IAChB;AAEA,QAAI,cAAc,UAAU,OAAO,aAAa,QAAW;AACzD,gBAAU,WAAW,OAAO;AAAA,IAC9B;AACA,QAAI,OAAO,aAAa,QAAW;AACjC,gBAAU,WAAW,OAAO;AAAA,IAC9B;AACA,QAAI,kBAAkB,UAAU,OAAO,iBAAiB,QAAW;AACjE,gBAAU,eAAe,OAAO;AAAA,IAClC;AACA,QAAI,yBAAyB,UAAU,OAAO,wBAAwB,QAAW;AAC/E,gBAAU,sBAAsB,OAAO;AAAA,IACzC;AACA,QAAI,0BAA0B,UAAU,OAAO,yBAAyB,QAAW;AACjF,gBAAU,uBAAuB,OAAO;AAAA,IAC1C;AACA,QAAI,wBAAwB,UAAU,OAAO,uBAAuB,QAAW;AAC7E,gBAAU,qBAAqB,OAAO;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,cACL,KACA,WACA,SACgB;AAGhB,UAAM,gBAAgB,UAAU,SAAS;AAEzC,YAAQ,eAAe;AAAA,MACrB,KAAK;AACH,eAAO,KAAK,cAAc,KAAK,WAAW,OAAO;AAAA,MACnD,KAAK;AACH,eAAO,KAAK,cAAc,KAAK,WAAW,OAAO;AAAA,MACnD,KAAK;AAAA,MACL;AACE,eAAO,KAAK,mBAAmB,KAAK,WAAW,OAAO;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,qBAAqB,KAAa,MAAsC;AAC7E,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AAAA,UACL;AAAA,UACA,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,KAAK;AACH,eAAO;AAAA,UACL;AAAA,UACA,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,KAAK;AAAA,MACL;AAEE,eAAO;AAAA,UACL;AAAA,UACA,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAe,cAAc,KAAa,WAAgC;AACxE,WAAO;AAAA,MACL;AAAA;AAAA,MAEA,SAAS,UAAU,SAAS,WAAW;AAAA,MACvC,OAAO,UAAU;AAAA,MACjB,UAAU,UAAU;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,mBACL,KACA,WACA,SACsB;AACtB,WAAO;AAAA,MACL,GAAG,KAAK,cAAc,KAAK,SAAS;AAAA,MACpC;AAAA,MACA,UAAU,UAAU;AAAA,MACpB,oBAAoB,UAAU;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,cACL,KACA,WACA,SACiB;AACjB,WAAO;AAAA,MACL,GAAG,KAAK,cAAc,KAAK,SAAS;AAAA,MACpC;AAAA,MACA,cAAc,UAAU;AAAA,MACxB,oBAAoB,UAAU;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,cACL,KACA,WACA,SACiB;AAEjB,QAAI;AACJ,QAAI,UAAU,uBAAuB,UAAU,oBAAoB,KAAK,EAAE,SAAS,GAAG;AACpF,4BAAsB,UAAU,oBAAoB,KAAK;AAAA,IAC3D,WAAW,UAAU,wBAAwB,UAAU,qBAAqB,SAAS,GAAG;AACtF,YAAM,WAAW,UAAU,qBAAqB;AAAA,QAC9C,CAAC,cAAc,aAAa,UAAU,KAAK,EAAE,SAAS;AAAA,MACxD;AACA,4BAAsB,WAAW,SAAS,KAAK,IAAI;AAAA,IACrD;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,cAAc,KAAK,SAAS;AAAA,MACpC;AAAA,MACA,UAAU,UAAU;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;;;ACjOA,OAAO,cAAc;;;ACIrB,IAAM,0BAAN,MAA8B;AAAA,EAC5B,OAAO,MAAM,qBAAuD;AAClE,QAAI,CAAC,qBAAqB;AACxB,aAAO,CAAC;AAAA,IACV;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,QACV,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa,4CAA4C,mBAAmB;AAAA,UAC5E,YAAY;AAAA,YACV,CAAC,mBAAmB,GAAG,KAAK,gBAAgB,mBAAmB;AAAA,UACjE;AAAA,UACA,UAAU,CAAC,mBAAmB;AAAA,UAC9B,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,UAAU,CAAC,aAAa;AAAA,MACxB,sBAAsB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,OAAe,gBAAgB,KAAa;AAC1C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,UACT,aAAa,iCAAiC,GAAG;AAAA,QACnD;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa,kCAAkC,GAAG;AAAA,QACpD;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS,WAAW;AAAA,MAC/B,sBAAsB;AAAA,IACxB;AAAA,EACF;AACF;;;AD7BO,IAAM,QAAN,MAAY;AAAA,EAIjB,YACmB,WACA,kBACA,aACjB,QACA;AAJiB;AACA;AACA;AAGjB,SAAK,UAAU;AACf,UAAM,sBAAsB,KAAK,wBAAwB;AACzD,SAAK,+BAA+B,wBAAwB,MAAM,mBAAmB;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,0BAA8C;AACpD,QACE,KAAK,UAAU,uBACf,KAAK,UAAU,oBAAoB,KAAK,EAAE,SAAS,GACnD;AACA,aAAO,KAAK,UAAU,oBAAoB,KAAK;AAAA,IACjD;AACA,QAAI,KAAK,UAAU,wBAAwB,KAAK,UAAU,qBAAqB,SAAS,GAAG;AACzF,YAAM,WAAW,KAAK,UAAU,qBAAqB;AAAA,QACnD,CAAC,QAAQ,OAAO,IAAI,KAAK,EAAE,SAAS;AAAA,MACtC;AACA,aAAO,WAAW,SAAS,KAAK,IAAI;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SACJ,OACA,QACA,eAAuB,GACa;AACpC,QAAI;AACF,YAAM,sBAAsB,KAAK,wBAAwB;AACzD,UAAI,CAAC,qBAAqB;AACxB,aAAK,SAAS;AAAA,UACZ;AAAA,UACA,KAAK,iBAAiB,aAAa;AAAA,QACrC;AACA,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,KAAK,UAAU,UAAU;AAC5B,aAAK,SAAS;AAAA,UACZ;AAAA,UACA,KAAK,iBAAiB,aAAa;AAAA,QACrC;AACA,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,OAAO,IAAI,cAAc;AAChC,aAAK,SAAS,MAAM,kDAAkD,YAAY,EAAE;AACpF,eAAO;AAAA,MACT;AAEA,YAAM,WAAW,KAAK,6BAA6B,OAAO,MAAM;AAEhE,YAAM,WAAW,MAAM,KAAK,iBAAiB;AAAA,QAC3C,CAAC,WAA+B,OAAO;AAAA,QACvC,MAAM,KAAK,YAAY,sBAAsB,UAAU,KAAK,4BAA4B;AAAA,MAC1F;AAEA,UAAI,EAAE,QAAQ,IAAI,SAAS;AAE3B,YAAM,QAAQ,KAAK,yBAAyB,SAAS,MAAM,mBAAmB;AAE9E,UAAI,CAAC,MAAM,mBAAmB,GAAG;AAC/B,aAAK,SAAS;AAAA,UACZ;AAAA,UACA,KAAK,iBAAiB,aAAa;AAAA,QACrC;AACA,kBAAU;AAAA,MACZ;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,gBAAgB,KAAK,UAAU;AAAA,MACjC;AAAA,IACF,SAAS,OAAO;AACd,WAAK,SAAS,MAAM,4BAA4B,KAAK;AACrD,aAAO;AAAA,QACL,OAAO,CAAC;AAAA,QACR,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAChD,gBAAgB,KAAK,UAAU;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBACJ,UACA,UACA,gBAAwB,GACY;AACpC,UAAM,QAAQ,SAAS,WAAW,IAAI,KAAK,SAAS,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE,KAAK,MAAM;AACzF,UAAM,SAAS,SAAS,QAAQ;AAEhC,WAAO,KAAK,SAAS,OAAO,QAAQ,aAAa;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,cAA+B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,cAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKQ,6BAA6B,OAAe,QAA6B;AAC/E,UAAM,WAAwB,KAAK,UAAU,SAAU,IAAI,CAAC,SAAS;AAAA,MACnE,GAAG;AAAA,MACH,SAAS,KAAK,oBAAoB,IAAI,SAAS;AAAA,QAC7C,iBAAiB;AAAA,QACjB,sBAAsB;AAAA,MACxB,CAAC;AAAA,IACH,EAAE;AAEF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,SAAiB,WAA2C;AACtF,WAAO,SAAS,OAAO,SAAS,WAAW,QAAW,EAAE,QAAQ,CAAC,SAAc,KAAK,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA,EAKQ,yBACN,MACA,qBAC2B;AAC3B,UAAM,cAAc,KAAK;AACzB,UAAM,UAAqC,CAAC;AAE5C,QAAI,CAAC,KAAK,eAAe,OAAO,KAAK,gBAAgB,UAAU;AAC7D,WAAK,SAAS,KAAK,yDAAyD;AAC5E,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,YAAY,mBAAmB;AAElD,QAAI,CAAC,cAAc,OAAO,eAAe,UAAU;AACjD,WAAK,SAAS;AAAA,QACZ,sCAAsC,mBAAmB;AAAA,QACzD,KAAK,iBAAiB,aAAa;AAAA,MACrC;AACA,aAAO;AAAA,IACT;AAEA,UAAM,WAAW;AAEjB,QAAI,OAAO,SAAS,UAAU,YAAY,SAAS,QAAQ,KAAK,SAAS,QAAQ,GAAG;AAClF,WAAK,SAAS;AAAA,QACZ,+BAA+B,mBAAmB,KAAK,SAAS,KAAK;AAAA,QACrE,KAAK,iBAAiB,aAAa;AAAA,MACrC;AACA,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,SAAS,cAAc,UAAU;AAC1C,WAAK,SAAS;AAAA,QACZ,mCAAmC,mBAAmB,KAAK,SAAS,SAAS;AAAA,QAC7E,KAAK,iBAAiB,aAAa;AAAA,MACrC;AACA,aAAO;AAAA,IACT;AAEA,YAAQ,mBAAmB,IAAI;AAAA,MAC7B,OAAO,SAAS;AAAA,MAChB,WAAW,SAAS;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AACF;;;AE/NO,IAAe,aAAf,MAA0B;AAAA,EAG/B,YAAY,QAAmB;AAC7B,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YAAY,WAA+C;AAC/D,SAAK,QAAQ,KAAK,8CAA8C;AAChE,WAAO;AAAA,MACL,SAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA,SAAS;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,sBACJ,WACA,oBAC6B;AAC7B,SAAK,QAAQ,KAAK,wDAAwD;AAC1E,WAAO;AAAA,MACL,MAAM,CAAC;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,aAAa,OAAO,UAA0B,QAAwC;AACpF,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AACF;;;ACrFO,IAAM,yBAAyB;AAAA,EACpC;AAAA;AAAA,EAEA;AAAA,EACA;AACF;AAUO,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7B,aAAa,OACX,UACA,QACA,mBACiC;AACjC,UAAM,eAAe,SAAS,UAAU,MAAM,YAAY;AAE1D,UAAM,iBAAiB,KAAK,mBAAmB,mBAAmB,YAAY;AAI9E,eAAW,gBAAgB,gBAAgB;AACzC,cAAQ;AAAA,QACN,wCAAwC,SAAS,UAAU,IAAI,wBAAwB,YAAY;AAAA,MACrG;AAEA,YAAM,WAAW,MAAM,KAAK,mBAAmB,cAAc,UAAU,MAAM;AAC7E,UAAI,UAAU;AACZ,gBAAQ,MAAM,wCAAwC,SAAS,UAAU,IAAI,EAAE;AAC/E,eAAO;AAAA,MACT;AAAA,IACF;AAGA,YAAQ;AAAA,MACN,sDAAsD,SAAS,UAAU,QAAQ,SAAS;AAAA,IAC5F;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,mBACb,mBACA,cACuB;AAEvB,QAAI,mBAAmB;AACrB,aAAO,CAAC,iBAAiB;AAAA,IAC3B;AAGA,UAAM,cAAc,oBAAI,IAAyB;AAGjD,QAAI,gBAAgB,uBAAuB,SAAS,YAAmC,GAAG;AACxF,kBAAY,IAAI,YAAmC;AAAA,IACrD;AAGA,UAAM,wBAA+C,CAAC,aAAa,QAAQ;AAC3E,0BAAsB,QAAQ,CAAC,aAAa;AAC1C,kBAAY,IAAI,QAAQ;AAAA,IAC1B,CAAC;AAED,WAAO,MAAM,KAAK,WAAW;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,mBACnB,cACA,UACA,QACiC;AACjC,QAAI;AACF,UAAI;AAEJ,cAAQ,cAAc;AAAA,QACpB,KAAK,UAAU;AAEb,mBAAS,MAAM,OAAO,oCAA2C;AACjE,gBAAM,WAAY,MAAM,OAAO,eAAe,OAAO,UAAU,MAAM;AACrE,iBAAO;AAAA,QACT;AAAA,QACA,KAAK,aAAa;AAEhB,mBAAS,MAAM,OAAO,uCAA8C;AACpE,gBAAM,WAAY,MAAM,OAAO,kBAAkB,OAAO,UAAU,MAAM;AACxE,iBAAO;AAAA,QACT;AAAA,QACA,KAAK,UAAU;AAEb,mBAAS,MAAM,OAAO,oCAA2C;AACjE,gBAAM,WAAY,MAAM,OAAO,eAAe,OAAO,UAAU,MAAM;AACrE,iBAAO;AAAA,QACT;AAAA,QACA;AACE,iBAAO;AAAA,MACX;AAAA,IACF,SAAS,OAAY;AACnB,cAAQ;AAAA,QACN,mFAAmF,MAAM,OAAO;AAAA,MAClG;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AClIO,SAAS,wBAAwB,MAIvB;AACf,SAAO;AAAA,IACL,OAAO,KAAK,eAAe;AAAA,IAC3B,OAAO,KAAK,eAAe;AAAA,IAC3B,QAAQ,KAAK,gBAAgB;AAAA,EAC/B;AACF;;;ACVO,SAAS,kBAAkB,MAIjB;AACf,SAAO;AAAA,IACL,OAAO,KAAK,gBAAgB;AAAA,IAC5B,OAAO,KAAK,iBAAiB;AAAA,IAC7B,QAAQ,KAAK,qBAAqB;AAAA,EACpC;AACF;;;ACTO,IAAK,iBAAL,kBAAKC,oBAAL;AAIL,EAAAA,gBAAA,cAAW;AAIX,EAAAA,gBAAA,cAAW;AARD,SAAAA;AAAA,GAAA;;;ACDL,SAAS,4BAA4B,MAM3B;AACf,SAAO;AAAA,IACL,OAAO,KAAK,eAAe;AAAA,IAC3B,OAAO,KAAK,eAAe,KAAK,gBAAgB;AAAA,IAChD,QAAQ,KAAK,gBAAgB,KAAK,oBAAoB;AAAA,EACxD;AACF;;;ACdO,IAAM,YAAY;AAClB,IAAM,eAAe;;;ACerB,IAAM,wBAAN,MAAyD;AAAA,EAG9D,YACU,WACA,YACA,eACA,UACA,YACA,eACA,UACR;AAPQ;AACA;AACA;AACA;AACA;AACA;AACA;AATV,SAAQ,kBAAqC,CAAC;AAAA,EAU3C;AAAA,EAEH,eAQE;AACA,WAAO;AAAA,MACL,cAAc,KAAK;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,UAAwB;AACpC,SAAK,gBAAgB,aAAa;AAClC,SAAK,UAAU,MAAM,yBAAyB,KAAK,UAAU,KAAK,aAAa,GAAG,QAAQ;AAAA,EAC5F;AAAA,EAEA,MAAM,gBAAsB,MAA0C;AACpE,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK;AAC1B,aAAO;AAAA,IACT,UAAE;AACA,YAAM,UAAU,KAAK,IAAI;AACzB,YAAM,WAAW,UAAU;AAC3B,WAAK,cAAc,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,sBAAsB,oBAA4B;AAChD,SAAK,gBAAgB,qBAAqB;AAC1C,SAAK,UAAU;AAAA,MACb;AAAA,MACA,KAAK;AAAA,MACL,KAAK,aAAa;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBAAgB,QAAmC;AACjD,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,WAAW,SAAS,MAAM;AACzD,WAAK,UAAU,MAAM,WAAW,KAAK,UAAU,KAAK,aAAa,GAAG,UAAU,KAAK;AAAA,IACrF,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,UAAyB;AAC1C,WAAO,QAAQ,SAAS,KAAK,EAAE,QAAQ,CAAC,CAAC,WAAW,SAAS,MAAM;AACjE,WAAK,UAAU;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,EAAE,GAAG,KAAK,aAAa,GAAG,gBAAgB,SAAS,eAAe;AAAA,QAClE,UAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,UAA0C;AACtD,SAAK,gBAAgB,WAAW;AAChC,QAAI,SAAS,oCAAkC;AAC7C,WAAK,UAAU,MAAM,iCAAiC,KAAK,UAAU,KAAK,aAAa,GAAG,CAAC;AAAA,IAC7F,WAAW,SAAS,oCAAkC;AACpD,WAAK,UAAU,MAAM,iCAAiC,KAAK,UAAU,KAAK,aAAa,GAAG,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA,EAEA,eAAqB;AACnB,SAAK,gBAAgB,UAAU;AAC/B,SAAK,UAAU,MAAM,6BAA6B,KAAK,UAAU,KAAK,aAAa,GAAG,CAAC;AAAA,EACzF;AAAA,EAEA,aAAmB;AACjB,SAAK,gBAAgB,UAAU;AAC/B,SAAK,UAAU,MAAM,2BAA2B,KAAK,UAAU,KAAK,aAAa,GAAG,CAAC;AAAA,EACvF;AAAA,EAEA,MAAM,eACJ,kBACA,MACe;AACf,QAAI;AAEJ,QAAI;AACF,eAAS,MAAM,KAAK,gBAAgB,IAAI;AAAA,IAC1C,SAAS,KAAK;AACZ,WAAK,WAAW;AAChB,YAAM;AAAA,IACR;AAGA,UAAM,UAAU,iBAAiB,MAAM;AAGvC,QAAI,QAAQ,SAAS;AACnB,WAAK,aAAa;AAAA,IACpB,OAAO;AACL,WAAK,WAAW;AAAA,IAClB;AAGA,QAAI,QAAQ,OAAO;AACjB,WAAK,YAAY,QAAQ,KAAK;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,qBACE,eACA,kBACS;AACT,UAAM,YAAY,KAAK,IAAI;AAE3B,QAAI;AAEF,YAAM,SAAS,cAAc;AAG7B,WAAK,gCAAgC,QAAQ,kBAAkB,SAAS;AAGxE,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,WAAK,cAAc,KAAK,IAAI,IAAI,SAAS;AACzC,WAAK,WAAW;AAChB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,gCACZ,QACA,kBACA,WACe;AACf,QAAI;AAEF,YAAM,UAAU,MAAM,iBAAiB,MAAM;AAG7C,UAAI,QAAQ,SAAS;AACnB,aAAK,aAAa;AAAA,MACpB,OAAO;AACL,aAAK,WAAW;AAAA,MAClB;AAGA,UAAI,QAAQ,OAAO;AACjB,aAAK,YAAY,QAAQ,KAAK;AAAA,MAChC;AAAA,IACF,SAAS,OAAO;AAEd,WAAK,WAAW;AAAA,IAClB,UAAE;AAEA,WAAK,cAAc,KAAK,IAAI,IAAI,SAAS;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,mBAQJ,MAA0C;AAC1C,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,gBAAgB,IAAI;AAC9C,WAAK,aAAa;AAClB,UAAI,OAAO,OAAO;AAChB,aAAK,YAAY,kBAAkB,OAAO,KAAK,CAAC;AAAA,MAClD;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,WAAK,WAAW;AAChB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,4BAUE,KAAiB;AACjB,QAAI,IAAI,WAAW,mBAAmB,KAAK;AACzC,WAAK,aAAa;AAAA,IACpB,WAAW,IAAI,WAAW,kBAAkB,IAAI,UAAU,kBAAkB,KAAK;AAC/E,WAAK,WAAW;AAAA,IAClB;AACA,QAAI,IAAI,WAAW,IAAI,QAAQ,WAAW;AACxC,WAAK,cAAc,IAAI,QAAQ,SAAS;AAAA,IAC1C;AACA,QAAI,IAAI,OAAO;AACb,WAAK,YAAY,wBAAwB,IAAI,KAAK,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oCAUJ,MAA0C;AAC1C,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,gBAAgB,IAAI;AAC9C,WAAK,aAAa;AAClB,UAAI,OAAO,OAAO;AAChB,aAAK,YAAY,4BAA4B,OAAO,KAAK,CAAC;AAAA,MAC5D;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,WAAK,WAAW;AAChB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,YAAY,QAA4B;AACtC,SAAK,gBAAgB,SAAS;AAC9B,UAAM,YAAY,KAAK,aAAa;AACpC,QAAI,OAAO,QAAQ,GAAG;AACpB,WAAK,UAAU,MAAM,uBAAuB,KAAK,UAAU,WAAW,OAAO,KAAK;AAAA,IACpF;AACA,QAAI,OAAO,QAAQ,GAAG;AACpB,WAAK,UAAU,MAAM,uBAAuB,KAAK,UAAU,WAAW,OAAO,KAAK;AAAA,IACpF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,WAAK,UAAU,MAAM,wBAAwB,KAAK,UAAU,WAAW,OAAO,MAAM;AAAA,IACtF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAgC;AAC9B,WAAO,EAAE,GAAG,KAAK,gBAAgB;AAAA,EACnC;AACF;;;AZlQA,IAAM,sBAAsB;AAC5B,IAAM,2BAA2B;AACjC,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAEtB,IAAM,iBAAN,MAA2C;AAAA,EAGhD,YAAoB,WAAwB;AAAxB;AAClB,SAAK,UAAU,UAAU;AAAA,EAC3B;AAAA,EAEQ,qBAAqB,UAAkB,WAA4C;AACzF,WAAOC,UAAS,OAAO,UAAU,WAAW,QAAW,EAAE,QAAQ,CAAC,SAAc,KAAK,CAAC;AAAA,EACxF;AAAA,EAEA,MAAc,UACZ,KACA,SACA,cACA,MACA,WACyB;AACzB,UAAM,cAAc,gBAAgB,YAAY,cAAc,IAAI;AAElE,UAAM,QAA6B,MAAM,KAAK,UAAU,UAAU,KAAK,SAAS,WAAW;AAI3F,UAAM,WAAW,MAAM,SAAS,QAAQ;AACxC,QAAI,aAAa,MAAM;AACrB,WAAK,SAAS;AAAA,QACZ,+BAA+B,GAAG,cAAc,IAAI,SAAS,QAAQ;AAAA,MACvE;AACA,aAAO,gBAAgB,qBAAqB,KAAK,IAAI;AAAA,IACvD;AAEA,UAAM,UAAU,IAAI;AAAA,MAClB,KAAK;AAAA,MACL;AAAA;AAAA,MAEA,MAAM,SAAS,gBAAgB;AAAA;AAAA,MAE/B,MAAM,SAAS,WAAW;AAAA,MAC1B,MAAM,OAAO,QAAQ;AAAA,MACrB,MAAM,UAAU,QAAQ;AAAA,MACxB;AAAA,IACF;AAEA,UAAM,SAAS,gBAAgB,cAAc,KAAK,OAAO,OAAO;AAGhE,WAAO,KAAK,oBAAoB,QAAQ,SAAS,SAAS;AAAA,EAC5D;AAAA,EAEQ,oBACN,QACA,SACA,WACgB;AAChB,UAAM,eAAe,EAAE,GAAG,WAAW,OAAO,QAAQ;AAEpD,QAAI,cAAc,UAAU,OAAO,UAAU;AAC3C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU,OAAO,SAAS,IAAI,CAAC,WAAsB;AAAA,UACnD,GAAG;AAAA,UACH,SAAS,KAAK,qBAAqB,MAAM,SAAS,YAAY;AAAA,QAChE,EAAE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,kBAAkB,UAAU,OAAO,cAAc;AACnD,aAAO;AAAA,QACL,GAAG;AAAA,QACH,cAAc,KAAK,qBAAqB,OAAO,cAAc,YAAY;AAAA,MAC3E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kBACZ,cACA,SACA,WACA,mBACgC;AAChC,UAAM,SAAgC,CAAC;AAEvC,UAAM,gBAAgB,aAAa,IAAI,OAAO,gBAAgB;AAC5D,YAAM,QAAQ,MAAM,KAAK;AAAA,QACvB,YAAY;AAAA,QACZ;AAAA,QACA,EAAE,SAAS,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,MACF;AACA,aAAO,QAAQ,EAAE,KAAK,YAAY,KAAK,MAAM,IAAI;AAAA,IACnD,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,IAAI,aAAa;AAC/C,YAAQ,QAAQ,CAAC,WAAW;AAC1B,UAAI,QAAQ;AACV,eAAO,OAAO,GAAG,IAAI,OAAO;AAAA,MAC9B;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBACJ,KACA,SACA,cACA,WAC+B;AAC/B,SAAK,UAAU,MAAM,qBAAqB,SAAS,KAAK,CAAC;AAEzD,UAAM,SAAS,MAAM,KAAK,UAAU,KAAK,SAAS,cAAc,cAAc,SAAS;AACvF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,KACA,SACA,cACA,WAC+B;AAC/B,WAAO,KAAK,iBAAiB,KAAK,SAAS,cAAc,SAAS;AAAA,EACpE;AAAA,EAEA,MAAM,YACJ,KACA,SACA,cACA,WAC0B;AAC1B,SAAK,UAAU,MAAM,oBAAoB,SAAS,KAAK,CAAC;AAExD,UAAM,SAAS,MAAM,KAAK,UAAU,KAAK,SAAS,cAAc,SAAS,SAAS;AAClF,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YACJ,KACA,SACA,cACA,WAC0B;AAC1B,SAAK,UAAU,MAAM,oBAAoB,SAAS,KAAK,CAAC;AAExD,UAAM,SAAS,MAAM,KAAK,UAAU,KAAK,SAAS,cAAc,SAAS,SAAS;AAClF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MACJ,KACA,SACA,cACA,WAC0B;AAC1B,WAAO,KAAK,YAAY,KAAK,SAAS,cAAc,SAAS;AAAA,EAC/D;AAAA,EAEA,MAAM,aACJ,cACA,SACoD;AACpD,SAAK,UAAU,MAAM,sBAAsB,SAAS,aAAa,QAAQ,aAAa,MAAM;AAE5F,UAAM,SAAS,CAAC;AAEhB,UAAM,QAAQ;AAAA,MACZ,aAAa,IAAI,OAAO,WAAW;AACjC,cAAM,QAAQ,MAAM,KAAK;AAAA,UACvB,OAAO;AAAA,UACP;AAAA,UACA,OAAO;AAAA,UACP;AAAA,UACA,OAAO;AAAA,QACT;AACA,eAAO,OAAO,GAAuB,IAAI;AAAA,MAC3C,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,cACA,SACoD;AACpD,WAAO,KAAK,aAAa,cAAc,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,WACJ,KACA,SACA,cACA,WACA,mBACkC;AAClC,SAAK,UAAU,MAAM,0BAA0B,SAAS,KAAK,CAAC;AAE9D,UAAM,SAAS,MAAM,KAAK,iBAAiB,KAAK,SAAS,cAAc,SAAS;AAEhF,QAAI,CAAC,OAAO,WAAW,CAAC,OAAO,SAAS;AACtC,WAAK,SAAS,KAAK,mCAAmC,GAAG,EAAE;AAC3D,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,MAAM,kBAAkB,OAAO,QAAQ,KAAK,SAAS,iBAAiB;AACvF,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,OAAO,oBAAoB,UAAU,CAAC;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO,IAAI,YAAY,QAAQ,OAAO,SAAS,UAAU,QAAQ,KAAK,OAAO;AAAA,EAC/E;AAAA,EAEA,MAAM,YACJ,KACA,SACA,cACA,WACA,mBAC4B;AAC5B,SAAK,UAAU,MAAM,oBAAoB,SAAS,KAAK,CAAC;AAExD,QAAI;AACF,UAAI,WAAW,oBAAoB,QAAW;AAC5C,aAAK,SAAS;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AACA,UAAI,WAAW,yBAAyB,QAAW;AACjD,aAAK,SAAS;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAGA,YAAM,oBAAoB;AAAA,QACxB,GAAG;AAAA,QACH,iBAAiB;AAAA,QACjB,sBAAsB;AAAA,MACxB;AAEA,YAAM,cAAc,MAAM,KAAK,YAAY,KAAK,SAAS,cAAc,iBAAiB;AAExF,UAAI,CAAC,YAAY,WAAW,CAAC,YAAY,SAAS;AAChD,aAAK,SAAS,KAAK,oCAAoC,GAAG,EAAE;AAC5D,eAAO;AAAA,MACT;AAEA,YAAM,WAAW,MAAM,kBAAkB,OAAO,aAAa,KAAK,SAAS,iBAAiB;AAC5F,UAAI,CAAC,UAAU;AACb,eAAO;AAAA,MACT;AAEA,aAAO,IAAI,MAAM,aAAa,YAAY,SAAS,UAAU,KAAK,OAAO;AAAA,IAC3E,SAAS,OAAO;AACd,WAAK,SAAS,MAAM,8BAA8B,GAAG,KAAK,KAAK;AAC/D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,KACA,SACA,cACA,WACA,mBACkC;AAClC,WAAO,KAAK,WAAW,KAAK,SAAS,cAAc,WAAW,iBAAiB;AAAA,EACjF;AACF;;;AajTO,SAAS,OAAO,UAAmC;AACxD,SAAO,IAAI,eAAe,QAAQ;AACpC;","names":["Mustache","LDFeedbackKind","Mustache"]}
1
+ {"version":3,"sources":["../src/LDAIClientImpl.ts","../src/api/chat/TrackedChat.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/judge/Judge.ts","../src/api/judge/EvaluationSchemaBuilder.ts","../src/api/providers/AIProvider.ts","../src/api/providers/AIProviderFactory.ts","../src/api/metrics/BedrockTokenUsage.ts","../src/api/metrics/OpenAiUsage.ts","../src/api/metrics/LDFeedbackKind.ts","../src/api/metrics/VercelAISDKTokenUsage.ts","../src/LDAIConfigTrackerImpl.ts","../src/sdkInfo.ts","../src/index.ts"],"sourcesContent":["import Mustache from 'mustache';\n\nimport { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { TrackedChat } from './api/chat';\nimport {\n LDAIAgentConfig,\n LDAIAgentConfigDefault,\n LDAIAgentRequestConfig,\n LDAICompletionConfig,\n LDAICompletionConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { Judge } from './api/judge/Judge';\nimport { LDAIClient } from './api/LDAIClient';\nimport { AIProviderFactory, SupportedAIProvider } from './api/providers';\nimport { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl';\nimport { LDClientMin } from './LDClientMin';\nimport { aiSdkLanguage, aiSdkName, aiSdkVersion } from './sdkInfo';\n\n/**\n * Tracking event keys for AI SDK usage metrics.\n */\nconst TRACK_SDK_INFO = '$ld:ai:sdk:info';\nconst TRACK_USAGE_COMPLETION_CONFIG = '$ld:ai:usage:completion-config';\nconst TRACK_USAGE_CREATE_CHAT = '$ld:ai:usage:create-chat';\nconst TRACK_USAGE_JUDGE_CONFIG = '$ld:ai:usage:judge-config';\nconst TRACK_USAGE_CREATE_JUDGE = '$ld:ai:usage:create-judge';\nconst TRACK_USAGE_AGENT_CONFIG = '$ld:ai:usage:agent-config';\nconst TRACK_USAGE_AGENT_CONFIGS = '$ld:ai:usage:agent-configs';\n\nconst INIT_TRACK_CONTEXT: LDContext = {\n kind: 'ld_ai',\n key: 'ld-internal-tracking',\n anonymous: true,\n};\n\nexport class LDAIClientImpl implements LDAIClient {\n private _logger?: LDLogger;\n\n constructor(private _ldClient: LDClientMin) {\n this._logger = _ldClient.logger;\n this._ldClient.track(\n TRACK_SDK_INFO,\n INIT_TRACK_CONTEXT,\n {\n aiSdkName,\n aiSdkVersion,\n aiSdkLanguage,\n },\n 1,\n );\n }\n\n private _interpolateTemplate(template: string, variables: Record<string, unknown>): string {\n return Mustache.render(template, variables, undefined, { escape: (item: any) => item });\n }\n\n private async _evaluate(\n key: string,\n context: LDContext,\n defaultValue: LDAIConfigDefaultKind,\n mode: LDAIConfigMode,\n variables?: Record<string, unknown>,\n ): Promise<LDAIConfigKind> {\n const ldFlagValue = LDAIConfigUtils.toFlagValue(defaultValue, mode);\n\n const value: LDAIConfigFlagValue = await this._ldClient.variation(key, context, ldFlagValue);\n\n // Validate mode match\n // eslint-disable-next-line no-underscore-dangle\n const flagMode = value._ldMeta?.mode ?? 'completion';\n if (flagMode !== mode) {\n this._logger?.warn(\n `AI Config mode mismatch for ${key}: expected ${mode}, got ${flagMode}. Returning disabled config.`,\n );\n return LDAIConfigUtils.createDisabledConfig(key, mode);\n }\n\n const tracker = new LDAIConfigTrackerImpl(\n this._ldClient,\n key,\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.variationKey ?? '',\n // eslint-disable-next-line no-underscore-dangle\n value._ldMeta?.version ?? 1,\n value.model?.name ?? '',\n value.provider?.name ?? '',\n context,\n );\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, tracker);\n\n // Apply variable interpolation (always needed for ldctx)\n return this._applyInterpolation(config, context, variables);\n }\n\n private _applyInterpolation(\n config: LDAIConfigKind,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): LDAIConfigKind {\n const allVariables = { ...variables, ldctx: context };\n\n if ('messages' in config && config.messages) {\n return {\n ...config,\n messages: config.messages.map((entry: LDMessage) => ({\n ...entry,\n content: this._interpolateTemplate(entry.content, allVariables),\n })),\n };\n }\n\n if ('instructions' in config && config.instructions) {\n return {\n ...config,\n instructions: this._interpolateTemplate(config.instructions, allVariables),\n };\n }\n\n return config;\n }\n\n private async _initializeJudges(\n judgeConfigs: LDJudge[],\n context: LDContext,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Record<string, Judge>> {\n const judges: Record<string, Judge> = {};\n\n const judgePromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = await this.createJudge(\n judgeConfig.key,\n context,\n { enabled: false },\n variables,\n defaultAiProvider,\n );\n return judge ? { key: judgeConfig.key, judge } : null;\n });\n\n const results = await Promise.all(judgePromises);\n results.forEach((result) => {\n if (result) {\n judges[result.key] = result.judge;\n }\n });\n\n return judges;\n }\n\n private async _completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n const config = await this._evaluate(key, context, defaultValue, 'completion', variables);\n return config as LDAICompletionConfig;\n }\n\n async completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1);\n\n return this._completionConfig(key, context, defaultValue, variables);\n }\n\n /**\n * @deprecated Use `completionConfig` instead. This method will be removed in a future version.\n */\n async config(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAICompletionConfig> {\n return this.completionConfig(key, context, defaultValue, variables);\n }\n\n private async _judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n const config = await this._evaluate(key, context, defaultValue, 'judge', variables);\n return config as LDAIJudgeConfig;\n }\n\n async judgeConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIJudgeConfig> {\n this._ldClient.track(TRACK_USAGE_JUDGE_CONFIG, context, key, 1);\n\n return this._judgeConfig(key, context, defaultValue, variables);\n }\n\n async agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1);\n\n const config = await this._evaluate(key, context, defaultValue, 'agent', variables);\n return config as LDAIAgentConfig;\n }\n\n /**\n * @deprecated Use `agentConfig` instead. This method will be removed in a future version.\n */\n async agent(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n ): Promise<LDAIAgentConfig> {\n return this.agentConfig(key, context, defaultValue, variables);\n }\n\n async agentConfigs<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n this._ldClient.track(\n TRACK_USAGE_AGENT_CONFIGS,\n context,\n agentConfigs.length,\n agentConfigs.length,\n );\n\n const agents = {} as Record<T[number]['key'], LDAIAgentConfig>;\n\n await Promise.all(\n agentConfigs.map(async (config) => {\n const agent = await this._evaluate(\n config.key,\n context,\n config.defaultValue,\n 'agent',\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent as LDAIAgentConfig;\n }),\n );\n\n return agents;\n }\n\n /**\n * @deprecated Use `agentConfigs` instead. This method will be removed in a future version.\n */\n async agents<const T extends readonly LDAIAgentRequestConfig[]>(\n agentConfigs: T,\n context: LDContext,\n ): Promise<Record<T[number]['key'], LDAIAgentConfig>> {\n return this.agentConfigs(agentConfigs, context);\n }\n\n async createChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1);\n\n const config = await this._completionConfig(key, context, defaultValue, variables);\n\n if (!config.enabled || !config.tracker) {\n this._logger?.info(`Chat configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(config, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n const judges = await this._initializeJudges(\n config.judgeConfiguration?.judges ?? [],\n context,\n variables,\n defaultAiProvider,\n );\n\n return new TrackedChat(config, config.tracker, provider, judges, this._logger);\n }\n\n async createJudge(\n key: string,\n context: LDContext,\n defaultValue: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Judge | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1);\n\n try {\n if (variables?.message_history !== undefined) {\n this._logger?.warn(\n \"The variable 'message_history' is reserved by the judge and will be ignored.\",\n );\n }\n if (variables?.response_to_evaluate !== undefined) {\n this._logger?.warn(\n \"The variable 'response_to_evaluate' is reserved by the judge and will be ignored.\",\n );\n }\n\n // Overwrite reserved variables to ensure they remain as placeholders for judge evaluation\n const extendedVariables = {\n ...variables,\n message_history: '{{message_history}}',\n response_to_evaluate: '{{response_to_evaluate}}',\n };\n\n const judgeConfig = await this._judgeConfig(key, context, defaultValue, extendedVariables);\n\n if (!judgeConfig.enabled || !judgeConfig.tracker) {\n this._logger?.info(`Judge configuration is disabled: ${key}`);\n return undefined;\n }\n\n const provider = await AIProviderFactory.create(judgeConfig, this._logger, defaultAiProvider);\n if (!provider) {\n return undefined;\n }\n\n return new Judge(judgeConfig, judgeConfig.tracker, provider, this._logger);\n } catch (error) {\n this._logger?.error(`Failed to initialize judge ${key}:`, error);\n return undefined;\n }\n }\n\n /**\n * @deprecated Use `createChat` instead. This method will be removed in a future version.\n */\n async initChat(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<TrackedChat | undefined> {\n return this.createChat(key, context, defaultValue, variables, defaultAiProvider);\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAICompletionConfig, LDMessage } from '../config/types';\nimport { Judge } from '../judge/Judge';\nimport { JudgeResponse } from '../judge/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { ChatResponse } from './types';\n\n/**\n * Concrete implementation of TrackedChat that provides chat functionality\n * by delegating to an AIProvider implementation.\n * This class handles conversation management and tracking, while delegating\n * the actual model invocation to the provider.\n */\nexport class TrackedChat {\n protected messages: LDMessage[];\n\n constructor(\n protected readonly aiConfig: LDAICompletionConfig,\n protected readonly tracker: LDAIConfigTracker,\n protected readonly provider: AIProvider,\n protected readonly judges: Record<string, Judge> = {},\n private readonly _logger?: LDLogger,\n ) {\n this.messages = [];\n }\n\n /**\n * Invoke the chat model with a prompt string.\n * This method handles conversation management and tracking, delegating to the provider's invokeModel method.\n */\n async invoke(prompt: string): Promise<ChatResponse> {\n // Convert prompt string to LDMessage with role 'user' and add to conversation history\n const userMessage: LDMessage = {\n role: 'user',\n content: prompt,\n };\n this.messages.push(userMessage);\n\n // Prepend config messages to conversation history for model invocation\n const configMessages = this.aiConfig.messages || [];\n const allMessages = [...configMessages, ...this.messages];\n\n // Delegate to provider-specific implementation with tracking\n const response = await this.tracker.trackMetricsOf(\n (result: ChatResponse) => result.metrics,\n () => this.provider.invokeModel(allMessages),\n );\n\n if (\n this.aiConfig.judgeConfiguration?.judges &&\n this.aiConfig.judgeConfiguration.judges.length > 0\n ) {\n response.evaluations = this._evaluateWithJudges(this.messages, response);\n }\n\n this.messages.push(response.message);\n return response;\n }\n\n /**\n * Evaluates the response with all configured judges.\n * Returns a promise that resolves to an array of evaluation results.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @returns Promise resolving to array of judge evaluation results\n */\n private async _evaluateWithJudges(\n messages: LDMessage[],\n response: ChatResponse,\n ): Promise<Array<JudgeResponse | undefined>> {\n const judgeConfigs = this.aiConfig.judgeConfiguration!.judges;\n\n // Start all judge evaluations in parallel\n const evaluationPromises = judgeConfigs.map(async (judgeConfig) => {\n const judge = this.judges[judgeConfig.key];\n if (!judge) {\n this._logger?.warn(\n `Judge configuration is not enabled: ${judgeConfig.key}`,\n this.tracker.getTrackData(),\n );\n return undefined;\n }\n\n const judgeResponse = await judge.evaluateMessages(\n messages,\n response,\n judgeConfig.samplingRate,\n );\n\n if (judgeResponse && judgeResponse.success) {\n this.tracker.trackJudgeResponse(judgeResponse);\n }\n\n return judgeResponse;\n });\n\n // ensure all evaluations complete even if some fail\n const results = await Promise.allSettled(evaluationPromises);\n\n return results.map((result) => (result.status === 'fulfilled' ? result.value : undefined));\n }\n\n /**\n * Get the underlying AI configuration used to initialize this TrackedChat.\n */\n getConfig(): LDAICompletionConfig {\n return this.aiConfig;\n }\n\n /**\n * Get the underlying AI configuration tracker used to initialize this TrackedChat.\n */\n getTracker(): LDAIConfigTracker {\n return this.tracker;\n }\n\n /**\n * Get the underlying AI provider instance.\n * This provides direct access to the provider for advanced use cases.\n */\n getProvider(): AIProvider {\n return this.provider;\n }\n\n /**\n * Get the judges associated with this TrackedChat.\n * Returns a record of judge instances keyed by their configuration keys.\n */\n getJudges(): Record<string, Judge> {\n return this.judges;\n }\n\n /**\n * Append messages to the conversation history.\n * Adds messages to the conversation history without invoking the model,\n * which is useful for managing multi-turn conversations or injecting context.\n *\n * @param messages Array of messages to append to the conversation history\n */\n appendMessages(messages: LDMessage[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Get all messages in the conversation history.\n *\n * @param includeConfigMessages Whether to include the config messages from the AIConfig.\n * Defaults to false.\n * @returns Array of messages. When includeConfigMessages is true, returns both config\n * messages and conversation history with config messages prepended. When false,\n * returns only the conversation history messages.\n */\n getMessages(includeConfigMessages: boolean = false): LDMessage[] {\n if (includeConfigMessages) {\n const configMessages = this.aiConfig.messages || [];\n return [...configMessages, ...this.messages];\n }\n return [...this.messages];\n }\n}\n","import { LDAIConfigTracker } from './LDAIConfigTracker';\nimport {\n LDAIAgentConfig,\n LDAICompletionConfig,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIJudgeConfig,\n LDJudgeConfiguration,\n LDMessage,\n LDModelConfig,\n LDProviderConfig,\n} from './types';\n\n/**\n * Internal flag value structure returned by LaunchDarkly.\n * This represents the raw data structure that LaunchDarkly returns for AI configuration flags.\n *\n * @internal - Not meant for external use\n */\nexport interface LDAIConfigFlagValue {\n _ldMeta?: {\n variationKey?: string;\n enabled: boolean;\n version?: number;\n mode?: LDAIConfigMode;\n };\n model?: LDModelConfig;\n messages?: LDMessage[];\n provider?: LDProviderConfig;\n instructions?: string;\n evaluationMetricKey?: string;\n evaluationMetricKeys?: string[];\n judgeConfiguration?: LDJudgeConfiguration;\n}\n\n/**\n * Utility class for converting between AI configuration types and LaunchDarkly flag values.\n *\n * @internal - This class and its types are internal implementation details and should not be used by SDK consumers.\n */\nexport class LDAIConfigUtils {\n /**\n * Converts a default AI configuration to a LaunchDarkly flag value format.\n *\n * @param config The default AI configuration to convert\n * @param mode The mode for the configuration\n * @returns The flag value structure for LaunchDarkly\n */\n static toFlagValue(config: LDAIConfigDefaultKind, mode: LDAIConfigMode): LDAIConfigFlagValue {\n const flagValue: LDAIConfigFlagValue = {\n _ldMeta: {\n variationKey: '', // Not available when converting from config\n enabled: config.enabled ?? false,\n mode,\n },\n model: config.model,\n };\n\n if ('messages' in config && config.messages !== undefined) {\n flagValue.messages = config.messages;\n }\n if (config.provider !== undefined) {\n flagValue.provider = config.provider;\n }\n if ('instructions' in config && config.instructions !== undefined) {\n flagValue.instructions = config.instructions;\n }\n if ('evaluationMetricKey' in config && config.evaluationMetricKey !== undefined) {\n flagValue.evaluationMetricKey = config.evaluationMetricKey;\n }\n if ('evaluationMetricKeys' in config && config.evaluationMetricKeys !== undefined) {\n flagValue.evaluationMetricKeys = config.evaluationMetricKeys;\n }\n if ('judgeConfiguration' in config && config.judgeConfiguration !== undefined) {\n flagValue.judgeConfiguration = config.judgeConfiguration;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIConfigKind {\n // Determine the actual mode from flag value\n // eslint-disable-next-line no-underscore-dangle\n const flagValueMode = flagValue._ldMeta?.mode;\n\n switch (flagValueMode) {\n case 'agent':\n return this.toAgentConfig(key, flagValue, tracker);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, tracker);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, tracker);\n }\n }\n\n /**\n * Creates a disabled configuration of the specified mode.\n *\n * @param mode The mode for the disabled config\n * @returns A disabled config of the appropriate type\n */\n static createDisabledConfig(key: string, mode: LDAIConfigMode): LDAIConfigKind {\n switch (mode) {\n case 'agent':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAIJudgeConfig;\n case 'completion':\n default:\n // Default to completion config for completion mode or any unexpected mode\n return {\n key,\n enabled: false,\n tracker: undefined,\n } as LDAICompletionConfig;\n }\n }\n\n /**\n * Creates the base configuration that all config types share.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @returns Base configuration object\n */\n private static _toBaseConfig(key: string, flagValue: LDAIConfigFlagValue) {\n return {\n key,\n // eslint-disable-next-line no-underscore-dangle\n enabled: flagValue._ldMeta?.enabled ?? false,\n model: flagValue.model,\n provider: flagValue.provider,\n };\n }\n\n /**\n * Creates a completion config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param flagValue The flag value from LaunchDarkly\n * @param tracker The tracker to add to the config\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n tracker: LDAIConfigTracker,\n ): LDAIJudgeConfig {\n // Prioritize evaluationMetricKey, fallback to first valid (non-empty, non-whitespace) value in evaluationMetricKeys\n let evaluationMetricKey: string | undefined;\n if (flagValue.evaluationMetricKey && flagValue.evaluationMetricKey.trim().length > 0) {\n evaluationMetricKey = flagValue.evaluationMetricKey.trim();\n } else if (flagValue.evaluationMetricKeys && flagValue.evaluationMetricKeys.length > 0) {\n const validKey = flagValue.evaluationMetricKeys.find(\n (metricKey) => metricKey && metricKey.trim().length > 0,\n );\n evaluationMetricKey = validKey ? validKey.trim() : undefined;\n }\n\n return {\n ...this._toBaseConfig(key, flagValue),\n tracker,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import Mustache from 'mustache';\n\nimport { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigTracker } from '../config/LDAIConfigTracker';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { EvaluationSchemaBuilder } from './EvaluationSchemaBuilder';\nimport { EvalScore, JudgeResponse, StructuredResponse } from './types';\n\n/**\n * Judge implementation that handles evaluation functionality and conversation management.\n *\n * According to the AIEval spec, judges are AI Configs with mode: \"judge\" that evaluate\n * other AI Configs using structured output.\n */\nexport class Judge {\n private readonly _logger?: LDLogger;\n private readonly _evaluationResponseStructure: Record<string, unknown>;\n\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _aiConfigTracker: LDAIConfigTracker,\n private readonly _aiProvider: AIProvider,\n logger?: LDLogger,\n ) {\n this._logger = logger;\n const evaluationMetricKey = this._getEvaluationMetricKey();\n this._evaluationResponseStructure = EvaluationSchemaBuilder.build(evaluationMetricKey);\n }\n\n /**\n * Gets the evaluation metric key, prioritizing evaluationMetricKey over evaluationMetricKeys.\n * Falls back to the first valid (non-empty, non-whitespace) value in evaluationMetricKeys if evaluationMetricKey is not provided.\n * Treats empty strings and whitespace-only strings as invalid.\n * @returns The evaluation metric key, or undefined if not available\n */\n private _getEvaluationMetricKey(): string | undefined {\n if (\n this._aiConfig.evaluationMetricKey &&\n this._aiConfig.evaluationMetricKey.trim().length > 0\n ) {\n return this._aiConfig.evaluationMetricKey.trim();\n }\n if (this._aiConfig.evaluationMetricKeys && this._aiConfig.evaluationMetricKeys.length > 0) {\n const validKey = this._aiConfig.evaluationMetricKeys.find(\n (key) => key && key.trim().length > 0,\n );\n return validKey ? validKey.trim() : undefined;\n }\n return undefined;\n }\n\n /**\n * Evaluates an AI response using the judge's configuration.\n *\n * @param input The input prompt or question that was provided to the AI\n * @param output The AI-generated response to be evaluated\n * @param samplingRate Sampling rate (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluate(\n input: string,\n output: string,\n samplingRate: number = 1,\n ): Promise<JudgeResponse | undefined> {\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (!this._aiConfig.messages) {\n this._logger?.warn(\n 'Judge configuration must include messages',\n this._aiConfigTracker.getTrackData(),\n );\n return undefined;\n }\n\n if (Math.random() > samplingRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${samplingRate}`);\n return undefined;\n }\n\n const messages = this._constructEvaluationMessages(input, output);\n\n const response = await this._aiConfigTracker.trackMetricsOf(\n (result: StructuredResponse) => result.metrics,\n () => this._aiProvider.invokeStructuredModel(messages, this._evaluationResponseStructure),\n );\n\n let { success } = response.metrics;\n\n const evals = this._parseEvaluationResponse(response.data, evaluationMetricKey);\n\n if (!evals[evaluationMetricKey]) {\n this._logger?.warn(\n 'Judge evaluation did not return the expected evaluation',\n this._aiConfigTracker.getTrackData(),\n );\n success = false;\n }\n\n return {\n evals,\n success,\n judgeConfigKey: this._aiConfig.key,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n return {\n evals: {},\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n judgeConfigKey: this._aiConfig.key,\n };\n }\n }\n\n /**\n * Evaluates an AI response from chat messages and response.\n *\n * @param messages Array of messages representing the conversation history\n * @param response The AI response to be evaluated\n * @param samplingRatio Sampling ratio (0-1) to determine if evaluation should be processed (defaults to 1)\n * @returns Promise that resolves to evaluation results or undefined if not sampled\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio: number = 1,\n ): Promise<JudgeResponse | undefined> {\n const input = messages.length === 0 ? '' : messages.map((msg) => msg.content).join('\\r\\n');\n const output = response.message.content;\n\n return this.evaluate(input, output, samplingRatio);\n }\n\n /**\n * Returns the AI Config used by this judge.\n */\n getAIConfig(): LDAIJudgeConfig {\n return this._aiConfig;\n }\n\n /**\n * Returns the tracker associated with this judge.\n */\n getTracker(): LDAIConfigTracker {\n return this._aiConfigTracker;\n }\n\n /**\n * Returns the AI provider used by this judge.\n */\n getProvider(): AIProvider {\n return this._aiProvider;\n }\n\n /**\n * Constructs evaluation messages by combining judge's config messages with input/output.\n */\n private _constructEvaluationMessages(input: string, output: string): LDMessage[] {\n const messages: LDMessage[] = this._aiConfig.messages!.map((msg) => ({\n ...msg,\n content: this._interpolateMessage(msg.content, {\n message_history: input,\n response_to_evaluate: output,\n }),\n }));\n\n return messages;\n }\n\n /**\n * Interpolates message content with variables using Mustache templating.\n */\n private _interpolateMessage(content: string, variables: Record<string, string>): string {\n return Mustache.render(content, variables, undefined, { escape: (item: any) => item });\n }\n\n /**\n * Parses the structured evaluation response from the AI provider.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown>,\n evaluationMetricKey: string,\n ): Record<string, EvalScore> {\n const evaluations = data.evaluations as Record<string, unknown>;\n const results: Record<string, EvalScore> = {};\n\n if (!data.evaluations || typeof data.evaluations !== 'object') {\n this._logger?.warn('Invalid response: missing or invalid evaluations object');\n return results;\n }\n\n const evaluation = evaluations[evaluationMetricKey];\n\n if (!evaluation || typeof evaluation !== 'object') {\n this._logger?.warn(\n `Missing evaluation for metric key: ${evaluationMetricKey}`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n const evalData = evaluation as Record<string, unknown>;\n\n if (typeof evalData.score !== 'number' || evalData.score < 0 || evalData.score > 1) {\n this._logger?.warn(\n `Invalid score evaluated for ${evaluationMetricKey}: ${evalData.score}. Score must be a number between 0 and 1 inclusive`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n if (typeof evalData.reasoning !== 'string') {\n this._logger?.warn(\n `Invalid reasoning evaluated for ${evaluationMetricKey}: ${evalData.reasoning}. Reasoning must be a string`,\n this._aiConfigTracker.getTrackData(),\n );\n return results;\n }\n\n results[evaluationMetricKey] = {\n score: evalData.score,\n reasoning: evalData.reasoning,\n };\n\n return results;\n }\n}\n","/**\n * Internal class for building dynamic evaluation response schemas.\n * Not exported - only used internally by TrackedJudge.\n */\nclass EvaluationSchemaBuilder {\n static build(evaluationMetricKey?: string): Record<string, unknown> {\n if (!evaluationMetricKey) {\n return {};\n }\n return {\n type: 'object',\n properties: {\n evaluations: {\n type: 'object',\n description: `Object containing evaluation results for ${evaluationMetricKey} metric`,\n properties: {\n [evaluationMetricKey]: this._buildKeySchema(evaluationMetricKey),\n },\n required: [evaluationMetricKey],\n additionalProperties: false,\n },\n },\n required: ['evaluations'],\n additionalProperties: false,\n } as const;\n }\n\n private static _buildKeySchema(key: string) {\n return {\n type: 'object',\n properties: {\n score: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: `Score between 0.0 and 1.0 for ${key}`,\n },\n reasoning: {\n type: 'string',\n description: `Reasoning behind the score for ${key}`,\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n };\n }\n}\n\nexport { EvaluationSchemaBuilder };\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIConfigKind, LDMessage } from '../config/types';\nimport { StructuredResponse } from '../judge/types';\n\n/**\n * Abstract base class for AI providers that implement chat model functionality.\n * This class provides the contract that all provider implementations must follow\n * to integrate with LaunchDarkly's tracking and configuration capabilities.\n *\n * Following the AICHAT spec recommendation to use base classes with non-abstract methods\n * for better extensibility and backwards compatibility.\n */\nexport abstract class AIProvider {\n protected readonly logger?: LDLogger;\n\n constructor(logger?: LDLogger) {\n this.logger = logger;\n }\n /**\n * Invoke the chat model with an array of messages.\n * This method should convert messages to provider format, invoke the model,\n * and return a ChatResponse with the result and metrics.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @returns Promise that resolves to a ChatResponse containing the model's response\n */\n async invokeModel(_messages: LDMessage[]): Promise<ChatResponse> {\n this.logger?.warn('invokeModel not implemented by this provider');\n return {\n message: {\n role: 'assistant',\n content: '',\n },\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Invoke the chat model with structured output support.\n * This method should convert messages to provider format, invoke the model with\n * structured output configuration, and return a structured response.\n *\n * Default implementation takes no action and returns a placeholder response.\n * Provider implementations should override this method.\n *\n * @param messages Array of LDMessage objects representing the conversation\n * @param responseStructure Dictionary of output configurations keyed by output name\n * @returns Promise that resolves to a structured response\n */\n async invokeStructuredModel(\n _messages: LDMessage[],\n _responseStructure: Record<string, unknown>,\n ): Promise<StructuredResponse> {\n this.logger?.warn('invokeStructuredModel not implemented by this provider');\n return {\n data: {},\n rawResponse: '',\n metrics: {\n success: false,\n usage: {\n total: 0,\n input: 0,\n output: 0,\n },\n },\n };\n }\n\n /**\n * Static method that constructs an instance of the provider.\n * Each provider implementation must provide their own static create method\n * that accepts an AIConfig and returns a configured instance.\n *\n * @param aiConfig The LaunchDarkly AI configuration\n * @param logger Optional logger for the provider\n * @returns Promise that resolves to a configured provider instance\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static async create(aiConfig: LDAIConfigKind, logger?: LDLogger): Promise<AIProvider> {\n throw new Error('Provider implementations must override the static create method');\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigKind } from '../config/types';\nimport { AIProvider } from './AIProvider';\n\n/**\n * List of supported AI providers.\n */\nexport const SUPPORTED_AI_PROVIDERS = [\n 'openai',\n // Multi-provider packages should be last in the list\n 'langchain',\n 'vercel',\n] as const;\n\n/**\n * Type representing the supported AI providers.\n */\nexport type SupportedAIProvider = (typeof SUPPORTED_AI_PROVIDERS)[number];\n\n/**\n * Factory for creating AIProvider instances based on the provider configuration.\n */\nexport class AIProviderFactory {\n /**\n * Create an AIProvider instance based on the AI configuration.\n * This method attempts to load provider-specific implementations dynamically.\n * Returns undefined if the provider is not supported.\n *\n * @param aiConfig The AI configuration\n * @param logger Optional logger for logging provider initialization\n * @param defaultAiProvider Optional default AI provider to use\n */\n static async create(\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<AIProvider | undefined> {\n const providerName = aiConfig.provider?.name?.toLowerCase();\n // Determine which providers to try based on defaultAiProvider\n const providersToTry = this._getProvidersToTry(defaultAiProvider, providerName);\n\n // Try each provider in order\n // eslint-disable-next-line no-restricted-syntax\n for (const providerType of providersToTry) {\n logger?.debug(\n `Attempting to create AIProvider for: ${aiConfig.provider?.name} with provider type: ${providerType}`,\n );\n // eslint-disable-next-line no-await-in-loop\n const provider = await this._tryCreateProvider(providerType, aiConfig, logger);\n if (provider) {\n logger?.debug(`Successfully created AIProvider for: ${aiConfig.provider?.name}`);\n return provider;\n }\n }\n\n // If no provider was successfully created, log a warning\n logger?.warn(\n `Provider is not supported or failed to initialize: ${aiConfig.provider?.name ?? 'unknown'}`,\n );\n return undefined;\n }\n\n /**\n * Determine which providers to try based on defaultAiProvider and providerName.\n */\n private static _getProvidersToTry(\n defaultAiProvider?: SupportedAIProvider,\n providerName?: string,\n ): SupportedAIProvider[] {\n // If defaultAiProvider is set, only try that specific provider\n if (defaultAiProvider) {\n return [defaultAiProvider];\n }\n\n // If no defaultAiProvider is set, try all providers in order\n const providerSet = new Set<SupportedAIProvider>();\n\n // First try the specific provider if it's supported\n if (providerName && SUPPORTED_AI_PROVIDERS.includes(providerName as SupportedAIProvider)) {\n providerSet.add(providerName as SupportedAIProvider);\n }\n\n // Then try multi-provider packages, but avoid duplicates\n const multiProviderPackages: SupportedAIProvider[] = ['langchain', 'vercel'];\n multiProviderPackages.forEach((provider) => {\n providerSet.add(provider);\n });\n\n return Array.from(providerSet);\n }\n\n /**\n * Try to create a provider of the specified type.\n */\n private static async _tryCreateProvider(\n providerType: SupportedAIProvider,\n aiConfig: LDAIConfigKind,\n logger?: LDLogger,\n ): Promise<AIProvider | undefined> {\n try {\n let module;\n\n switch (providerType) {\n case 'openai': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-openai' as any);\n const provider = (await module.OpenAIProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'langchain': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-langchain' as any);\n const provider = (await module.LangChainProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n case 'vercel': {\n // eslint-disable-next-line import/no-extraneous-dependencies\n module = await import('@launchdarkly/server-sdk-ai-vercel' as any);\n const provider = (await module.VercelProvider.create(aiConfig, logger)) as AIProvider;\n return provider;\n }\n default:\n return undefined;\n }\n } catch (error: any) {\n logger?.warn(\n `Unable to create AIProvider. Check that you have installed the correct package. ${error.message}`,\n );\n return undefined;\n }\n }\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createBedrockTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens || 0,\n input: data.inputTokens || 0,\n output: data.outputTokens || 0,\n };\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createOpenAiUsage(data: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n}): LDTokenUsage {\n return {\n total: data.total_tokens ?? 0,\n input: data.prompt_tokens ?? 0,\n output: data.completion_tokens ?? 0,\n };\n}\n","/**\n * Feedback about the generated content.\n */\nexport enum LDFeedbackKind {\n /**\n * The sentiment was positive.\n */\n Positive = 'positive',\n /**\n * The sentiment is negative.\n */\n Negative = 'negative',\n}\n","import { LDTokenUsage } from './LDTokenUsage';\n\nexport function createVercelAISDKTokenUsage(data: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n}): LDTokenUsage {\n return {\n total: data.totalTokens ?? 0,\n input: data.inputTokens ?? data.promptTokens ?? 0,\n output: data.outputTokens ?? data.completionTokens ?? 0,\n };\n}\n","import { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIConfigTracker } from './api/config';\nimport { LDAIMetricSummary } from './api/config/LDAIConfigTracker';\nimport { EvalScore, JudgeResponse } from './api/judge/types';\nimport {\n createBedrockTokenUsage,\n createOpenAiUsage,\n createVercelAISDKTokenUsage,\n LDAIMetrics,\n LDFeedbackKind,\n LDTokenUsage,\n} from './api/metrics';\nimport { LDClientMin } from './LDClientMin';\n\nexport class LDAIConfigTrackerImpl implements LDAIConfigTracker {\n private _trackedMetrics: LDAIMetricSummary = {};\n\n constructor(\n private _ldClient: LDClientMin,\n private _configKey: string,\n private _variationKey: string,\n private _version: number,\n private _modelName: string,\n private _providerName: string,\n private _context: LDContext,\n ) {}\n\n getTrackData(): {\n variationKey: string;\n configKey: string;\n version: number;\n modelName: string;\n providerName: string;\n } {\n return {\n variationKey: this._variationKey,\n configKey: this._configKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n };\n }\n\n trackDuration(duration: number): void {\n this._trackedMetrics.durationMs = duration;\n this._ldClient.track('$ld:ai:duration:total', this._context, this.getTrackData(), duration);\n }\n\n async trackDurationOf<TRes>(func: () => Promise<TRes>): Promise<TRes> {\n const startTime = Date.now();\n try {\n // Be sure to await here so that we can track the duration of the function and also handle errors.\n const result = await func();\n return result;\n } finally {\n const endTime = Date.now();\n const duration = endTime - startTime; // duration in milliseconds\n this.trackDuration(duration);\n }\n }\n\n trackTimeToFirstToken(timeToFirstTokenMs: number) {\n this._trackedMetrics.timeToFirstTokenMs = timeToFirstTokenMs;\n this._ldClient.track(\n '$ld:ai:tokens:ttf',\n this._context,\n this.getTrackData(),\n timeToFirstTokenMs,\n );\n }\n\n trackEvalScores(scores: Record<string, EvalScore>) {\n Object.entries(scores).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(metricKey, this._context, this.getTrackData(), evalScore.score);\n });\n }\n\n trackJudgeResponse(response: JudgeResponse) {\n Object.entries(response.evals).forEach(([metricKey, evalScore]) => {\n this._ldClient.track(\n metricKey,\n this._context,\n { ...this.getTrackData(), judgeConfigKey: response.judgeConfigKey },\n evalScore.score,\n );\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n this._trackedMetrics.feedback = feedback;\n if (feedback.kind === LDFeedbackKind.Positive) {\n this._ldClient.track('$ld:ai:feedback:user:positive', this._context, this.getTrackData(), 1);\n } else if (feedback.kind === LDFeedbackKind.Negative) {\n this._ldClient.track('$ld:ai:feedback:user:negative', this._context, this.getTrackData(), 1);\n }\n }\n\n trackSuccess(): void {\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n this._trackedMetrics.success = false;\n this._ldClient.track('$ld:ai:generation:error', this._context, this.getTrackData(), 1);\n }\n\n async trackMetricsOf<TRes>(\n metricsExtractor: (result: TRes) => LDAIMetrics,\n func: () => Promise<TRes>,\n ): Promise<TRes> {\n let result: TRes;\n\n try {\n result = await this.trackDurationOf(func);\n } catch (err) {\n this.trackError();\n throw err;\n }\n\n // Extract metrics after successful AI call\n const metrics = metricsExtractor(result);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n\n return result;\n }\n\n trackStreamMetricsOf<TStream>(\n streamCreator: () => TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n ): TStream {\n const startTime = Date.now();\n\n try {\n // Create the stream synchronously\n const stream = streamCreator();\n\n // Start background metrics tracking (fire and forget)\n this._trackStreamMetricsInBackground(stream, metricsExtractor, startTime);\n\n // Return stream immediately for consumption\n return stream;\n } catch (error) {\n // Track error if stream creation fails\n this.trackDuration(Date.now() - startTime);\n this.trackError();\n throw error;\n }\n }\n\n private async _trackStreamMetricsInBackground<TStream>(\n stream: TStream,\n metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,\n startTime: number,\n ): Promise<void> {\n try {\n // Wait for metrics to be available\n const metrics = await metricsExtractor(stream);\n\n // Track success/error based on metrics\n if (metrics.success) {\n this.trackSuccess();\n } else {\n this.trackError();\n }\n\n // Track token usage if available\n if (metrics.usage) {\n this.trackTokens(metrics.usage);\n }\n } catch (error) {\n // If metrics extraction fails, track error\n this.trackError();\n } finally {\n // Track duration regardless of success/error\n this.trackDuration(Date.now() - startTime);\n }\n }\n\n async trackOpenAIMetrics<\n TRes extends {\n usage?: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createOpenAiUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackBedrockConverseMetrics<\n TRes extends {\n $metadata: { httpStatusCode?: number };\n metrics?: { latencyMs?: number };\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n },\n >(res: TRes): TRes {\n if (res.$metadata?.httpStatusCode === 200) {\n this.trackSuccess();\n } else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {\n this.trackError();\n }\n if (res.metrics && res.metrics.latencyMs) {\n this.trackDuration(res.metrics.latencyMs);\n }\n if (res.usage) {\n this.trackTokens(createBedrockTokenUsage(res.usage));\n }\n return res;\n }\n\n async trackVercelAISDKGenerateTextMetrics<\n TRes extends {\n usage?: {\n totalTokens?: number;\n inputTokens?: number;\n promptTokens?: number;\n outputTokens?: number;\n completionTokens?: number;\n };\n },\n >(func: () => Promise<TRes>): Promise<TRes> {\n try {\n const result = await this.trackDurationOf(func);\n this.trackSuccess();\n if (result.usage) {\n this.trackTokens(createVercelAISDKTokenUsage(result.usage));\n }\n return result;\n } catch (err) {\n this.trackError();\n throw err;\n }\n }\n\n trackTokens(tokens: LDTokenUsage): void {\n this._trackedMetrics.tokens = tokens;\n const trackData = this.getTrackData();\n if (tokens.total > 0) {\n this._ldClient.track('$ld:ai:tokens:total', this._context, trackData, tokens.total);\n }\n if (tokens.input > 0) {\n this._ldClient.track('$ld:ai:tokens:input', this._context, trackData, tokens.input);\n }\n if (tokens.output > 0) {\n this._ldClient.track('$ld:ai:tokens:output', this._context, trackData, tokens.output);\n }\n }\n\n /**\n * Get a summary of the tracked metrics.\n */\n getSummary(): LDAIMetricSummary {\n return { ...this._trackedMetrics };\n }\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.16.5'; // x-release-please-version\nexport const aiSdkLanguage = 'javascript';\n","/**\n * This is the API reference for the LaunchDarkly AI SDK for Server-Side JavaScript.\n *\n * In typical usage, you will call {@link initAi} once at startup time to obtain an instance of\n * {@link LDAIClient}, which provides access to all of the SDK's functionality.\n *\n * @packageDocumentation\n */\n// IMPORTANT: Namespace import required for CJS compatibility. js-server-sdk-common is CommonJS-only;\n// Node.js ESM can't reliably import named exports from CJS. DO NOT change to named imports.\nimport * as common from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIClient } from './api/LDAIClient';\nimport { LDAIClientImpl } from './LDAIClientImpl';\nimport { LDClientMin } from './LDClientMin';\n\n/**\n * Initialize a new AI client. This client will be used to perform any AI operations.\n * @param ldClient The base LaunchDarkly client.\n * @returns A new AI client.\n */\nexport function initAi(ldClient: LDClientMin): LDAIClient {\n return new LDAIClientImpl(ldClient);\n}\n\nexport type LDLogger = common.LDLogger;\n\nexport * from './api';\n"],"mappings":"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","names":["Mustache","LDFeedbackKind","Mustache"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchdarkly/server-sdk-ai",
3
- "version": "0.16.3",
3
+ "version": "0.16.5",
4
4
  "description": "LaunchDarkly AI SDK for Server-Side JavaScript",
5
5
  "homepage": "https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai",
6
6
  "repository": {
@@ -45,7 +45,7 @@
45
45
  "mustache": "^4.2.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@launchdarkly/js-server-sdk-common": "2.18.0",
48
+ "@launchdarkly/js-server-sdk-common": "2.18.2",
49
49
  "@trivago/prettier-plugin-sort-imports": "^4.1.1",
50
50
  "@types/jest": "^29.5.3",
51
51
  "@types/mustache": "^4.2.5",