@launchdarkly/server-sdk-ai 0.19.1 → 0.20.0
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 +26 -0
- package/README.md +13 -16
- package/dist/index.cjs +586 -351
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +591 -265
- package/dist/index.d.ts +591 -265
- package/dist/index.js +582 -349
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/LDAIClientImpl.ts","../src/api/chat/TrackedChat.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/graph/AgentGraphNode.ts","../src/api/graph/AgentGraphDefinition.ts","../src/api/judge/Judge.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/LDGraphTrackerImpl.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';\nexport { LDGraphTrackerImpl } from './LDGraphTrackerImpl';\n","import Mustache from 'mustache';\nimport { randomUUID } from 'node:crypto';\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 LDAIConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIConfigTracker,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { AgentGraphDefinition, LDAgentGraphFlagValue, LDGraphTracker } from './api/graph';\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 { LDGraphTrackerImpl } from './LDGraphTrackerImpl';\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';\nconst TRACK_USAGE_AGENT_GRAPH = '$ld:ai:usage:agent-graph';\n\nconst INIT_TRACK_CONTEXT: LDContext = {\n kind: 'ld_ai',\n key: 'ld-internal-tracking',\n anonymous: true,\n};\n\nconst disabledAIConfig: LDAIConfigDefault = { enabled: false };\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 graphKey?: string,\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 trackerFactory = () =>\n new LDAIConfigTrackerImpl(\n this._ldClient,\n randomUUID(),\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 graphKey,\n );\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, trackerFactory);\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 undefined,\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 return this._completionConfig(key, context, defaultValue ?? disabledAIConfig, 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 return this._judgeConfig(key, context, defaultValue ?? disabledAIConfig, variables);\n }\n\n private async _agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n graphKey?: string,\n ): Promise<LDAIAgentConfig> {\n const config = await this._evaluate(key, context, defaultValue, 'agent', variables, graphKey);\n return config as LDAIAgentConfig;\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 return this._agentConfig(key, context, defaultValue ?? disabledAIConfig, variables);\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._agentConfig(\n config.key,\n context,\n config.defaultValue ?? disabledAIConfig,\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent;\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 const config = await this._completionConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n );\n\n if (!config.enabled) {\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, 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(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n extendedVariables,\n );\n\n if (!judgeConfig.enabled) {\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, 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 createTracker(token: string, context: LDContext): LDAIConfigTracker {\n return LDAIConfigTrackerImpl.fromResumptionToken(token, this._ldClient, context);\n }\n\n async agentGraph(\n graphKey: string,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): Promise<AgentGraphDefinition> {\n this._ldClient.track(TRACK_USAGE_AGENT_GRAPH, context, graphKey, 1);\n\n const defaultGraphValue: LDAgentGraphFlagValue = { root: '' };\n const graphFlagValue = (await this._ldClient.variation(\n graphKey,\n context,\n defaultGraphValue,\n )) as LDAgentGraphFlagValue;\n\n // eslint-disable-next-line no-underscore-dangle\n const variationKey = graphFlagValue._ldMeta?.variationKey;\n // eslint-disable-next-line no-underscore-dangle\n const version = graphFlagValue._ldMeta?.version ?? 1;\n const ldClient = this._ldClient;\n const trackerFactory = () =>\n new LDGraphTrackerImpl(ldClient, randomUUID(), graphKey, variationKey, version, context);\n\n const disabled = new AgentGraphDefinition(graphFlagValue, {}, false, trackerFactory);\n\n // eslint-disable-next-line no-underscore-dangle\n if (graphFlagValue._ldMeta?.enabled === false) {\n this._logger?.debug(`agentGraph: graph \"${graphKey}\" is disabled.`);\n return disabled;\n }\n\n if (!graphFlagValue.root) {\n this._logger?.debug(`agentGraph: graph \"${graphKey}\" is not fetchable or has no root node.`);\n return disabled;\n }\n\n const allKeys = AgentGraphDefinition.collectAllKeys(graphFlagValue);\n const reachableKeys = this._collectReachableKeys(graphFlagValue);\n\n const unreachableKey = [...allKeys].find((key) => !reachableKeys.has(key));\n if (unreachableKey) {\n this._logger?.debug(\n `agentGraph: graph \"${graphKey}\" has unconnected node \"${unreachableKey}\" that is not reachable from the root.`,\n );\n return disabled;\n }\n\n const agentConfigs: Record<string, LDAIAgentConfig> = {};\n const fetchResults = await Promise.all(\n [...allKeys].map(async (key) => {\n const config = await this._agentConfig(key, context, disabledAIConfig, variables, graphKey);\n return { key, config };\n }),\n );\n\n const disabledResult = fetchResults.find(({ config }) => !config.enabled);\n if (disabledResult) {\n this._logger?.debug(\n `agentGraph: agent config \"${disabledResult.key}\" in graph \"${graphKey}\" is not enabled or could not be fetched.`,\n );\n return disabled;\n }\n fetchResults.forEach(({ key, config }) => {\n agentConfigs[key] = config;\n });\n\n const nodes = AgentGraphDefinition.buildNodes(graphFlagValue, agentConfigs);\n return new AgentGraphDefinition(graphFlagValue, nodes, true, trackerFactory);\n }\n\n createGraphTracker(token: string, context: LDContext): LDGraphTracker {\n return LDGraphTrackerImpl.fromResumptionToken(token, this._ldClient, context);\n }\n\n /**\n * Returns the set of all node keys reachable from the root via BFS.\n */\n private _collectReachableKeys(graph: LDAgentGraphFlagValue): Set<string> {\n const visited = new Set<string>();\n const queue: string[] = [graph.root];\n visited.add(graph.root);\n\n while (queue.length > 0) {\n const key = queue.shift()!;\n const edges = graph.edges?.[key] ?? [];\n edges.forEach((edge) => {\n if (!visited.has(edge.key)) {\n visited.add(edge.key);\n queue.push(edge.key);\n }\n });\n }\n\n return visited;\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAICompletionConfig, LDMessage } from '../config/types';\nimport { Judge } from '../judge/Judge';\nimport { LDJudgeResult } 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 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 const tracker = this.aiConfig.createTracker!();\n\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 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).then(\n (evaluations) => {\n evaluations.forEach((judgeResult) => {\n tracker.trackJudgeResult(judgeResult);\n });\n return evaluations;\n },\n );\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<LDJudgeResult[]> {\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 for ${judgeConfig.key} in ${this.aiConfig.key}`,\n );\n const result: LDJudgeResult = {\n success: false,\n sampled: true,\n errorMessage: `Judge configuration is not enabled for ${judgeConfig.key}`,\n };\n return result;\n }\n\n return judge.evaluateMessages(messages, response, judgeConfig.samplingRate);\n });\n\n // ensure all evaluations complete even if some fail\n const results = await Promise.allSettled(evaluationPromises);\n\n return results.map((settled) => {\n if (settled.status === 'fulfilled') {\n return settled.value;\n }\n const result: LDJudgeResult = {\n success: false,\n sampled: true,\n errorMessage: 'Judge evaluation failed',\n };\n return result;\n });\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 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 LDTool,\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 tools?: { [toolName: string]: LDTool };\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 if ('tools' in config && config.tools !== undefined) {\n flagValue.tools = config.tools;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => 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, trackerFactory);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, trackerFactory);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, trackerFactory);\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 createTracker: undefined,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n createTracker: 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 createTracker: undefined,\n } as LDAICompletionConfig;\n }\n }\n\n private static _resolveTools(\n flagValue: LDAIConfigFlagValue,\n ): { [toolName: string]: LDTool } | undefined {\n if (flagValue.tools !== undefined) {\n return flagValue.tools as { [toolName: string]: LDTool } | undefined;\n }\n\n const rawTools = flagValue.model?.parameters?.['tools'];\n if (!Array.isArray(rawTools)) {\n return undefined;\n }\n\n const result: { [toolName: string]: LDTool } = {};\n for (const entry of rawTools) {\n const tool = entry as LDTool;\n if (tool?.name) {\n result[tool.name] = tool;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\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 key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => LDAIConfigTracker,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n createTracker: trackerFactory,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n tools: this._resolveTools(flagValue),\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => LDAIConfigTracker,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n createTracker: trackerFactory,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n tools: this._resolveTools(flagValue),\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => 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 createTracker: trackerFactory,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import type { LDAIAgentConfig } from '../config';\nimport type { LDGraphEdge } from './types';\n\n/**\n * Represents a single node within an agent graph.\n *\n * Each node wraps an {@link LDAIAgentConfig} and carries the outgoing edges\n * to its children. Use the node's tracker (via `getConfig().tracker`) to record\n * node-level metrics against the underlying agent config.\n */\nexport class AgentGraphNode {\n constructor(\n private readonly _key: string,\n private readonly _config: LDAIAgentConfig,\n private readonly _edges: LDGraphEdge[],\n ) {}\n\n /**\n * Returns the agent config key that identifies this node in the graph.\n */\n getKey(): string {\n return this._key;\n }\n\n /**\n * Returns the underlying AIAgentConfig for this node.\n * Use `getConfig().tracker` to record node-level metrics.\n */\n getConfig(): LDAIAgentConfig {\n return this._config;\n }\n\n /**\n * Returns the outgoing edges from this node to its children.\n */\n getEdges(): LDGraphEdge[] {\n return this._edges;\n }\n\n /**\n * Returns `true` if this node has no outgoing edges (i.e., it is a terminal/leaf node).\n */\n isTerminal(): boolean {\n return this._edges.length === 0;\n }\n}\n","import type { LDAIAgentConfig } from '../config';\nimport { AgentGraphNode } from './AgentGraphNode';\nimport type { LDGraphTracker } from './LDGraphTracker';\nimport type { LDAgentGraphFlagValue, LDGraphEdge } from './types';\n\n/**\n * Callback function signature for graph traversal methods.\n */\nexport type TraversalFn = (\n node: AgentGraphNode,\n executionContext: Record<string, unknown>,\n) => unknown;\n\n/**\n * Encapsulates an agent graph configuration and its pre-built node collection.\n *\n * Provides graph-level orchestration including relationship queries (parent/child),\n * breadth-first traversal in both forward and reverse directions, and graph tracker creation.\n *\n * Obtain an instance via {@link LDAIClient.agentGraph}. When the graph is disabled\n * or invalid, the returned instance has {@link enabled} set to `false` and an\n * empty node collection.\n */\nexport class AgentGraphDefinition {\n constructor(\n private readonly _agentGraph: LDAgentGraphFlagValue,\n private readonly _nodes: Record<string, AgentGraphNode>,\n readonly enabled: boolean,\n private readonly _createTracker: () => LDGraphTracker,\n ) {}\n\n /**\n * Builds a node map from a raw agent graph flag value and a map of pre-fetched agent configs.\n *\n * @param graph Raw graph flag value from LaunchDarkly.\n * @param agentConfigs Map of agent config key to resolved LDAIAgentConfig.\n * @returns Record mapping agent config keys to AgentGraphNode instances.\n */\n static buildNodes(\n graph: LDAgentGraphFlagValue,\n agentConfigs: Record<string, LDAIAgentConfig>,\n ): Record<string, AgentGraphNode> {\n const nodes: Record<string, AgentGraphNode> = {};\n const allKeys = AgentGraphDefinition.collectAllKeys(graph);\n\n allKeys.forEach((key) => {\n const config = agentConfigs[key];\n if (!config) {\n return;\n }\n const outgoingEdges: LDGraphEdge[] = graph.edges?.[key] ?? [];\n nodes[key] = new AgentGraphNode(key, config, outgoingEdges);\n });\n\n return nodes;\n }\n\n /**\n * Returns the children of the node identified by `nodeKey`.\n *\n * @param nodeKey The agent config key of the parent node.\n */\n getChildNodes(nodeKey: string): AgentGraphNode[] {\n const node = this._nodes[nodeKey];\n if (!node) {\n return [];\n }\n return node\n .getEdges()\n .map((edge) => this._nodes[edge.key])\n .filter((n): n is AgentGraphNode => n !== undefined);\n }\n\n /**\n * Returns all nodes that have a direct edge to the node identified by `nodeKey`.\n *\n * @param nodeKey The agent config key of the child node.\n */\n getParentNodes(nodeKey: string): AgentGraphNode[] {\n return Object.values(this._nodes).filter((node) =>\n node.getEdges().some((edge) => edge.key === nodeKey),\n );\n }\n\n /**\n * Returns all terminal nodes (nodes with no outgoing edges).\n */\n terminalNodes(): AgentGraphNode[] {\n return Object.values(this._nodes).filter((node) => node.isTerminal());\n }\n\n /**\n * Returns the root node of the graph.\n */\n rootNode(): AgentGraphNode {\n return this._nodes[this._agentGraph.root];\n }\n\n /**\n * Returns the node with the given key, or `null` if not found.\n *\n * @param nodeKey The agent config key to look up.\n */\n getNode(nodeKey: string): AgentGraphNode | null {\n return this._nodes[nodeKey] ?? null;\n }\n\n /**\n * Returns the underlying raw graph configuration from LaunchDarkly.\n */\n getConfig(): LDAgentGraphFlagValue {\n return this._agentGraph;\n }\n\n /**\n * Returns a new {@link LDGraphTracker} for this graph invocation.\n *\n * Call this once per invocation. Each call produces a tracker with a fresh `runId`\n * that groups all events for that invocation.\n */\n createTracker(): LDGraphTracker {\n return this._createTracker();\n }\n\n /**\n * Traverses the graph breadth-first from the root to all terminal nodes.\n *\n * Nodes at the same depth are processed before advancing to the next depth.\n * The value returned by `fn` is stored in the mutable `executionContext` under\n * the node's key, making upstream results available to downstream nodes.\n *\n * Cyclic graphs are handled safely — each node is visited at most once.\n *\n * @param fn Callback invoked for each node. Its return value is added to\n * `executionContext` keyed by the node's config key.\n * @param initialExecutionContext Optional initial context to seed the traversal.\n */\n traverse(fn: TraversalFn, initialExecutionContext: Record<string, unknown> = {}): void {\n const root = this.rootNode();\n if (!root) {\n return;\n }\n\n const executionContext = { ...initialExecutionContext };\n const visited = new Set<string>();\n const queue: AgentGraphNode[] = [root];\n visited.add(root.getKey());\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n const result = fn(node, executionContext);\n executionContext[node.getKey()] = result;\n\n node.getEdges().forEach((edge) => {\n if (!visited.has(edge.key)) {\n const child = this._nodes[edge.key];\n if (child) {\n visited.add(edge.key);\n queue.push(child);\n }\n }\n });\n }\n }\n\n /**\n * Traverses the graph from terminal nodes up to the root.\n *\n * Uses BFS upward via parent edges so that each node is processed only after\n * all of its reachable descendants have been processed. The root is always\n * visited last. Cyclic graphs are handled safely — each node is visited at\n * most once; if the graph has no terminal nodes, this method returns without\n * invoking `fn`.\n *\n * **Ordering note:** Within a single BFS level (nodes at the same depth from a\n * terminal) the visit order is not strictly guaranteed. The guarantee is only\n * that a node is visited before any of its ancestors — not that siblings at the\n * same depth are visited in a specific order relative to each other.\n *\n * The value returned by `fn` is stored in the mutable `executionContext` under\n * the node's key.\n *\n * @param fn Callback invoked for each node. Its return value is added to\n * `executionContext` keyed by the node's config key.\n * @param initialExecutionContext Optional initial context to seed the traversal.\n */\n reverseTraverse(fn: TraversalFn, initialExecutionContext: Record<string, unknown> = {}): void {\n const terminals = this.terminalNodes();\n if (terminals.length === 0) {\n return;\n }\n\n const executionContext = { ...initialExecutionContext };\n const rootKey = this._agentGraph.root;\n const visited = new Set<string>();\n let queue: AgentGraphNode[] = terminals;\n\n while (queue.length > 0) {\n const nextQueue: AgentGraphNode[] = [];\n\n queue.forEach((node) => {\n const key = node.getKey();\n if (visited.has(key)) {\n return;\n }\n visited.add(key);\n\n // Defer the root so it is always processed last\n if (key === rootKey) {\n return;\n }\n\n const result = fn(node, executionContext);\n executionContext[key] = result;\n\n this.getParentNodes(key).forEach((parent) => {\n if (!visited.has(parent.getKey())) {\n nextQueue.push(parent);\n }\n });\n });\n\n queue = nextQueue;\n }\n\n // Root is always last — only invoke if it was reached during traversal\n const root = this._nodes[rootKey];\n if (root && visited.has(rootKey)) {\n const result = fn(root, executionContext);\n executionContext[rootKey] = result;\n }\n }\n\n /**\n * Collects every unique node key referenced in the graph (root + all edge sources\n * and targets).\n */\n static collectAllKeys(graph: LDAgentGraphFlagValue): Set<string> {\n const keys = new Set<string>();\n keys.add(graph.root);\n\n if (graph.edges) {\n Object.entries(graph.edges).forEach(([sourceKey, edges]) => {\n keys.add(sourceKey);\n edges.forEach((edge) => {\n keys.add(edge.key);\n });\n });\n }\n\n return keys;\n }\n}\n","import Mustache from 'mustache';\n\nimport { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { AIProvider } from '../providers/AIProvider';\nimport { LDJudgeResult, StructuredResponse } from './types';\n\nconst EVALUATION_SCHEMA = {\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.',\n },\n reasoning: {\n type: 'string',\n description: 'Reasoning behind the score.',\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n} as const;\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\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _aiProvider: AIProvider,\n logger?: LDLogger,\n ) {\n this._logger = logger;\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\n */\n async evaluate(input: string, output: string, samplingRate: number = 1): Promise<LDJudgeResult> {\n const result: LDJudgeResult = {\n success: false,\n sampled: false,\n judgeConfigKey: this._aiConfig.key,\n };\n\n const tracker = this._aiConfig.createTracker!();\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n tracker.getTrackData(),\n );\n result.sampled = true;\n result.errorMessage = 'Judge configuration is missing required evaluation metric key';\n return result;\n }\n\n if (!this._aiConfig.messages) {\n this._logger?.warn('Judge configuration must include messages', tracker.getTrackData());\n result.sampled = true;\n result.errorMessage = 'Judge configuration must include messages';\n return result;\n }\n\n if (Math.random() > samplingRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${samplingRate}`);\n return result;\n }\n\n result.sampled = true;\n\n const messages = this._constructEvaluationMessages(input, output);\n\n const response = await tracker.trackMetricsOf(\n (r: StructuredResponse) => r.metrics,\n () => this._aiProvider.invokeStructuredModel(messages, EVALUATION_SCHEMA),\n );\n\n const evalResult = this._parseEvaluationResponse(response.data);\n\n if (!evalResult) {\n this._logger?.warn(\n `Could not parse evaluation response: ${JSON.stringify(response.data)}`,\n tracker.getTrackData(),\n );\n return result;\n }\n\n return {\n ...result,\n success: response.metrics.success,\n score: evalResult.score,\n reasoning: evalResult.reasoning,\n metricKey: evaluationMetricKey,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n result.sampled = true;\n result.errorMessage = error instanceof Error ? error.message : 'Unknown error';\n return result;\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\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio: number = 1,\n ): Promise<LDJudgeResult> {\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 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. Expects top-level {score, reasoning}.\n * Returns score and reasoning, or undefined if parsing fails.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown>,\n ): { score: number; reasoning: string } | undefined {\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return undefined;\n }\n\n if (typeof data.score !== 'number' || data.score < 0 || data.score > 1) {\n return undefined;\n }\n\n if (typeof data.reasoning !== 'string') {\n return undefined;\n }\n\n return {\n score: data.score,\n reasoning: data.reasoning,\n };\n }\n}\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 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 { LDJudgeResult } 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 _runId: string,\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 private _graphKey?: string,\n ) {}\n\n getTrackData(): {\n runId: string;\n configKey: string;\n variationKey: string;\n version: number;\n modelName: string;\n providerName: string;\n graphKey?: string;\n } {\n return {\n runId: this._runId,\n configKey: this._configKey,\n variationKey: this._variationKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n ...(this._graphKey !== undefined ? { graphKey: this._graphKey } : {}),\n };\n }\n\n get resumptionToken(): string {\n const json = JSON.stringify({\n runId: this._runId,\n configKey: this._configKey,\n variationKey: this._variationKey,\n version: this._version,\n ...(this._graphKey !== undefined ? { graphKey: this._graphKey } : {}),\n });\n return Buffer.from(json).toString('base64url');\n }\n\n static fromResumptionToken(\n token: string,\n ldClient: LDClientMin,\n context: LDContext,\n ): LDAIConfigTrackerImpl {\n const json = Buffer.from(token, 'base64url').toString('utf8');\n const payload = JSON.parse(json);\n return new LDAIConfigTrackerImpl(\n ldClient,\n payload.runId,\n payload.configKey,\n payload.variationKey ?? '',\n payload.version,\n '',\n '',\n context,\n payload.graphKey,\n );\n }\n\n trackDuration(duration: number): void {\n if (this._trackedMetrics.durationMs !== undefined) {\n this._ldClient.logger?.warn(\n 'Duration has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 if (this._trackedMetrics.timeToFirstTokenMs !== undefined) {\n this._ldClient.logger?.warn(\n 'Time to first token has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 trackJudgeResult(result: LDJudgeResult) {\n if (!result.sampled || !result.success) {\n return;\n }\n if (result.metricKey !== undefined && result.score !== undefined) {\n const trackData = result.judgeConfigKey\n ? { ...this.getTrackData(), judgeConfigKey: result.judgeConfigKey }\n : this.getTrackData();\n this._ldClient.track(result.metricKey, this._context, trackData, result.score);\n }\n }\n\n trackToolCall(toolKey: string): void {\n this._ldClient.track('$ld:ai:tool_call', this._context, { ...this.getTrackData(), toolKey }, 1);\n }\n\n trackToolCalls(toolKeys: string[]): void {\n toolKeys.forEach((toolKey) => {\n this.trackToolCall(toolKey);\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n if (this._trackedMetrics.feedback !== undefined) {\n this._ldClient.logger?.warn(\n 'Feedback has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 if (this._trackedMetrics.success !== undefined) {\n this._ldClient.logger?.warn(\n 'Generation result has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n if (this._trackedMetrics.success !== undefined) {\n this._ldClient.logger?.warn(\n 'Generation result has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 if (this._trackedMetrics.tokens !== undefined) {\n this._ldClient.logger?.warn(\n 'Token usage has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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","import type { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport type { LDGraphTracker } from './api/graph/LDGraphTracker';\nimport type { LDGraphMetricSummary, LDGraphTrackData } from './api/graph/types';\nimport type { LDTokenUsage } from './api/metrics';\nimport type { LDClientMin } from './LDClientMin';\n\n/**\n * Concrete implementation of {@link LDGraphTracker}.\n *\n * Construct directly or reconstruct from a resumption token via\n * {@link LDGraphTrackerImpl.fromResumptionToken}.\n */\nexport class LDGraphTrackerImpl implements LDGraphTracker {\n private _summary: LDGraphMetricSummary = {};\n\n constructor(\n private readonly _ldClient: LDClientMin,\n private readonly _runId: string,\n private readonly _graphKey: string,\n private readonly _variationKey: string | undefined,\n private readonly _version: number,\n private readonly _context: LDContext,\n ) {}\n\n /**\n * Reconstructs an {@link LDGraphTrackerImpl} from a resumption token, preserving\n * the original `runId` so all events continue to be correlated under the same run.\n *\n * **Security note:** The token contains the flag variation key and version.\n * Do not pass the raw token to untrusted clients.\n *\n * @param token URL-safe Base64-encoded token produced by {@link LDGraphTrackerImpl.resumptionToken}.\n * @param ldClient LaunchDarkly client instance.\n * @param context LDContext for the new tracker.\n */\n static fromResumptionToken(\n token: string,\n ldClient: LDClientMin,\n context: LDContext,\n ): LDGraphTrackerImpl {\n const json = Buffer.from(token, 'base64url').toString('utf8');\n const data = JSON.parse(json) as LDGraphTrackData;\n return new LDGraphTrackerImpl(\n ldClient,\n data.runId,\n data.graphKey,\n data.variationKey,\n data.version,\n context,\n );\n }\n\n getTrackData(): LDGraphTrackData {\n const data: LDGraphTrackData = {\n runId: this._runId,\n graphKey: this._graphKey,\n version: this._version,\n };\n if (this._variationKey !== undefined) {\n data.variationKey = this._variationKey;\n }\n return data;\n }\n\n getSummary(): LDGraphMetricSummary {\n return { ...this._summary };\n }\n\n get resumptionToken(): string {\n // Keys must appear in exact spec-defined order:\n // runId, graphKey, variationKey (omitted if absent), version\n const parts: string[] = [\n `\"runId\":${JSON.stringify(this._runId)}`,\n `\"graphKey\":${JSON.stringify(this._graphKey)}`,\n ];\n if (this._variationKey !== undefined) {\n parts.push(`\"variationKey\":${JSON.stringify(this._variationKey)}`);\n }\n parts.push(`\"version\":${this._version}`);\n const json = `{${parts.join(',')}}`;\n return Buffer.from(json).toString('base64url');\n }\n\n trackInvocationSuccess(): void {\n if (this._summary.success !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: invocation success/failure already recorded for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.success = true;\n this._ldClient.track('$ld:ai:graph:invocation_success', this._context, this.getTrackData(), 1);\n }\n\n trackInvocationFailure(): void {\n if (this._summary.success !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: invocation success/failure already recorded for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.success = false;\n this._ldClient.track('$ld:ai:graph:invocation_failure', this._context, this.getTrackData(), 1);\n }\n\n trackDuration(durationMs: number): void {\n if (this._summary.durationMs !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackDuration already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.durationMs = durationMs;\n this._ldClient.track(\n '$ld:ai:graph:duration:total',\n this._context,\n this.getTrackData(),\n durationMs,\n );\n }\n\n trackTotalTokens(tokens: LDTokenUsage): void {\n if (this._summary.tokens !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackTotalTokens already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.tokens = { ...tokens };\n this._ldClient.track(\n '$ld:ai:graph:total_tokens',\n this._context,\n this.getTrackData(),\n tokens.total,\n );\n }\n\n trackPath(path: string[]): void {\n if (this._summary.path !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackPath already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.path = [...path];\n this._ldClient.track('$ld:ai:graph:path', this._context, { ...this.getTrackData(), path }, 1);\n }\n\n trackRedirect(sourceKey: string, redirectedTarget: string): void {\n this._ldClient.track(\n '$ld:ai:graph:redirect',\n this._context,\n { ...this.getTrackData(), sourceKey, redirectedTarget },\n 1,\n );\n }\n\n trackHandoffSuccess(sourceKey: string, targetKey: string): void {\n this._ldClient.track(\n '$ld:ai:graph:handoff_success',\n this._context,\n { ...this.getTrackData(), sourceKey, targetKey },\n 1,\n );\n }\n\n trackHandoffFailure(sourceKey: string, targetKey: string): void {\n this._ldClient.track(\n '$ld:ai:graph:handoff_failure',\n this._context,\n { ...this.getTrackData(), sourceKey, targetKey },\n 1,\n );\n }\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.19.1'; // x-release-please-version\nexport const aiSdkLanguage = 'javascript';\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/ManagedAgent.ts","../src/api/ManagedModel.ts","../src/api/config/LDAIConfigUtils.ts","../src/api/graph/AgentGraphNode.ts","../src/api/graph/AgentGraphDefinition.ts","../src/api/graph/ManagedAgentGraph.ts","../src/api/judge/Evaluator.ts","../src/api/judge/Judge.ts","../src/api/providers/AIProvider.ts","../src/api/providers/RunnerFactory.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/LDGraphTrackerImpl.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';\nexport { LDGraphTrackerImpl } from './LDGraphTrackerImpl';\n","import Mustache from 'mustache';\nimport { randomUUID } from 'node:crypto';\n\nimport { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ManagedAgent } from './api/ManagedAgent';\nimport { ManagedModel } from './api/ManagedModel';\nimport {\n LDAIAgentConfig,\n LDAIAgentConfigDefault,\n LDAIAgentRequestConfig,\n LDAICompletionConfig,\n LDAICompletionConfigDefault,\n LDAIConfigDefault,\n LDAIConfigDefaultKind,\n LDAIConfigKind,\n LDAIConfigMode,\n LDAIConfigTracker,\n LDAIJudgeConfig,\n LDAIJudgeConfigDefault,\n LDJudge,\n LDMessage,\n} from './api/config';\nimport { LDAIConfigFlagValue, LDAIConfigUtils } from './api/config/LDAIConfigUtils';\nimport { AgentGraphDefinition, LDAgentGraphFlagValue, LDGraphTracker } from './api/graph';\nimport { Evaluator } from './api/judge/Evaluator';\nimport { Judge, stripLegacyJudgeMessages } from './api/judge/Judge';\nimport { LDAIClient } from './api/LDAIClient';\nimport { RunnerFactory, SupportedAIProvider } from './api/providers';\nimport { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl';\nimport { LDClientMin } from './LDClientMin';\nimport { LDGraphTrackerImpl } from './LDGraphTrackerImpl';\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_CREATE_AGENT = '$ld:ai:usage:create-agent';\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';\nconst TRACK_USAGE_AGENT_GRAPH = '$ld:ai:usage:agent-graph';\n\nconst INIT_TRACK_CONTEXT: LDContext = {\n kind: 'ld_ai',\n key: 'ld-internal-tracking',\n anonymous: true,\n};\n\nconst disabledAIConfig: LDAIConfigDefault = { enabled: false };\n\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 graphKey?: string,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<LDAIConfigKind> {\n const ldFlagValue = LDAIConfigUtils.toFlagValue(defaultValue, mode);\n\n const value: LDAIConfigFlagValue = await this._ldClient.variation(key, context, ldFlagValue);\n\n const trackerFactory = () =>\n new LDAIConfigTrackerImpl(\n this._ldClient,\n randomUUID(),\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 graphKey,\n );\n\n // Validate mode match\n // eslint-disable-next-line no-underscore-dangle\n const flagMode = value._ldMeta?.mode ?? 'completion';\n let evaluator = Evaluator.noop();\n\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, trackerFactory, evaluator);\n }\n\n if (flagMode !== 'judge') {\n evaluator = await this._buildEvaluator(\n value.judgeConfiguration?.judges ?? [],\n context,\n variables,\n defaultAiProvider,\n );\n }\n\n const config = LDAIConfigUtils.fromFlagValue(key, value, trackerFactory, evaluator);\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 _buildEvaluator(\n judgeConfigs: LDJudge[],\n context: LDContext,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Evaluator> {\n if (judgeConfigs.length === 0) {\n return Evaluator.noop();\n }\n\n const judgeInstances = (\n await Promise.all(\n judgeConfigs.map((jc) =>\n this._createJudgeInstance(\n jc.key,\n context,\n undefined,\n variables,\n defaultAiProvider,\n jc.samplingRate,\n ),\n ),\n )\n ).filter((j): j is Judge => j !== undefined);\n\n return new Evaluator(judgeInstances);\n }\n\n private async _completionConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<LDAICompletionConfig> {\n return (await this._evaluate(\n key,\n context,\n defaultValue,\n 'completion',\n variables,\n undefined,\n defaultAiProvider,\n )) as LDAICompletionConfig;\n }\n\n async completionConfig(\n key: string,\n context: LDContext,\n defaultValue?: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<LDAICompletionConfig> {\n this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1);\n return this._completionConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n defaultAiProvider,\n );\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 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 // Re-inject the reserved variables as their literal placeholders so they\n // survive Mustache interpolation in `_evaluate`. Without this, legacy\n // templates like `{{message_history}}` get rendered to empty strings and\n // `stripLegacyJudgeMessages` below cannot detect them.\n const extendedVariables = {\n ...variables,\n message_history: '{{message_history}}',\n response_to_evaluate: '{{response_to_evaluate}}',\n };\n\n const config = (await this._evaluate(\n key,\n context,\n defaultValue,\n 'judge',\n extendedVariables,\n )) as LDAIJudgeConfig;\n\n // Strip legacy judge template messages (containing {{message_history}} or\n // {{response_to_evaluate}}) before returning the config. New-style configs\n // omit these and rely on Judge._buildEvaluationInput.\n if (config.messages) {\n return { ...config, messages: stripLegacyJudgeMessages(config.messages) };\n }\n\n return config;\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 return this._judgeConfig(key, context, defaultValue ?? disabledAIConfig, variables);\n }\n\n private async _agentConfig(\n key: string,\n context: LDContext,\n defaultValue: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n graphKey?: string,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<LDAIAgentConfig> {\n return (await this._evaluate(\n key,\n context,\n defaultValue,\n 'agent',\n variables,\n graphKey,\n defaultAiProvider,\n )) as LDAIAgentConfig;\n }\n\n async agentConfig(\n key: string,\n context: LDContext,\n defaultValue?: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<LDAIAgentConfig> {\n this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1);\n return this._agentConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n undefined,\n defaultAiProvider,\n );\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._agentConfig(\n config.key,\n context,\n config.defaultValue ?? disabledAIConfig,\n config.variables,\n );\n agents[config.key as T[number]['key']] = agent;\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 createJudge(\n key: string,\n context: LDContext,\n defaultValue?: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n sampleRate: number = 1.0,\n ): Promise<Judge | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1);\n return this._createJudgeInstance(\n key,\n context,\n defaultValue,\n variables,\n defaultAiProvider,\n sampleRate,\n );\n }\n\n private async _createJudgeInstance(\n key: string,\n context: LDContext,\n defaultValue?: LDAIJudgeConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n sampleRate: number = 1.0,\n ): Promise<Judge | undefined> {\n try {\n const judgeConfig = await this._judgeConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n );\n\n if (!judgeConfig.enabled) {\n this._logger?.info(`Judge configuration is disabled: ${key}`);\n return undefined;\n }\n\n const runner = await RunnerFactory.createModel(judgeConfig, this._logger, defaultAiProvider);\n if (!runner) {\n return undefined;\n }\n\n return new Judge(judgeConfig, runner, sampleRate, this._logger);\n } catch (error) {\n this._logger?.error(`Failed to initialize judge ${key}:`, error);\n return undefined;\n }\n }\n\n async createModel(\n key: string,\n context: LDContext,\n defaultValue?: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<ManagedModel | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1);\n const config = await this._completionConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n defaultAiProvider,\n );\n\n if (!config.enabled) {\n this._logger?.info(`Completion configuration is disabled: ${key}`);\n return undefined;\n }\n\n const runner = await RunnerFactory.createModel(config, this._logger, defaultAiProvider);\n if (!runner) {\n return undefined;\n }\n\n return new ManagedModel(config, runner, this._logger);\n }\n\n async createAgent(\n key: string,\n context: LDContext,\n defaultValue?: LDAIAgentConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<ManagedAgent | undefined> {\n this._ldClient.track(TRACK_USAGE_CREATE_AGENT, context, key, 1);\n\n const config = await this._agentConfig(\n key,\n context,\n defaultValue ?? disabledAIConfig,\n variables,\n undefined,\n defaultAiProvider,\n );\n\n if (!config.enabled) {\n this._logger?.info(`Agent configuration is disabled: ${key}`);\n return undefined;\n }\n\n const runner = await RunnerFactory.createAgent(config, undefined, this._logger, defaultAiProvider);\n if (!runner) {\n return undefined;\n }\n\n return new ManagedAgent(config, runner, this._logger);\n }\n\n /**\n * @deprecated Use `createModel` instead. This method will be removed in a future version.\n */\n async createChat(\n key: string,\n context: LDContext,\n defaultValue?: LDAICompletionConfigDefault,\n variables?: Record<string, unknown>,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<ManagedModel | undefined> {\n return this.createModel(key, context, defaultValue, variables, defaultAiProvider);\n }\n\n /**\n * @deprecated Use `createModel` 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<ManagedModel | undefined> {\n return this.createModel(key, context, defaultValue, variables, defaultAiProvider);\n }\n\n createTracker(token: string, context: LDContext): LDAIConfigTracker {\n return LDAIConfigTrackerImpl.fromResumptionToken(token, this._ldClient, context);\n }\n\n async agentGraph(\n graphKey: string,\n context: LDContext,\n variables?: Record<string, unknown>,\n ): Promise<AgentGraphDefinition> {\n this._ldClient.track(TRACK_USAGE_AGENT_GRAPH, context, graphKey, 1);\n\n const defaultGraphValue: LDAgentGraphFlagValue = { root: '' };\n const graphFlagValue = (await this._ldClient.variation(\n graphKey,\n context,\n defaultGraphValue,\n )) as LDAgentGraphFlagValue;\n\n // eslint-disable-next-line no-underscore-dangle\n const variationKey = graphFlagValue._ldMeta?.variationKey;\n // eslint-disable-next-line no-underscore-dangle\n const version = graphFlagValue._ldMeta?.version ?? 1;\n const ldClient = this._ldClient;\n const trackerFactory = () =>\n new LDGraphTrackerImpl(ldClient, randomUUID(), graphKey, variationKey, version, context);\n\n const disabled = new AgentGraphDefinition(graphFlagValue, {}, false, trackerFactory);\n\n // eslint-disable-next-line no-underscore-dangle\n if (graphFlagValue._ldMeta?.enabled === false) {\n this._logger?.debug(`agentGraph: graph \"${graphKey}\" is disabled.`);\n return disabled;\n }\n\n if (!graphFlagValue.root) {\n this._logger?.debug(`agentGraph: graph \"${graphKey}\" is not fetchable or has no root node.`);\n return disabled;\n }\n\n const allKeys = AgentGraphDefinition.collectAllKeys(graphFlagValue);\n const reachableKeys = this._collectReachableKeys(graphFlagValue);\n\n const unreachableKey = [...allKeys].find((key) => !reachableKeys.has(key));\n if (unreachableKey) {\n this._logger?.debug(\n `agentGraph: graph \"${graphKey}\" has unconnected node \"${unreachableKey}\" that is not reachable from the root.`,\n );\n return disabled;\n }\n\n const agentConfigs: Record<string, LDAIAgentConfig> = {};\n const fetchResults = await Promise.all(\n [...allKeys].map(async (key) => {\n const config = await this._agentConfig(key, context, disabledAIConfig, variables, graphKey);\n return { key, config };\n }),\n );\n\n const disabledResult = fetchResults.find(({ config }) => !config.enabled);\n if (disabledResult) {\n this._logger?.debug(\n `agentGraph: agent config \"${disabledResult.key}\" in graph \"${graphKey}\" is not enabled or could not be fetched.`,\n );\n return disabled;\n }\n fetchResults.forEach(({ key, config }) => {\n agentConfigs[key] = config;\n });\n\n const nodes = AgentGraphDefinition.buildNodes(graphFlagValue, agentConfigs);\n return new AgentGraphDefinition(graphFlagValue, nodes, true, trackerFactory);\n }\n\n createGraphTracker(token: string, context: LDContext): LDGraphTracker {\n return LDGraphTrackerImpl.fromResumptionToken(token, this._ldClient, context);\n }\n\n /**\n * Returns the set of all node keys reachable from the root via BFS.\n */\n private _collectReachableKeys(graph: LDAgentGraphFlagValue): Set<string> {\n const visited = new Set<string>();\n const queue: string[] = [graph.root];\n visited.add(graph.root);\n\n while (queue.length > 0) {\n const key = queue.shift()!;\n const edges = graph.edges?.[key] ?? [];\n edges.forEach((edge) => {\n if (!visited.has(edge.key)) {\n visited.add(edge.key);\n queue.push(edge.key);\n }\n });\n }\n\n return visited;\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIAgentConfig } from './config/types';\nimport { ManagedResult, RunnerResult } from './model/types';\nimport { Runner } from './providers/Runner';\n\n/**\n * ManagedAgent provides agent invocation with automatic tracking and automatic\n * judge evaluation.\n *\n * The class is stateless: each `run()` call sends the prompt directly to the\n * underlying `Runner` and returns a `ManagedResult`. Conversation history,\n * if any, must be managed by the caller (or by the Runner implementation).\n *\n * Obtain an instance via `LDAIClient.createAgent()`.\n */\nexport class ManagedAgent {\n constructor(\n protected readonly aiAgentConfig: LDAIAgentConfig,\n protected readonly runner: Runner,\n private readonly _logger?: LDLogger,\n ) {}\n\n /**\n * Invoke the agent with a prompt string and return a ManagedResult.\n *\n * `run()` resolves before `ManagedResult.evaluations` resolves. Awaiting\n * `evaluations` guarantees both judge evaluation and tracker.trackJudgeResult()\n * are complete.\n *\n * @param prompt The user input to send to the agent.\n * @returns Promise resolving to ManagedResult (before evaluations settle).\n */\n async run(prompt: string): Promise<ManagedResult> {\n const tracker = this.aiAgentConfig.createTracker!();\n\n const result = await tracker.trackMetricsOf(\n (r: RunnerResult) => r.metrics,\n () => this.runner.run(prompt),\n );\n\n const metrics = tracker.getSummary();\n\n const output = result.content;\n const evaluations = this.aiAgentConfig.evaluator\n .evaluate(prompt, output)\n .then((results) => {\n results.forEach((judgeResult) => {\n if (!judgeResult.sampled) {\n return;\n }\n tracker.trackJudgeResult(judgeResult);\n });\n return results;\n })\n .catch((err) => {\n this._logger?.warn('Judge evaluation failed unexpectedly:', err);\n return [];\n });\n\n return {\n content: output,\n metrics,\n raw: result.raw,\n parsed: result.parsed,\n evaluations,\n };\n }\n\n /**\n * Get the underlying AI agent configuration used to initialize this ManagedAgent.\n */\n getConfig(): LDAIAgentConfig {\n return this.aiAgentConfig;\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAICompletionConfig } from './config/types';\nimport { ManagedResult, RunnerResult } from './model/types';\nimport { Runner } from './providers/Runner';\n\n/**\n * ManagedModel provides chat-completion invocation with automatic tracking and\n * automatic judge evaluation.\n *\n * The class is stateless: each `run()` call sends the prompt directly to the\n * underlying `Runner` and returns a `ManagedResult`. Conversation history,\n * if any, must be managed by the caller (or by the Runner implementation).\n *\n * Obtain an instance via `LDAIClient.createModel()`.\n */\nexport class ManagedModel {\n constructor(\n protected readonly aiConfig: LDAICompletionConfig,\n protected readonly runner: Runner,\n private readonly _logger?: LDLogger,\n ) {}\n\n /**\n * Invoke the model with a prompt string and return a ManagedResult.\n *\n * `run()` resolves before `ManagedResult.evaluations` resolves. Awaiting\n * `evaluations` guarantees both judge evaluation and tracker.trackJudgeResult()\n * are complete.\n *\n * @param prompt The user input to send to the model.\n * @returns Promise resolving to ManagedResult (before evaluations settle).\n */\n async run(prompt: string): Promise<ManagedResult> {\n const tracker = this.aiConfig.createTracker();\n\n const result = await tracker.trackMetricsOf(\n (r: RunnerResult) => r.metrics,\n () => this.runner.run(prompt),\n );\n\n const metrics = tracker.getSummary();\n\n const output = result.content;\n const evaluations = this.aiConfig.evaluator\n .evaluate(prompt, output)\n .then((results) => {\n results.forEach((judgeResult) => {\n if (!judgeResult.sampled) {\n return;\n }\n tracker.trackJudgeResult(judgeResult);\n });\n return results;\n })\n .catch((err) => {\n this._logger?.warn('Judge evaluation failed unexpectedly:', err);\n return [];\n });\n\n return {\n content: output,\n metrics,\n raw: result.raw,\n parsed: result.parsed,\n evaluations,\n };\n }\n\n /**\n * Get the underlying AI configuration used to initialize this ManagedModel.\n */\n getConfig(): LDAICompletionConfig {\n return this.aiConfig;\n }\n}\n","import { Evaluator } from '../judge/Evaluator';\nimport { 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 LDTool,\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 tools?: { [toolName: string]: LDTool };\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 if ('tools' in config && config.tools !== undefined) {\n flagValue.tools = config.tools;\n }\n\n return flagValue;\n }\n\n /**\n * Converts a LaunchDarkly flag value to the appropriate AI configuration type.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @param evaluator The evaluator to attach to completion and agent configs\n * @returns The appropriate AI configuration type\n */\n static fromFlagValue(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => LDAIConfigTracker,\n evaluator: Evaluator,\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, trackerFactory, evaluator);\n case 'judge':\n return this.toJudgeConfig(key, flagValue, trackerFactory);\n case 'completion':\n default:\n return this.toCompletionConfig(key, flagValue, trackerFactory, evaluator);\n }\n }\n\n /**\n * Creates a disabled configuration of the specified mode.\n *\n * @param key The configuration key\n * @param mode The mode for the disabled config\n * @param createTracker A factory function that creates a new tracker for each execution\n * @param evaluator The evaluator to attach to completion and agent configs\n * @returns A disabled config of the appropriate type\n */\n static createDisabledConfig(\n key: string,\n mode: LDAIConfigMode,\n createTracker: () => LDAIConfigTracker,\n evaluator: Evaluator,\n ): LDAIConfigKind {\n switch (mode) {\n case 'agent':\n return {\n key,\n enabled: false,\n createTracker,\n evaluator,\n } as LDAIAgentConfig;\n case 'judge':\n return {\n key,\n enabled: false,\n createTracker,\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 createTracker,\n evaluator,\n } as LDAICompletionConfig;\n }\n }\n\n private static _resolveTools(\n flagValue: LDAIConfigFlagValue,\n ): { [toolName: string]: LDTool } | undefined {\n if (flagValue.tools !== undefined) {\n return flagValue.tools as { [toolName: string]: LDTool } | undefined;\n }\n\n const rawTools = flagValue.model?.parameters?.['tools'];\n if (!Array.isArray(rawTools)) {\n return undefined;\n }\n\n const result: { [toolName: string]: LDTool } = {};\n for (const entry of rawTools) {\n const tool = entry as LDTool;\n if (tool?.name) {\n result[tool.name] = tool;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\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 key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @param evaluator The evaluator for this completion config\n * @returns A completion configuration\n */\n static toCompletionConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => LDAIConfigTracker,\n evaluator: Evaluator,\n ): LDAICompletionConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n createTracker: trackerFactory,\n evaluator,\n messages: flagValue.messages,\n judgeConfiguration: flagValue.judgeConfiguration,\n tools: this._resolveTools(flagValue),\n };\n }\n\n /**\n * Creates an agent config from flag value data.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @param evaluator The evaluator for this agent config\n * @returns An agent configuration\n */\n static toAgentConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => LDAIConfigTracker,\n evaluator: Evaluator,\n ): LDAIAgentConfig {\n return {\n ...this._toBaseConfig(key, flagValue),\n createTracker: trackerFactory,\n evaluator,\n instructions: flagValue.instructions,\n judgeConfiguration: flagValue.judgeConfiguration,\n tools: this._resolveTools(flagValue),\n };\n }\n\n /**\n * Creates a judge config from flag value data.\n *\n * @param key The configuration key\n * @param flagValue The flag value from LaunchDarkly\n * @param trackerFactory A factory function that creates a new tracker for each execution\n * @returns A judge configuration\n */\n static toJudgeConfig(\n key: string,\n flagValue: LDAIConfigFlagValue,\n trackerFactory: () => 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 createTracker: trackerFactory,\n messages: flagValue.messages,\n evaluationMetricKey,\n };\n }\n}\n","import type { LDAIAgentConfig } from '../config';\nimport type { LDGraphEdge } from './types';\n\n/**\n * Represents a single node within an agent graph.\n *\n * Each node wraps an {@link LDAIAgentConfig} and carries the outgoing edges\n * to its children. Use the node's tracker (via `getConfig().tracker`) to record\n * node-level metrics against the underlying agent config.\n */\nexport class AgentGraphNode {\n constructor(\n private readonly _key: string,\n private readonly _config: LDAIAgentConfig,\n private readonly _edges: LDGraphEdge[],\n ) {}\n\n /**\n * Returns the agent config key that identifies this node in the graph.\n */\n getKey(): string {\n return this._key;\n }\n\n /**\n * Returns the underlying AIAgentConfig for this node.\n * Use `getConfig().tracker` to record node-level metrics.\n */\n getConfig(): LDAIAgentConfig {\n return this._config;\n }\n\n /**\n * Returns the outgoing edges from this node to its children.\n */\n getEdges(): LDGraphEdge[] {\n return this._edges;\n }\n\n /**\n * Returns `true` if this node has no outgoing edges (i.e., it is a terminal/leaf node).\n */\n isTerminal(): boolean {\n return this._edges.length === 0;\n }\n}\n","import type { LDAIAgentConfig } from '../config';\nimport { AgentGraphNode } from './AgentGraphNode';\nimport type { LDGraphTracker } from './LDGraphTracker';\nimport type { LDAgentGraphFlagValue, LDGraphEdge } from './types';\n\n/**\n * Callback function signature for graph traversal methods.\n */\nexport type TraversalFn = (\n node: AgentGraphNode,\n executionContext: Record<string, unknown>,\n) => unknown;\n\n/**\n * Encapsulates an agent graph configuration and its pre-built node collection.\n *\n * Provides graph-level orchestration including relationship queries (parent/child),\n * breadth-first traversal in both forward and reverse directions, and graph tracker creation.\n *\n * Obtain an instance via {@link LDAIClient.agentGraph}. When the graph is disabled\n * or invalid, the returned instance has {@link enabled} set to `false` and an\n * empty node collection.\n */\nexport class AgentGraphDefinition {\n constructor(\n private readonly _agentGraph: LDAgentGraphFlagValue,\n private readonly _nodes: Record<string, AgentGraphNode>,\n readonly enabled: boolean,\n private readonly _createTracker: () => LDGraphTracker,\n ) {}\n\n /**\n * Builds a node map from a raw agent graph flag value and a map of pre-fetched agent configs.\n *\n * @param graph Raw graph flag value from LaunchDarkly.\n * @param agentConfigs Map of agent config key to resolved LDAIAgentConfig.\n * @returns Record mapping agent config keys to AgentGraphNode instances.\n */\n static buildNodes(\n graph: LDAgentGraphFlagValue,\n agentConfigs: Record<string, LDAIAgentConfig>,\n ): Record<string, AgentGraphNode> {\n const nodes: Record<string, AgentGraphNode> = {};\n const allKeys = AgentGraphDefinition.collectAllKeys(graph);\n\n allKeys.forEach((key) => {\n const config = agentConfigs[key];\n if (!config) {\n return;\n }\n const outgoingEdges: LDGraphEdge[] = graph.edges?.[key] ?? [];\n nodes[key] = new AgentGraphNode(key, config, outgoingEdges);\n });\n\n return nodes;\n }\n\n /**\n * Returns the children of the node identified by `nodeKey`.\n *\n * @param nodeKey The agent config key of the parent node.\n */\n getChildNodes(nodeKey: string): AgentGraphNode[] {\n const node = this._nodes[nodeKey];\n if (!node) {\n return [];\n }\n return node\n .getEdges()\n .map((edge) => this._nodes[edge.key])\n .filter((n): n is AgentGraphNode => n !== undefined);\n }\n\n /**\n * Returns all nodes that have a direct edge to the node identified by `nodeKey`.\n *\n * @param nodeKey The agent config key of the child node.\n */\n getParentNodes(nodeKey: string): AgentGraphNode[] {\n return Object.values(this._nodes).filter((node) =>\n node.getEdges().some((edge) => edge.key === nodeKey),\n );\n }\n\n /**\n * Returns all terminal nodes (nodes with no outgoing edges).\n */\n terminalNodes(): AgentGraphNode[] {\n return Object.values(this._nodes).filter((node) => node.isTerminal());\n }\n\n /**\n * Returns the root node of the graph.\n */\n rootNode(): AgentGraphNode {\n return this._nodes[this._agentGraph.root];\n }\n\n /**\n * Returns the node with the given key, or `null` if not found.\n *\n * @param nodeKey The agent config key to look up.\n */\n getNode(nodeKey: string): AgentGraphNode | null {\n return this._nodes[nodeKey] ?? null;\n }\n\n /**\n * Returns the underlying raw graph configuration from LaunchDarkly.\n */\n getConfig(): LDAgentGraphFlagValue {\n return this._agentGraph;\n }\n\n /**\n * Returns a new {@link LDGraphTracker} for this graph invocation.\n *\n * Call this once per invocation. Each call produces a tracker with a fresh `runId`\n * that groups all events for that invocation.\n */\n createTracker(): LDGraphTracker {\n return this._createTracker();\n }\n\n /**\n * Traverses the graph breadth-first from the root to all terminal nodes.\n *\n * Nodes at the same depth are processed before advancing to the next depth.\n * The value returned by `fn` is stored in the mutable `executionContext` under\n * the node's key, making upstream results available to downstream nodes.\n *\n * Cyclic graphs are handled safely — each node is visited at most once.\n *\n * @param fn Callback invoked for each node. Its return value is added to\n * `executionContext` keyed by the node's config key.\n * @param initialExecutionContext Optional initial context to seed the traversal.\n */\n traverse(fn: TraversalFn, initialExecutionContext: Record<string, unknown> = {}): void {\n const root = this.rootNode();\n if (!root) {\n return;\n }\n\n const executionContext = { ...initialExecutionContext };\n const visited = new Set<string>();\n const queue: AgentGraphNode[] = [root];\n visited.add(root.getKey());\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n const result = fn(node, executionContext);\n executionContext[node.getKey()] = result;\n\n node.getEdges().forEach((edge) => {\n if (!visited.has(edge.key)) {\n const child = this._nodes[edge.key];\n if (child) {\n visited.add(edge.key);\n queue.push(child);\n }\n }\n });\n }\n }\n\n /**\n * Traverses the graph from terminal nodes up to the root.\n *\n * Uses BFS upward via parent edges so that each node is processed only after\n * all of its reachable descendants have been processed. The root is always\n * visited last. Cyclic graphs are handled safely — each node is visited at\n * most once; if the graph has no terminal nodes, this method returns without\n * invoking `fn`.\n *\n * **Ordering note:** Within a single BFS level (nodes at the same depth from a\n * terminal) the visit order is not strictly guaranteed. The guarantee is only\n * that a node is visited before any of its ancestors — not that siblings at the\n * same depth are visited in a specific order relative to each other.\n *\n * The value returned by `fn` is stored in the mutable `executionContext` under\n * the node's key.\n *\n * @param fn Callback invoked for each node. Its return value is added to\n * `executionContext` keyed by the node's config key.\n * @param initialExecutionContext Optional initial context to seed the traversal.\n */\n reverseTraverse(fn: TraversalFn, initialExecutionContext: Record<string, unknown> = {}): void {\n const terminals = this.terminalNodes();\n if (terminals.length === 0) {\n return;\n }\n\n const executionContext = { ...initialExecutionContext };\n const rootKey = this._agentGraph.root;\n const visited = new Set<string>();\n let queue: AgentGraphNode[] = terminals;\n\n while (queue.length > 0) {\n const nextQueue: AgentGraphNode[] = [];\n\n queue.forEach((node) => {\n const key = node.getKey();\n if (visited.has(key)) {\n return;\n }\n visited.add(key);\n\n // Defer the root so it is always processed last\n if (key === rootKey) {\n return;\n }\n\n const result = fn(node, executionContext);\n executionContext[key] = result;\n\n this.getParentNodes(key).forEach((parent) => {\n if (!visited.has(parent.getKey())) {\n nextQueue.push(parent);\n }\n });\n });\n\n queue = nextQueue;\n }\n\n // Root is always last — only invoke if it was reached during traversal\n const root = this._nodes[rootKey];\n if (root && visited.has(rootKey)) {\n const result = fn(root, executionContext);\n executionContext[rootKey] = result;\n }\n }\n\n /**\n * Collects every unique node key referenced in the graph (root + all edge sources\n * and targets).\n */\n static collectAllKeys(graph: LDAgentGraphFlagValue): Set<string> {\n const keys = new Set<string>();\n keys.add(graph.root);\n\n if (graph.edges) {\n Object.entries(graph.edges).forEach(([sourceKey, edges]) => {\n keys.add(sourceKey);\n edges.forEach((edge) => {\n keys.add(edge.key);\n });\n });\n }\n\n return keys;\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIMetrics } from '../metrics';\nimport { LDAIMetricSummary } from '../model/types';\nimport { LDJudgeResult } from '../judge/types';\nimport { AgentGraphDefinition } from './AgentGraphDefinition';\nimport { LDGraphTracker } from './LDGraphTracker';\nimport { AgentGraphRunnerResult, LDAIGraphMetricSummary, ManagedGraphResult } from './types';\n\n/**\n * ManagedAgentGraph wraps an AgentGraphDefinition and provides a managed run()\n * method that returns ManagedGraphResult with async judge evaluations.\n *\n * The runner function is responsible for executing the graph and returning\n * an AgentGraphRunnerResult. ManagedAgentGraph builds the managed result from\n * the runner result, including LDAIGraphMetricSummary with the graphTracker's\n * resumptionToken.\n */\nexport class ManagedAgentGraph {\n constructor(\n private readonly _graphDefinition: AgentGraphDefinition,\n private readonly _logger?: LDLogger,\n ) {}\n\n /**\n * Runs the agent graph using the provided runner function and returns a ManagedGraphResult.\n *\n * The runner function receives the graph tracker and AgentGraphDefinition,\n * executes the graph, and returns an AgentGraphRunnerResult.\n *\n * run() returns before ManagedGraphResult.evaluations resolves.\n *\n * @param runner Async function that executes the graph and returns AgentGraphRunnerResult.\n * @returns ManagedGraphResult with LDAIGraphMetricSummary and evaluations promise.\n */\n async run(\n runner: (\n graphDefinition: AgentGraphDefinition,\n graphTracker: LDGraphTracker,\n ) => Promise<AgentGraphRunnerResult>,\n ): Promise<ManagedGraphResult> {\n const graphTracker = this._graphDefinition.createTracker();\n\n const runnerResult = await runner(this._graphDefinition, graphTracker);\n\n const metrics: LDAIGraphMetricSummary = {\n success: runnerResult.metrics.success,\n path: runnerResult.metrics.path,\n durationMs: runnerResult.metrics.durationMs,\n tokens: runnerResult.metrics.tokens,\n nodeMetrics: this._trackNodeMetrics(runnerResult.metrics.nodeMetrics),\n resumptionToken: graphTracker.resumptionToken,\n };\n\n const evaluations: Promise<LDJudgeResult[]> = Promise.resolve([]);\n\n return {\n content: runnerResult.content,\n metrics,\n raw: runnerResult.raw,\n evaluations,\n };\n }\n\n /**\n * Converts per-node LDAIMetrics from the runner into LDAIMetricSummary by\n * creating a per-node tracker, firing tracking events, and calling getSummary().\n */\n private _trackNodeMetrics(\n nodeMetrics: Record<string, LDAIMetrics>,\n ): Record<string, LDAIMetricSummary> {\n const summaries: Record<string, LDAIMetricSummary> = {};\n\n for (const [nodeKey, metrics] of Object.entries(nodeMetrics)) {\n const node = this._graphDefinition.getNode(nodeKey);\n if (!node) {\n this._logger?.warn(`ManagedAgentGraph: no node found for key \"${nodeKey}\", skipping metrics`);\n continue;\n }\n\n const tracker = node.getConfig().createTracker!();\n if (metrics.tokens) {\n tracker.trackTokens(metrics.tokens);\n }\n if (metrics.durationMs !== undefined) {\n tracker.trackDuration(metrics.durationMs);\n }\n if (metrics.toolCalls?.length) {\n tracker.trackToolCalls(metrics.toolCalls);\n }\n if (metrics.success) {\n tracker.trackSuccess();\n } else {\n tracker.trackError();\n }\n\n summaries[nodeKey] = tracker.getSummary();\n }\n\n return summaries;\n }\n\n /**\n * Returns the underlying AgentGraphDefinition.\n */\n getGraphDefinition(): AgentGraphDefinition {\n return this._graphDefinition;\n }\n}\n","import { Judge } from './Judge';\nimport { LDJudgeResult } from './types';\n\n/**\n * Wraps a collection of judges, providing a single `evaluate` method that\n * runs all judges against a given input/output pair.\n *\n * @internal\n */\nexport class Evaluator {\n constructor(private readonly _judges: Judge[]) {}\n\n static noop(): Evaluator {\n return new Evaluator([]);\n }\n\n async evaluate(input: string, output: string): Promise<LDJudgeResult[]> {\n if (this._judges.length === 0) {\n return [];\n }\n\n return Promise.all(this._judges.map((judge) => judge.evaluate(input, output)));\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { ChatResponse } from '../chat/types';\nimport { LDAIJudgeConfig, LDMessage } from '../config/types';\nimport { RunnerResult } from '../model/types';\nimport { Runner } from '../providers/Runner';\nimport { LDJudgeResult } from './types';\n\nconst EVALUATION_SCHEMA = {\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.',\n },\n reasoning: {\n type: 'string',\n description: 'Reasoning behind the score.',\n },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n} as const;\n\n/**\n * Remove legacy judge template messages from a message list.\n *\n * Strips any non-system message whose content contains `{{message_history}}`\n * or `{{response_to_evaluate}}`. These were used by older judge configs to\n * indicate where the SDK should interpolate the evaluated conversation; new\n * configs omit them entirely and rely on the string input built by\n * `Judge._buildEvaluationInput`.\n *\n * @param messages The raw message list from the judge AI config.\n * @returns A new list with legacy template messages removed.\n */\nexport function stripLegacyJudgeMessages(messages: LDMessage[]): LDMessage[] {\n return messages.filter(\n (msg) =>\n msg.role === 'system' ||\n (!msg.content.includes('{{message_history}}') &&\n !msg.content.includes('{{response_to_evaluate}}')),\n );\n}\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\n constructor(\n private readonly _aiConfig: LDAIJudgeConfig,\n private readonly _runner: Runner,\n private readonly _sampleRate: number = 1.0,\n logger?: LDLogger,\n ) {\n this._logger = logger;\n }\n\n /**\n * The default sampling rate baked in at construction. Used by `evaluate` /\n * `evaluateMessages` when no per-call rate is supplied.\n */\n get sampleRate(): number {\n return this._sampleRate;\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.\n * When omitted, the Judge's constructor-default rate is used. An explicit `0` overrides\n * the default — only `undefined` falls through.\n * @returns Promise that resolves to evaluation results\n */\n async evaluate(input: string, output: string, samplingRate?: number): Promise<LDJudgeResult> {\n const effectiveRate = samplingRate ?? this._sampleRate;\n const result: LDJudgeResult = {\n success: false,\n sampled: false,\n judgeConfigKey: this._aiConfig.key,\n };\n\n const tracker = this._aiConfig.createTracker!();\n try {\n const evaluationMetricKey = this._getEvaluationMetricKey();\n if (!evaluationMetricKey) {\n this._logger?.warn(\n 'Judge configuration is missing required evaluation metric key',\n tracker.getTrackData(),\n );\n result.sampled = true;\n result.errorMessage = 'Judge configuration is missing required evaluation metric key';\n return result;\n }\n\n if (Math.random() > effectiveRate) {\n this._logger?.debug(`Judge evaluation skipped due to sampling rate: ${effectiveRate}`);\n return result;\n }\n\n result.sampled = true;\n\n const evaluationInput = this._buildEvaluationInput(input, output);\n\n const response = await tracker.trackMetricsOf(\n (r: RunnerResult) => r.metrics,\n () => this._runner.run(evaluationInput, EVALUATION_SCHEMA),\n );\n\n const evalResult = this._parseEvaluationResponse(response.parsed);\n\n if (!evalResult) {\n this._logger?.warn(\n `Could not parse evaluation response: ${JSON.stringify(response.parsed)}`,\n tracker.getTrackData(),\n );\n return result;\n }\n\n return {\n ...result,\n success: response.metrics.success,\n score: evalResult.score,\n reasoning: evalResult.reasoning,\n metricKey: evaluationMetricKey,\n };\n } catch (error) {\n this._logger?.error('Judge evaluation failed:', error);\n result.sampled = true;\n result.errorMessage = error instanceof Error ? error.message : 'Unknown error';\n return result;\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). When omitted, the Judge's\n * constructor-default rate is used.\n * @returns Promise that resolves to evaluation results\n */\n async evaluateMessages(\n messages: LDMessage[],\n response: ChatResponse,\n samplingRatio?: number,\n ): Promise<LDJudgeResult> {\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 runner used by this judge.\n */\n getRunner(): Runner {\n return this._runner;\n }\n\n /**\n * Builds the evaluation input string passed to the runner.\n *\n * Combines the original prompt and the response into a single, well-known\n * format the judge model is expected to evaluate.\n */\n private _buildEvaluationInput(input: string, output: string): string {\n return `MESSAGE HISTORY:\\n${input}\\n\\nRESPONSE TO EVALUATE:\\n${output}`;\n }\n\n /**\n * Parses the structured evaluation response. Expects top-level {score, reasoning}.\n * Returns score and reasoning, or undefined if parsing fails.\n */\n private _parseEvaluationResponse(\n data: Record<string, unknown> | undefined,\n ): { score: number; reasoning: string } | undefined {\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return undefined;\n }\n\n if (typeof data.score !== 'number' || data.score < 0 || data.score > 1) {\n return undefined;\n }\n\n if (typeof data.reasoning !== 'string') {\n return undefined;\n }\n\n return {\n score: data.score,\n reasoning: data.reasoning,\n };\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport { LDAIAgentConfig, LDAICompletionConfig, LDAIJudgeConfig } from '../config/types';\nimport { AgentGraphDefinition } from '../graph/AgentGraphDefinition';\nimport { AgentGraphRunner, Runner } from './Runner';\n\n/**\n * A registry of callable tools keyed by tool name.\n * Mirrors Python's `Dict[str, Callable]` — values are typically functions\n * that the provider invokes when the model requests a tool call.\n */\nexport type ToolRegistry = Record<string, (...args: any[]) => unknown>;\n\n/**\n * Abstract base class for AI providers.\n *\n * An `AIProvider` is a per-provider factory: it is instantiated once per\n * provider package and is responsible for constructing focused runtime\n * capability objects via {@link createModel}, {@link createAgent}, and\n * {@link createAgentGraph}.\n *\n * Provider packages subclass `AIProvider` and override the methods they\n * support. The default implementations return `undefined`, mirroring Python's\n * base-class behaviour, so providers only need to implement the modes they\n * actually support.\n */\nexport abstract class AIProvider {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected _logger?: LDLogger;\n\n constructor(logger?: LDLogger) {\n this._logger = logger;\n }\n /**\n * Create a Runner for a completion or judge AI Config.\n *\n * Override in provider subclasses to return a configured {@link Runner}.\n * Default implementation returns `undefined`.\n *\n * @param config The completion or judge AI configuration.\n * @returns Promise resolving to a {@link Runner}, or `undefined` if this\n * provider does not support model creation.\n */\n async createModel(_config: LDAICompletionConfig | LDAIJudgeConfig): Promise<Runner | undefined> {\n return undefined;\n }\n\n /**\n * Create a Runner for an agent AI Config.\n *\n * Override in provider subclasses to return a configured {@link Runner}.\n * Default implementation returns `undefined`.\n *\n * @param config The agent AI configuration.\n * @param tools Optional registry of callable tools.\n * @returns Promise resolving to a {@link Runner}, or `undefined` if this\n * provider does not support agent creation.\n */\n async createAgent(_config: LDAIAgentConfig, _tools?: ToolRegistry): Promise<Runner | undefined> {\n return undefined;\n }\n\n /**\n * Create an AgentGraphRunner for an agent graph definition.\n *\n * Override in provider subclasses to return a configured {@link AgentGraphRunner}.\n * Default implementation returns `undefined`.\n *\n * @param graphDef The agent graph definition.\n * @param tools Optional registry of callable tools.\n * @returns Promise resolving to an {@link AgentGraphRunner}, or `undefined` if\n * this provider does not support graph execution.\n */\n async createAgentGraph(\n _graphDef: AgentGraphDefinition,\n _tools?: ToolRegistry,\n ): Promise<AgentGraphRunner | undefined> {\n return undefined;\n }\n}\n","import { LDLogger } from '@launchdarkly/js-server-sdk-common';\n\nimport {\n LDAIAgentConfig,\n LDAICompletionConfig,\n LDAIJudgeConfig,\n} from '../config/types';\nimport { AgentGraphDefinition } from '../graph/AgentGraphDefinition';\nimport { AIProvider, ToolRegistry } from './AIProvider';\nimport { AgentGraphRunner, Runner } from './Runner';\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 * Sole entry point for runner creation.\n *\n * RunnerFactory is the single factory for creating {@link Runner} and\n * {@link AgentGraphRunner} instances. It mirrors the Python RunnerFactory\n * pattern: it knows about supported provider packages, loads them dynamically\n * via {@link _getProviderFactory}, and delegates creation to the factory\n * instance methods on {@link AIProvider}.\n *\n * Provider packages subclass {@link AIProvider} and override its factory\n * methods (`createModel`, `createAgent`, `createAgentGraph`).\n */\nexport class RunnerFactory {\n /**\n * Load and return the AIProvider factory for the given provider type.\n *\n * This is the single place in the codebase that knows provider package names.\n * Each supported provider package exports a `*RunnerFactory` class that\n * extends {@link AIProvider}; this method instantiates it directly.\n *\n * @param providerType One of the {@link SUPPORTED_AI_PROVIDERS} values.\n * @param logger Optional logger forwarded to the provider factory.\n * @returns A configured {@link AIProvider} instance, or `undefined` if the\n * package cannot be loaded.\n */\n private static async _getProviderFactory(\n providerType: SupportedAIProvider,\n logger?: LDLogger,\n ): Promise<AIProvider | undefined> {\n try {\n let module: any;\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 return new module.OpenAIRunnerFactory(logger) as AIProvider;\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 return new module.LangChainRunnerFactory(logger) as AIProvider;\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 return new module.VercelRunnerFactory(logger) as AIProvider;\n }\n default:\n return undefined;\n }\n } catch (error: any) {\n logger?.warn(\n `Unable to load provider package. Check that you have installed the correct package. ${error.message}`,\n );\n return undefined;\n }\n }\n\n /**\n * Determine which providers to try based on defaultAiProvider and providerName.\n *\n * Mirrors Python's `_get_providers_to_try` helper.\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 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 as fallback, avoiding 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 each provider in order and return the first non-undefined result.\n *\n * Mirrors Python's `_with_fallback` helper. Loads each provider factory via\n * {@link _getProviderFactory} and calls `fn` with it. Returns the first\n * truthy result, or `undefined` if no provider succeeds.\n *\n * @param providers Ordered list of provider types to try.\n * @param fn Callback that calls the appropriate factory method on the provider.\n * @param logger Optional logger forwarded to each provider factory.\n */\n private static async _withFallback<T>(\n providers: SupportedAIProvider[],\n fn: (factory: AIProvider) => Promise<T | undefined>,\n logger?: LDLogger,\n ): Promise<T | undefined> {\n for (const providerType of providers) {\n logger?.debug(`Attempting to create runner with provider: ${providerType}`);\n // eslint-disable-next-line no-await-in-loop, no-underscore-dangle\n const factory = await RunnerFactory._getProviderFactory(providerType, logger);\n if (factory) {\n // eslint-disable-next-line no-await-in-loop\n const result = await fn(factory);\n if (result) {\n logger?.debug(`Successfully created runner with provider: ${providerType}`);\n return result;\n }\n }\n }\n return undefined;\n }\n\n /**\n * Create a Runner for the given AI configuration.\n *\n * Suitable for completion, judge, and agent config modes. Dynamically\n * loads the matching provider package via {@link _getProviderFactory} and\n * delegates to its {@link AIProvider.createModel} method.\n *\n * @param config The AI configuration (completion, agent, or judge).\n * @param logger Optional logger forwarded to the underlying provider.\n * @param defaultAiProvider Optional provider override\n * ('openai', 'langchain', 'vercel', …). When set, only that provider is\n * tried. When omitted, providers are tried in priority order based on the\n * provider name in the config.\n * @returns A configured {@link Runner} ready to invoke the model, or\n * `undefined` if no suitable provider could be loaded.\n */\n static async createModel(\n config: LDAICompletionConfig | LDAIJudgeConfig,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Runner | undefined> {\n const providerName = config.provider?.name?.toLowerCase();\n // eslint-disable-next-line no-underscore-dangle\n const providers = RunnerFactory._getProvidersToTry(defaultAiProvider, providerName);\n\n // eslint-disable-next-line no-underscore-dangle\n const runner = await RunnerFactory._withFallback(\n providers,\n (factory) => factory.createModel(config),\n logger,\n );\n\n if (!runner) {\n logger?.warn(\n `Provider is not supported or failed to initialize: ${config.provider?.name ?? 'unknown'}`,\n );\n }\n\n return runner;\n }\n\n /**\n * Create a Runner for an agent AI Config.\n *\n * Delegates to the provider factory's {@link AIProvider.createAgent} method.\n *\n * @param config The agent AI configuration.\n * @param tools Optional registry of callable tools.\n * @param logger Optional logger forwarded to the underlying provider.\n * @param defaultAiProvider Optional provider override.\n * @returns A configured {@link Runner}, or `undefined` if no suitable\n * provider could be loaded.\n */\n static async createAgent(\n config: LDAIAgentConfig,\n tools?: ToolRegistry,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<Runner | undefined> {\n const providerName = config.provider?.name?.toLowerCase();\n // eslint-disable-next-line no-underscore-dangle\n const providers = RunnerFactory._getProvidersToTry(defaultAiProvider, providerName);\n\n // eslint-disable-next-line no-underscore-dangle\n const runner = await RunnerFactory._withFallback(\n providers,\n (factory) => factory.createAgent(config, tools),\n logger,\n );\n\n if (!runner) {\n logger?.warn(\n `Provider is not supported or failed to initialize: ${config.provider?.name ?? 'unknown'}`,\n );\n }\n\n return runner;\n }\n\n /**\n * Create an AgentGraphRunner for the given agent graph definition.\n *\n * Delegates to the provider factory's {@link AIProvider.createAgentGraph} method.\n *\n * @param graphDef The agent graph definition.\n * @param tools Optional registry of callable tools.\n * @param logger Optional logger forwarded to the underlying provider.\n * @param defaultAiProvider Optional provider override.\n * @returns A configured {@link AgentGraphRunner}, or `undefined` if no\n * suitable provider could be loaded.\n */\n static async createAgentGraph(\n graphDef: AgentGraphDefinition,\n tools?: ToolRegistry,\n logger?: LDLogger,\n defaultAiProvider?: SupportedAIProvider,\n ): Promise<AgentGraphRunner | undefined> {\n // AgentGraph does not have a per-node provider name at this level;\n // fall back to all multi-provider packages unless overridden.\n // eslint-disable-next-line no-underscore-dangle\n const providers = RunnerFactory._getProvidersToTry(defaultAiProvider);\n\n // eslint-disable-next-line no-underscore-dangle\n const runner = await RunnerFactory._withFallback(\n providers,\n (factory) => factory.createAgentGraph(graphDef, tools),\n logger,\n );\n\n if (!runner) {\n logger?.warn(`No provider could create an AgentGraphRunner for the given graph definition.`);\n }\n\n return runner;\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/model/types';\nimport { LDJudgeResult } 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 _runId: string,\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 private _graphKey?: string,\n ) {\n this._trackedMetrics.resumptionToken = this.resumptionToken;\n }\n\n getTrackData(): {\n runId: string;\n configKey: string;\n variationKey: string;\n version: number;\n modelName: string;\n providerName: string;\n graphKey?: string;\n } {\n return {\n runId: this._runId,\n configKey: this._configKey,\n variationKey: this._variationKey,\n version: this._version,\n modelName: this._modelName,\n providerName: this._providerName,\n ...(this._graphKey !== undefined ? { graphKey: this._graphKey } : {}),\n };\n }\n\n get resumptionToken(): string {\n const json = JSON.stringify({\n runId: this._runId,\n configKey: this._configKey,\n variationKey: this._variationKey,\n version: this._version,\n ...(this._graphKey !== undefined ? { graphKey: this._graphKey } : {}),\n });\n return Buffer.from(json).toString('base64url');\n }\n\n static fromResumptionToken(\n token: string,\n ldClient: LDClientMin,\n context: LDContext,\n ): LDAIConfigTrackerImpl {\n const json = Buffer.from(token, 'base64url').toString('utf8');\n const payload = JSON.parse(json);\n return new LDAIConfigTrackerImpl(\n ldClient,\n payload.runId,\n payload.configKey,\n payload.variationKey ?? '',\n payload.version,\n '',\n '',\n context,\n payload.graphKey,\n );\n }\n\n trackDuration(duration: number): void {\n if (this._trackedMetrics.durationMs !== undefined) {\n this._ldClient.logger?.warn(\n 'Duration has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 if (this._trackedMetrics.timeToFirstTokenMs !== undefined) {\n this._ldClient.logger?.warn(\n 'Time to first token has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 trackJudgeResult(result: LDJudgeResult) {\n if (!result.sampled || !result.success) {\n return;\n }\n if (result.metricKey !== undefined && result.score !== undefined) {\n const trackData = result.judgeConfigKey\n ? { ...this.getTrackData(), judgeConfigKey: result.judgeConfigKey }\n : this.getTrackData();\n this._ldClient.track(result.metricKey, this._context, trackData, result.score);\n }\n }\n\n trackToolCall(toolKey: string): void {\n if (!this._trackedMetrics.toolCalls) {\n this._trackedMetrics.toolCalls = [];\n }\n this._trackedMetrics.toolCalls.push(toolKey);\n this._ldClient.track('$ld:ai:tool_call', this._context, { ...this.getTrackData(), toolKey }, 1);\n }\n\n trackToolCalls(toolKeys: string[]): void {\n toolKeys.forEach((toolKey) => {\n this.trackToolCall(toolKey);\n });\n }\n\n trackFeedback(feedback: { kind: LDFeedbackKind }): void {\n if (this._trackedMetrics.feedback !== undefined) {\n this._ldClient.logger?.warn(\n 'Feedback has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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 if (this._trackedMetrics.success !== undefined) {\n this._ldClient.logger?.warn(\n 'Generation result has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\n this._trackedMetrics.success = true;\n this._ldClient.track('$ld:ai:generation:success', this._context, this.getTrackData(), 1);\n }\n\n trackError(): void {\n if (this._trackedMetrics.success !== undefined) {\n this._ldClient.logger?.warn(\n 'Generation result has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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.tokens) {\n this.trackTokens(metrics.tokens);\n }\n\n // Track tool calls if available\n if (metrics.toolCalls?.length) {\n this.trackToolCalls(metrics.toolCalls);\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.tokens) {\n this.trackTokens(metrics.tokens);\n }\n\n // Track tool calls if available\n if (metrics.toolCalls?.length) {\n this.trackToolCalls(metrics.toolCalls);\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 if (this._trackedMetrics.tokens !== undefined) {\n this._ldClient.logger?.warn(\n 'Token usage has already been tracked for this execution. Use createTracker() for a new execution.',\n );\n return;\n }\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","import type { LDContext } from '@launchdarkly/js-server-sdk-common';\n\nimport type { LDGraphTracker } from './api/graph/LDGraphTracker';\nimport type { LDAIGraphMetricSummary } from './api/graph/types';\nimport type { LDTokenUsage } from './api/metrics';\nimport type { LDClientMin } from './LDClientMin';\n\n/**\n * Concrete implementation of {@link LDGraphTracker}.\n *\n * Construct directly or reconstruct from a resumption token via\n * {@link LDGraphTrackerImpl.fromResumptionToken}.\n */\nexport class LDGraphTrackerImpl implements LDGraphTracker {\n private _summary: Partial<LDAIGraphMetricSummary> = {};\n\n constructor(\n private readonly _ldClient: LDClientMin,\n private readonly _runId: string,\n private readonly _graphKey: string,\n private readonly _variationKey: string | undefined,\n private readonly _version: number,\n private readonly _context: LDContext,\n ) {\n this._summary.resumptionToken = this.resumptionToken;\n }\n\n /**\n * Reconstructs an {@link LDGraphTrackerImpl} from a resumption token, preserving\n * the original `runId` so all events continue to be correlated under the same run.\n *\n * **Security note:** The token contains the flag variation key and version.\n * Do not pass the raw token to untrusted clients.\n *\n * @param token URL-safe Base64-encoded token produced by {@link LDGraphTrackerImpl.resumptionToken}.\n * @param ldClient LaunchDarkly client instance.\n * @param context LDContext for the new tracker.\n */\n static fromResumptionToken(\n token: string,\n ldClient: LDClientMin,\n context: LDContext,\n ): LDGraphTrackerImpl {\n const json = Buffer.from(token, 'base64url').toString('utf8');\n const data = JSON.parse(json);\n return new LDGraphTrackerImpl(\n ldClient,\n data.runId,\n data.graphKey,\n data.variationKey,\n data.version,\n context,\n );\n }\n\n getTrackData(): {\n runId: string;\n graphKey: string;\n variationKey?: string;\n version: number;\n } {\n return {\n runId: this._runId,\n graphKey: this._graphKey,\n version: this._version,\n ...(this._variationKey !== undefined ? { variationKey: this._variationKey } : {}),\n };\n }\n\n getSummary(): Partial<LDAIGraphMetricSummary> {\n return { ...this._summary };\n }\n\n get resumptionToken(): string {\n // Keys must appear in exact spec-defined order:\n // runId, graphKey, variationKey (omitted if absent), version\n const parts: string[] = [\n `\"runId\":${JSON.stringify(this._runId)}`,\n `\"graphKey\":${JSON.stringify(this._graphKey)}`,\n ];\n if (this._variationKey !== undefined) {\n parts.push(`\"variationKey\":${JSON.stringify(this._variationKey)}`);\n }\n parts.push(`\"version\":${this._version}`);\n const json = `{${parts.join(',')}}`;\n return Buffer.from(json).toString('base64url');\n }\n\n trackInvocationSuccess(): void {\n if (this._summary.success !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: invocation success/failure already recorded for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.success = true;\n this._ldClient.track('$ld:ai:graph:invocation_success', this._context, this.getTrackData(), 1);\n }\n\n trackInvocationFailure(): void {\n if (this._summary.success !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: invocation success/failure already recorded for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.success = false;\n this._ldClient.track('$ld:ai:graph:invocation_failure', this._context, this.getTrackData(), 1);\n }\n\n trackDuration(durationMs: number): void {\n if (this._summary.durationMs !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackDuration already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.durationMs = durationMs;\n this._ldClient.track(\n '$ld:ai:graph:duration:total',\n this._context,\n this.getTrackData(),\n durationMs,\n );\n }\n\n trackTotalTokens(tokens: LDTokenUsage): void {\n if (this._summary.tokens !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackTotalTokens already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.tokens = { ...tokens };\n this._ldClient.track(\n '$ld:ai:graph:total_tokens',\n this._context,\n this.getTrackData(),\n tokens.total,\n );\n }\n\n trackPath(path: string[]): void {\n if (this._summary.path !== undefined) {\n this._ldClient.logger?.warn(\n 'LDGraphTracker: trackPath already called for this run — dropping duplicate call.',\n );\n return;\n }\n this._summary.path = [...path];\n this._ldClient.track('$ld:ai:graph:path', this._context, { ...this.getTrackData(), path }, 1);\n }\n\n trackRedirect(sourceKey: string, redirectedTarget: string): void {\n this._ldClient.track(\n '$ld:ai:graph:redirect',\n this._context,\n { ...this.getTrackData(), sourceKey, redirectedTarget },\n 1,\n );\n }\n\n trackHandoffSuccess(sourceKey: string, targetKey: string): void {\n this._ldClient.track(\n '$ld:ai:graph:handoff_success',\n this._context,\n { ...this.getTrackData(), sourceKey, targetKey },\n 1,\n );\n }\n\n trackHandoffFailure(sourceKey: string, targetKey: string): void {\n this._ldClient.track(\n '$ld:ai:graph:handoff_failure',\n this._context,\n { ...this.getTrackData(), sourceKey, targetKey },\n 1,\n );\n }\n}\n","export const aiSdkName = '@launchdarkly/server-sdk-ai';\nexport const aiSdkVersion = '0.20.0'; // x-release-please-version\nexport const aiSdkLanguage = 'javascript';\n"],"mappings":"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","names":["module","LDFeedbackKind","Mustache"]}
|