@langfuse/client 4.0.0-alpha.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/LangfuseClient.ts","../src/dataset/index.ts","../src/media/index.ts","../src/prompt/promptManager.ts","../src/prompt/promptCache.ts","../src/prompt/promptClients.ts","../src/prompt/types.ts","../src/score/index.ts"],"sourcesContent":["import {\n LangfuseAPIClient,\n LANGFUSE_SDK_VERSION,\n getGlobalLogger,\n getEnv,\n} from \"@langfuse/core\";\n\nimport { DatasetManager } from \"./dataset/index.js\";\nimport { MediaManager } from \"./media/index.js\";\nimport { PromptManager } from \"./prompt/index.js\";\nimport { ScoreManager } from \"./score/index.js\";\n\nexport interface LangfuseClientParams {\n publicKey?: string;\n secretKey?: string;\n baseUrl?: string;\n timeout?: number;\n additionalHeaders?: Record<string, string>;\n}\n\nexport class LangfuseClient {\n public api: LangfuseAPIClient;\n public prompt: PromptManager;\n public dataset: DatasetManager;\n public score: ScoreManager;\n public media: MediaManager;\n\n private baseUrl: string;\n private projectId: string | null = null;\n\n /**\n * @deprecated Use prompt.get instead\n */\n public getPrompt: typeof PromptManager.prototype.get;\n /**\n * @deprecated Use prompt.create instead\n */\n public createPrompt: typeof PromptManager.prototype.create;\n /**\n * @deprecated Use prompt.update instead\n */\n public updatePrompt: typeof PromptManager.prototype.update;\n /**\n * @deprecated Use dataset.get instead\n */\n public getDataset: typeof DatasetManager.prototype.get;\n /**\n * @deprecated Use api.trace.get instead\n */\n public fetchTrace: typeof LangfuseAPIClient.prototype.trace.get;\n /**\n * @deprecated Use api.trace.list instead\n */\n public fetchTraces: typeof LangfuseAPIClient.prototype.trace.list;\n /**\n * @deprecated Use api.observations.get instead\n */\n public fetchObservation: typeof LangfuseAPIClient.prototype.observations.get;\n /**\n * @deprecated Use api.observations.list instead\n */\n public fetchObservations: typeof LangfuseAPIClient.prototype.observations.getMany;\n /**\n * @deprecated Use api.sessions.get instead\n */\n public fetchSessions: typeof LangfuseAPIClient.prototype.sessions.get;\n /**\n * @deprecated Use api.datasets.getRun instead\n */\n public getDatasetRun: typeof LangfuseAPIClient.prototype.datasets.getRun;\n /**\n * @deprecated Use api.datasets.getRuns instead\n */\n public getDatasetRuns: typeof LangfuseAPIClient.prototype.datasets.getRuns;\n /**\n * @deprecated Use api.datasets.create instead\n */\n public createDataset: typeof LangfuseAPIClient.prototype.datasets.create;\n /**\n * @deprecated Use api.datasetItems.get instead\n */\n public getDatasetItem: typeof LangfuseAPIClient.prototype.datasetItems.get;\n /**\n * @deprecated Use api.datasetItems.create instead\n */\n public createDatasetItem: typeof LangfuseAPIClient.prototype.datasetItems.create;\n /**\n * @deprecated Use api.media.get instead\n */\n public fetchMedia: typeof LangfuseAPIClient.prototype.media.get;\n /**\n * @deprecated Use media.resolveReferences instead\n */\n public resolveMediaReferences: typeof MediaManager.prototype.resolveReferences;\n\n constructor(params?: LangfuseClientParams) {\n const logger = getGlobalLogger();\n\n const publicKey = params?.publicKey ?? getEnv(\"LANGFUSE_PUBLIC_KEY\");\n const secretKey = params?.secretKey ?? getEnv(\"LANGFUSE_SECRET_KEY\");\n this.baseUrl =\n params?.baseUrl ??\n getEnv(\"LANGFUSE_BASE_URL\") ??\n getEnv(\"LANGFUSE_BASEURL\") ?? // legacy v2\n \"https://cloud.langfuse.com\";\n\n if (!publicKey) {\n logger.warn(\n \"No public key provided in constructor or as LANGFUSE_PUBLIC_KEY env var. Client operations will fail.\",\n );\n }\n if (!secretKey) {\n logger.warn(\n \"No secret key provided in constructor or as LANGFUSE_SECRET_KEY env var. Client operations will fail.\",\n );\n }\n const timeoutSeconds =\n params?.timeout ?? Number(getEnv(\"LANGFUSE_TIMEOUT\") ?? 5);\n\n this.api = new LangfuseAPIClient({\n baseUrl: this.baseUrl,\n username: publicKey,\n password: secretKey,\n xLangfusePublicKey: publicKey,\n xLangfuseSdkVersion: LANGFUSE_SDK_VERSION,\n xLangfuseSdkName: \"javascript\",\n environment: \"\", // noop as baseUrl is set\n headers: params?.additionalHeaders,\n });\n\n logger.debug(\"Initialized LangfuseClient with params:\", {\n publicKey,\n baseUrl: this.baseUrl,\n timeoutSeconds,\n });\n\n this.prompt = new PromptManager({ apiClient: this.api });\n this.dataset = new DatasetManager({ apiClient: this.api });\n this.score = new ScoreManager({ apiClient: this.api });\n this.media = new MediaManager({ apiClient: this.api });\n\n // Keep v3 compat by exposing old interface\n this.getPrompt = this.prompt.get.bind(this.prompt); // keep correct this context for cache access\n this.createPrompt = this.prompt.create.bind(this.prompt);\n this.updatePrompt = this.prompt.update.bind(this.prompt);\n this.getDataset = this.dataset.get;\n this.fetchTrace = this.api.trace.get;\n this.fetchTraces = this.api.trace.list;\n this.fetchObservation = this.api.observations.get;\n this.fetchObservations = this.api.observations.getMany;\n this.fetchSessions = this.api.sessions.get;\n this.getDatasetRun = this.api.datasets.getRun;\n this.getDatasetRuns = this.api.datasets.getRuns;\n this.createDataset = this.api.datasets.create;\n this.getDatasetItem = this.api.datasetItems.get;\n this.createDatasetItem = this.api.datasetItems.create;\n this.fetchMedia = this.api.media.get;\n this.resolveMediaReferences = this.media.resolveReferences;\n }\n\n public async flush() {\n return this.score.flush();\n }\n\n public async shutdown() {\n return this.score.shutdown();\n }\n\n public async getTraceUrl(traceId: string) {\n let projectId = this.projectId;\n\n if (!projectId) {\n projectId = (await this.api.projects.get()).data[0].id;\n this.projectId = projectId;\n }\n\n const traceUrl = `${this.baseUrl}/project/${projectId}/traces/${traceId}`;\n\n return traceUrl;\n }\n}\n","import {\n LangfuseAPIClient,\n Dataset,\n DatasetRunItem,\n DatasetItem,\n} from \"@langfuse/core\";\nimport { Span } from \"@opentelemetry/api\";\n\nexport type LinkDatasetItemFunction = (\n obj: { otelSpan: Span },\n runName: string,\n runArgs?: {\n description?: string;\n metadata?: any;\n },\n) => Promise<DatasetRunItem>;\n\nexport class DatasetManager {\n private apiClient: LangfuseAPIClient;\n\n constructor(params: { apiClient: LangfuseAPIClient }) {\n this.apiClient = params.apiClient;\n }\n\n async get(\n name: string,\n options?: {\n fetchItemsPageSize: number;\n },\n ): Promise<\n Dataset & {\n items: (DatasetItem & { link: LinkDatasetItemFunction })[];\n }\n > {\n const dataset = await this.apiClient.datasets.get(name);\n const items: DatasetItem[] = [];\n\n let page = 1;\n\n while (true) {\n const itemsResponse = await this.apiClient.datasetItems.list({\n datasetName: name,\n limit: options?.fetchItemsPageSize ?? 50,\n page,\n });\n\n items.push(...itemsResponse.data);\n\n if (itemsResponse.meta.totalPages <= page) {\n break;\n }\n\n page++;\n }\n\n const returnDataset = {\n ...dataset,\n items: items.map((item) => ({\n ...item,\n link: this.createDatasetItemLinkFunction(item),\n })),\n };\n\n return returnDataset;\n }\n\n private createDatasetItemLinkFunction(\n item: DatasetItem,\n ): LinkDatasetItemFunction {\n const linkFunction = async (\n obj: { otelSpan: Span },\n runName: string,\n runArgs?: {\n description?: string;\n metadata?: any;\n },\n ): Promise<DatasetRunItem> => {\n return await this.apiClient.datasetRunItems.create({\n runName,\n datasetItemId: item.id,\n traceId: obj.otelSpan.spanContext().traceId,\n runDescription: runArgs?.description,\n metadata: runArgs?.metadata,\n });\n };\n\n return linkFunction;\n }\n}\n","import {\n LangfuseAPIClient,\n ParsedMediaReference,\n MediaContentType,\n getGlobalLogger,\n uint8ArrayToBase64,\n} from \"@langfuse/core\";\n\nexport type LangfuseMediaResolveMediaReferencesParams<T> = {\n obj: T;\n resolveWith: \"base64DataUri\";\n maxDepth?: number;\n};\n\nexport class MediaManager {\n private apiClient: LangfuseAPIClient;\n\n constructor(params: { apiClient: LangfuseAPIClient }) {\n this.apiClient = params.apiClient;\n }\n\n /**\n * Replaces the media reference strings in an object with base64 data URIs for the media content.\n *\n * This method recursively traverses an object (up to a maximum depth of 10) looking for media reference strings\n * in the format \"@@@langfuseMedia:...@@@\". When found, it fetches the actual media content using the provided\n * Langfuse client and replaces the reference string with a base64 data URI.\n *\n * If fetching media content fails for a reference string, a warning is logged and the reference string is left unchanged.\n *\n * @param params - Configuration object\n * @param params.obj - The object to process. Can be a primitive value, array, or nested object\n * @param params.resolveWith - The representation of the media content to replace the media reference string with. Currently only \"base64DataUri\" is supported.\n * @param params.maxDepth - Optional. Default is 10. The maximum depth to traverse the object.\n *\n * @returns A deep copy of the input object with all media references replaced with base64 data URIs where possible\n *\n * @example\n * ```typescript\n * const obj = {\n * image: \"@@@langfuseMedia:type=image/jpeg|id=123|source=bytes@@@\",\n * nested: {\n * pdf: \"@@@langfuseMedia:type=application/pdf|id=456|source=bytes@@@\"\n * }\n * };\n *\n * const result = await LangfuseMedia.resolveMediaReferences({\n * obj,\n * langfuseClient\n * });\n *\n * // Result:\n * // {\n * // image: \"data:image/jpeg;base64,/9j/4AAQSkZJRg...\",\n * // nested: {\n * // pdf: \"data:application/pdf;base64,JVBERi0xLjcK...\"\n * // }\n * // }\n * ```\n */\n public async resolveReferences<T>(\n params: LangfuseMediaResolveMediaReferencesParams<T>,\n ): Promise<T> {\n const { obj, maxDepth = 10 } = params;\n\n const traverse = async <T>(obj: T, depth: number): Promise<T> => {\n if (depth > maxDepth) {\n return obj;\n }\n\n // Handle string with potential media references\n if (typeof obj === \"string\") {\n const regex = /@@@langfuseMedia:.+?@@@/g;\n const referenceStringMatches = obj.match(regex);\n if (!referenceStringMatches) {\n return obj;\n }\n\n let result = obj;\n const referenceStringToMediaContentMap = new Map<string, string>();\n\n await Promise.all(\n referenceStringMatches.map(async (referenceString) => {\n try {\n const parsedMediaReference =\n MediaManager.parseReferenceString(referenceString);\n const mediaData = await this.apiClient.media.get(\n parsedMediaReference.mediaId,\n );\n const mediaContent = await fetch(mediaData.url, {\n method: \"GET\",\n headers: {},\n });\n if (mediaContent.status !== 200) {\n throw new Error(\"Failed to fetch media content\");\n }\n\n const uint8Content = new Uint8Array(\n await mediaContent.arrayBuffer(),\n );\n\n const base64MediaContent = uint8ArrayToBase64(uint8Content);\n const base64DataUri = `data:${mediaData.contentType};base64,${base64MediaContent}`;\n\n referenceStringToMediaContentMap.set(\n referenceString,\n base64DataUri,\n );\n } catch (error) {\n getGlobalLogger().warn(\n \"Error fetching media content for reference string\",\n referenceString,\n error,\n );\n }\n }),\n );\n\n for (const [\n referenceString,\n base64MediaContent,\n ] of referenceStringToMediaContentMap.entries()) {\n result = result.replaceAll(referenceString, base64MediaContent) as T &\n string;\n }\n\n return result;\n }\n\n // Handle arrays\n if (Array.isArray(obj)) {\n return Promise.all(\n obj.map(async (item) => await traverse(item, depth + 1)),\n ) as Promise<T>;\n }\n\n // Handle objects\n if (typeof obj === \"object\" && obj !== null) {\n return Object.fromEntries(\n await Promise.all(\n Object.entries(obj).map(async ([key, value]) => [\n key,\n await traverse(value, depth + 1),\n ]),\n ),\n );\n }\n\n return obj;\n };\n\n return traverse(obj, 0);\n }\n\n /**\n * Parses a media reference string into a ParsedMediaReference.\n *\n * Example reference string:\n * \"@@@langfuseMedia:type=image/jpeg|id=some-uuid|source=base64DataUri@@@\"\n *\n * @param referenceString - The reference string to parse.\n * @returns An object with the mediaId, source, and contentType.\n *\n * @throws Error if the reference string is invalid or missing required fields.\n */\n public static parseReferenceString(\n referenceString: string,\n ): ParsedMediaReference {\n const prefix = \"@@@langfuseMedia:\";\n const suffix = \"@@@\";\n\n if (!referenceString.startsWith(prefix)) {\n throw new Error(\n \"Reference string does not start with '@@@langfuseMedia:type='\",\n );\n }\n\n if (!referenceString.endsWith(suffix)) {\n throw new Error(\"Reference string does not end with '@@@'\");\n }\n\n const content = referenceString.slice(prefix.length, -suffix.length);\n\n const pairs = content.split(\"|\");\n const parsedData: { [key: string]: string } = {};\n\n for (const pair of pairs) {\n const [key, value] = pair.split(\"=\", 2);\n parsedData[key] = value;\n }\n\n if (\n !(\"type\" in parsedData && \"id\" in parsedData && \"source\" in parsedData)\n ) {\n throw new Error(\"Missing required fields in reference string\");\n }\n\n return {\n mediaId: parsedData[\"id\"],\n source: parsedData[\"source\"],\n contentType: parsedData[\"type\"] as MediaContentType,\n };\n }\n}\n","import {\n CreatePromptRequest,\n getGlobalLogger,\n LangfuseAPIClient,\n PlaceholderMessage,\n Prompt,\n ChatMessage,\n} from \"@langfuse/core\";\n\nimport { LangfusePromptCache } from \"./promptCache.js\";\nimport {\n ChatPromptClient,\n TextPromptClient,\n LangfusePromptClient,\n} from \"./promptClients.js\";\nimport {\n ChatMessageType,\n CreateChatPromptBodyWithPlaceholders,\n} from \"./types.js\";\n\nexport class PromptManager {\n private cache: LangfusePromptCache;\n private apiClient: LangfuseAPIClient;\n\n constructor(params: { apiClient: LangfuseAPIClient }) {\n const { apiClient } = params;\n\n this.apiClient = apiClient;\n this.cache = new LangfusePromptCache();\n }\n\n get logger() {\n return getGlobalLogger();\n }\n\n async create(\n body: CreateChatPromptBodyWithPlaceholders,\n ): Promise<ChatPromptClient>;\n async create(\n body: Omit<CreatePromptRequest.Text, \"type\"> & { type?: \"text\" },\n ): Promise<TextPromptClient>;\n async create(body: CreatePromptRequest.Chat): Promise<ChatPromptClient>;\n async create(\n body:\n | CreatePromptRequest.Chat\n | (Omit<CreatePromptRequest.Text, \"type\"> & { type?: \"text\" })\n | CreateChatPromptBodyWithPlaceholders,\n ): Promise<LangfusePromptClient> {\n const requestBody: CreatePromptRequest =\n body.type === \"chat\"\n ? {\n ...body,\n prompt: body.prompt.map((item) => {\n if (\"type\" in item && item.type === ChatMessageType.Placeholder) {\n return {\n type: ChatMessageType.Placeholder,\n name: (item as PlaceholderMessage).name,\n };\n } else {\n // Handle regular ChatMessage (without type field) from API\n return { type: ChatMessageType.ChatMessage, ...item };\n }\n }),\n }\n : {\n ...body,\n type: body.type ?? \"text\",\n };\n\n const promptResponse = await this.apiClient.prompts.create(requestBody);\n\n if (promptResponse.type === \"chat\") {\n return new ChatPromptClient(promptResponse);\n }\n\n return new TextPromptClient(promptResponse);\n }\n\n async update(params: {\n name: string;\n version: number;\n newLabels: string[];\n }): Promise<Prompt> {\n const { name, version, newLabels } = params;\n\n const newPrompt = await this.apiClient.promptVersion.update(name, version, {\n newLabels,\n });\n\n this.cache.invalidate(name);\n\n return newPrompt;\n }\n\n async get(\n name: string,\n options?: {\n version?: number;\n label?: string;\n cacheTtlSeconds?: number;\n fallback?: string;\n maxRetries?: number;\n type?: \"text\";\n fetchTimeoutMs?: number;\n },\n ): Promise<TextPromptClient>;\n async get(\n name: string,\n options?: {\n version?: number;\n label?: string;\n cacheTtlSeconds?: number;\n fallback?: ChatMessage[];\n maxRetries?: number;\n type: \"chat\";\n fetchTimeoutMs?: number;\n },\n ): Promise<ChatPromptClient>;\n async get(\n name: string,\n options?: {\n version?: number;\n label?: string;\n cacheTtlSeconds?: number;\n fallback?: ChatMessage[] | string;\n maxRetries?: number;\n type?: \"chat\" | \"text\";\n fetchTimeoutMs?: number;\n },\n ): Promise<LangfusePromptClient> {\n const cacheKey = this.cache.createKey({\n name,\n label: options?.label,\n });\n const cachedPrompt = this.cache.getIncludingExpired(cacheKey);\n if (!cachedPrompt || options?.cacheTtlSeconds === 0) {\n try {\n return await this.fetchPromptAndUpdateCache({\n name,\n version: options?.version,\n label: options?.label,\n cacheTtlSeconds: options?.cacheTtlSeconds,\n maxRetries: options?.maxRetries,\n fetchTimeoutMs: options?.fetchTimeoutMs,\n });\n } catch (err) {\n if (options?.fallback) {\n const sharedFallbackParams = {\n name,\n version: options?.version ?? 0,\n labels: options.label ? [options.label] : [],\n cacheTtlSeconds: options?.cacheTtlSeconds,\n config: {},\n tags: [],\n };\n\n if (options.type === \"chat\") {\n return new ChatPromptClient(\n {\n ...sharedFallbackParams,\n type: \"chat\",\n prompt: (options.fallback as ChatMessage[]).map((msg) => ({\n type: ChatMessageType.ChatMessage,\n ...msg,\n })),\n },\n true,\n );\n } else {\n return new TextPromptClient(\n {\n ...sharedFallbackParams,\n type: \"text\",\n prompt: options.fallback as string,\n },\n true,\n );\n }\n }\n\n throw err;\n }\n }\n\n if (cachedPrompt.isExpired) {\n // If the cache is not currently being refreshed, start refreshing it and register the promise in the cache\n if (!this.cache.isRefreshing(cacheKey)) {\n const refreshPromptPromise = this.fetchPromptAndUpdateCache({\n name,\n version: options?.version,\n label: options?.label,\n cacheTtlSeconds: options?.cacheTtlSeconds,\n maxRetries: options?.maxRetries,\n fetchTimeoutMs: options?.fetchTimeoutMs,\n }).catch(() => {\n this.logger.warn(\n `Failed to refresh prompt cache '${cacheKey}', stale cache will be used until next refresh succeeds.`,\n );\n });\n this.cache.addRefreshingPromise(cacheKey, refreshPromptPromise);\n }\n\n return cachedPrompt.value;\n }\n\n return cachedPrompt.value;\n }\n\n private async fetchPromptAndUpdateCache(params: {\n name: string;\n version?: number;\n cacheTtlSeconds?: number;\n label?: string;\n maxRetries?: number;\n fetchTimeoutMs?: number;\n }): Promise<LangfusePromptClient> {\n const cacheKey = this.cache.createKey(params);\n\n try {\n const {\n name,\n version,\n cacheTtlSeconds,\n label,\n maxRetries,\n fetchTimeoutMs,\n } = params;\n\n const data = await this.apiClient.prompts.get(\n name,\n {\n version,\n label,\n },\n {\n maxRetries,\n timeoutInSeconds: fetchTimeoutMs ? fetchTimeoutMs / 1_000 : undefined,\n },\n );\n\n let prompt: LangfusePromptClient;\n if (data.type === \"chat\") {\n prompt = new ChatPromptClient(data);\n } else {\n prompt = new TextPromptClient(data);\n }\n\n this.cache.set(cacheKey, prompt, cacheTtlSeconds);\n\n return prompt;\n } catch (error) {\n this.logger.error(`Error fetching prompt '${cacheKey}':`, error);\n\n throw error;\n }\n }\n}\n","import { getGlobalLogger } from \"@langfuse/core\";\n\nimport type { LangfusePromptClient } from \"./promptClients.js\";\n\nexport const DEFAULT_PROMPT_CACHE_TTL_SECONDS = 60;\n\nclass LangfusePromptCacheItem {\n private _expiry: number;\n\n constructor(\n public value: LangfusePromptClient,\n ttlSeconds: number,\n ) {\n this._expiry = Date.now() + ttlSeconds * 1000;\n }\n\n get isExpired(): boolean {\n return Date.now() > this._expiry;\n }\n}\nexport class LangfusePromptCache {\n private _cache: Map<string, LangfusePromptCacheItem>;\n private _defaultTtlSeconds: number;\n private _refreshingKeys: Map<string, Promise<void>>;\n\n constructor() {\n this._cache = new Map<string, LangfusePromptCacheItem>();\n this._defaultTtlSeconds = DEFAULT_PROMPT_CACHE_TTL_SECONDS;\n this._refreshingKeys = new Map<string, Promise<void>>();\n }\n\n public getIncludingExpired(key: string): LangfusePromptCacheItem | null {\n return this._cache.get(key) ?? null;\n }\n\n public createKey(params: {\n name: string;\n version?: number;\n label?: string;\n }): string {\n const { name, version, label } = params;\n const parts = [name];\n\n if (version !== undefined) {\n parts.push(\"version:\" + version.toString());\n } else if (label !== undefined) {\n parts.push(\"label:\" + label);\n } else {\n parts.push(\"label:production\");\n }\n\n return parts.join(\"-\");\n }\n\n public set(\n key: string,\n value: LangfusePromptClient,\n ttlSeconds?: number,\n ): void {\n const effectiveTtlSeconds = ttlSeconds ?? this._defaultTtlSeconds;\n this._cache.set(\n key,\n new LangfusePromptCacheItem(value, effectiveTtlSeconds),\n );\n }\n\n public addRefreshingPromise(key: string, promise: Promise<any>): void {\n this._refreshingKeys.set(key, promise);\n promise\n .then(() => {\n this._refreshingKeys.delete(key);\n })\n .catch(() => {\n this._refreshingKeys.delete(key);\n });\n }\n\n public isRefreshing(key: string): boolean {\n return this._refreshingKeys.has(key);\n }\n\n public invalidate(promptName: string): void {\n getGlobalLogger().debug(\n \"Invalidating cache keys for\",\n promptName,\n this._cache.keys(),\n );\n\n for (const key of this._cache.keys()) {\n if (key.startsWith(promptName)) {\n this._cache.delete(key);\n }\n }\n }\n}\n","import {\n Prompt,\n ChatMessage,\n BasePrompt,\n ChatMessageWithPlaceholders,\n} from \"@langfuse/core\";\nimport mustache from \"mustache\";\n\nimport {\n ChatMessageOrPlaceholder,\n ChatMessageType,\n LangchainMessagesPlaceholder,\n} from \"./types.js\";\n\nmustache.escape = function (text) {\n return text;\n};\n\nabstract class BasePromptClient {\n public readonly name: string;\n public readonly version: number;\n public readonly config: unknown;\n public readonly labels: string[];\n public readonly tags: string[];\n public readonly isFallback: boolean;\n public readonly type: \"text\" | \"chat\";\n public readonly commitMessage: string | null | undefined;\n\n constructor(prompt: BasePrompt, isFallback = false, type: \"text\" | \"chat\") {\n this.name = prompt.name;\n this.version = prompt.version;\n this.config = prompt.config;\n this.labels = prompt.labels;\n this.tags = prompt.tags;\n this.isFallback = isFallback;\n this.type = type;\n this.commitMessage = prompt.commitMessage;\n }\n\n abstract get prompt(): string | ChatMessageWithPlaceholders[];\n abstract set prompt(value: string | ChatMessageWithPlaceholders[]);\n\n abstract compile(\n variables?: Record<string, string>,\n placeholders?: Record<string, any>,\n ): string | ChatMessage[] | (ChatMessageOrPlaceholder | any)[];\n\n public abstract getLangchainPrompt(options?: {\n placeholders?: Record<string, any>;\n }):\n | string\n | ChatMessage[]\n | ChatMessageOrPlaceholder[]\n | (ChatMessage | LangchainMessagesPlaceholder | any)[];\n\n protected _transformToLangchainVariables(content: string): string {\n const jsonEscapedContent = this.escapeJsonForLangchain(content);\n\n return jsonEscapedContent.replace(/\\{\\{(\\w+)\\}\\}/g, \"{$1}\");\n }\n\n /**\n * Escapes every curly brace that is part of a JSON object by doubling it.\n *\n * A curly brace is considered “JSON-related” when, after skipping any immediate\n * whitespace, the next non-whitespace character is a single (') or double (\") quote.\n *\n * Braces that are already doubled (e.g. `{{variable}}` placeholders) are left untouched.\n *\n * @param text - Input string that may contain JSON snippets.\n * @returns The string with JSON-related braces doubled.\n */\n protected escapeJsonForLangchain(text: string): string {\n const out: string[] = []; // collected characters\n const stack: boolean[] = []; // true = “this { belongs to JSON”, false = normal “{”\n let i = 0;\n const n = text.length;\n\n while (i < n) {\n const ch = text[i];\n\n // ---------- opening brace ----------\n if (ch === \"{\") {\n // leave existing “{{ …” untouched\n if (i + 1 < n && text[i + 1] === \"{\") {\n out.push(\"{{\");\n i += 2;\n continue;\n }\n\n // look ahead to find the next non-space character\n let j = i + 1;\n while (j < n && /\\s/.test(text[j])) {\n j++;\n }\n\n const isJson = j < n && (text[j] === \"'\" || text[j] === '\"');\n out.push(isJson ? \"{{\" : \"{\");\n stack.push(isJson); // remember how this “{” was treated\n i += 1;\n continue;\n }\n\n // ---------- closing brace ----------\n if (ch === \"}\") {\n // leave existing “… }}” untouched\n if (i + 1 < n && text[i + 1] === \"}\") {\n out.push(\"}}\");\n i += 2;\n continue;\n }\n\n const isJson = stack.pop() ?? false;\n out.push(isJson ? \"}}\" : \"}\");\n i += 1;\n continue;\n }\n\n // ---------- any other character ----------\n out.push(ch);\n i += 1;\n }\n\n return out.join(\"\");\n }\n\n public abstract toJSON(): string;\n}\n\nexport class TextPromptClient extends BasePromptClient {\n public readonly promptResponse: Prompt.Text;\n public readonly prompt: string;\n\n constructor(prompt: Prompt.Text, isFallback = false) {\n super(prompt, isFallback, \"text\");\n this.promptResponse = prompt;\n this.prompt = prompt.prompt;\n }\n\n compile(\n variables?: Record<string, string>,\n _placeholders?: Record<string, any>,\n ): string {\n return mustache.render(this.promptResponse.prompt, variables ?? {});\n }\n\n public getLangchainPrompt(_options?: {\n placeholders?: Record<string, any>;\n }): string {\n /**\n * Converts Langfuse prompt into string compatible with Langchain PromptTemplate.\n *\n * It specifically adapts the mustache-style double curly braces {{variable}} used in Langfuse\n * to the single curly brace {variable} format expected by Langchain.\n *\n * @returns {string} The string that can be plugged into Langchain's PromptTemplate.\n */\n return this._transformToLangchainVariables(this.prompt);\n }\n\n public toJSON(): string {\n return JSON.stringify({\n name: this.name,\n prompt: this.prompt,\n version: this.version,\n isFallback: this.isFallback,\n tags: this.tags,\n labels: this.labels,\n type: this.type,\n config: this.config,\n });\n }\n}\n\nexport class ChatPromptClient extends BasePromptClient {\n public readonly promptResponse: Prompt.Chat;\n public readonly prompt: ChatMessageWithPlaceholders[];\n\n constructor(prompt: Prompt.Chat, isFallback = false) {\n const normalizedPrompt = ChatPromptClient.normalizePrompt(prompt.prompt);\n const typedPrompt: Prompt.Chat = {\n ...prompt,\n prompt: normalizedPrompt,\n };\n\n super(typedPrompt, isFallback, \"chat\");\n this.promptResponse = typedPrompt;\n this.prompt = normalizedPrompt;\n }\n\n private static normalizePrompt(\n prompt: ChatMessage[] | ChatMessageWithPlaceholders[],\n ): ChatMessageWithPlaceholders[] {\n // Convert ChatMessages to ChatMessageWithPlaceholders for backward compatibility\n return prompt.map((item): ChatMessageWithPlaceholders => {\n if (\"type\" in item) {\n // Already has type field (new format)\n return item as ChatMessageWithPlaceholders;\n } else {\n // Plain ChatMessage (legacy format) - add type field\n return {\n type: ChatMessageType.ChatMessage,\n ...item,\n } as ChatMessageWithPlaceholders;\n }\n });\n }\n\n compile(\n variables?: Record<string, string>,\n placeholders?: Record<string, any>,\n ): (ChatMessageOrPlaceholder | any)[] {\n /**\n * Compiles the chat prompt by replacing placeholders and variables with provided values.\n *\n * First fills-in placeholders by from the provided placeholder parameter.\n * Then compiles variables into the message content.\n * Unresolved placeholders are included in the output as placeholder objects.\n * If you only want to fill-in placeholders, pass an empty object for variables.\n *\n * @param variables - Key-value pairs for Mustache variable substitution in message content\n * @param placeholders - Key-value pairs where keys are placeholder names and values can be ChatMessage arrays\n * @returns Array of ChatMessage objects and placeholder objects with placeholders replaced and variables rendered\n */\n const messagesWithPlaceholdersReplaced: (ChatMessageOrPlaceholder | any)[] =\n [];\n const placeholderValues = placeholders ?? {};\n\n for (const item of this.prompt) {\n if (\"type\" in item && item.type === ChatMessageType.Placeholder) {\n const placeholderValue = placeholderValues[item.name];\n if (\n Array.isArray(placeholderValue) &&\n placeholderValue.length > 0 &&\n placeholderValue.every(\n (msg) =>\n typeof msg === \"object\" && \"role\" in msg && \"content\" in msg,\n )\n ) {\n messagesWithPlaceholdersReplaced.push(\n ...(placeholderValue as ChatMessage[]),\n );\n } else if (\n Array.isArray(placeholderValue) &&\n placeholderValue.length === 0\n ) {\n // Empty array provided - skip placeholder (don't include it)\n } else if (placeholderValue !== undefined) {\n // Non-standard placeholder value format, just stringfiy\n messagesWithPlaceholdersReplaced.push(\n JSON.stringify(placeholderValue),\n );\n } else {\n // Keep unresolved placeholder in the output\n messagesWithPlaceholdersReplaced.push(\n item as { type: ChatMessageType.Placeholder } & typeof item,\n );\n }\n } else if (\n \"role\" in item &&\n \"content\" in item &&\n item.type === ChatMessageType.ChatMessage\n ) {\n messagesWithPlaceholdersReplaced.push({\n role: item.role,\n content: item.content,\n });\n }\n }\n\n return messagesWithPlaceholdersReplaced.map((item) => {\n if (\n typeof item === \"object\" &&\n item !== null &&\n \"role\" in item &&\n \"content\" in item\n ) {\n return {\n ...item,\n content: mustache.render(item.content, variables ?? {}),\n };\n } else {\n // Return placeholder or stringified value as-is\n return item;\n }\n });\n }\n\n public getLangchainPrompt(options?: {\n placeholders?: Record<string, any>;\n }): (ChatMessage | LangchainMessagesPlaceholder | any)[] {\n /*\n * Converts Langfuse prompt into format compatible with Langchain PromptTemplate.\n *\n * Fills-in placeholders from provided values and converts unresolved ones to Langchain MessagesPlaceholder objects.\n * Transforms variables from {{var}} to {var} format for Langchain without rendering them.\n *\n * @param options - Configuration object\n * @param options.placeholders - Key-value pairs where keys are placeholder names and values can be ChatMessage arrays\n * @returns Array of ChatMessage objects and Langchain MessagesPlaceholder objects with variables transformed for Langchain compatibility.\n *\n * @example\n * ```typescript\n * const client = new ChatPromptClient(prompt);\n * client.getLangchainPrompt({ placeholders: { examples: [{ role: \"user\", content: \"Hello\" }] } });\n * ```\n */\n const messagesWithPlaceholdersReplaced: (\n | ChatMessage\n | LangchainMessagesPlaceholder\n | any\n )[] = [];\n const placeholderValues = options?.placeholders ?? {};\n\n for (const item of this.prompt) {\n if (\"type\" in item && item.type === ChatMessageType.Placeholder) {\n const placeholderValue = placeholderValues[item.name];\n if (\n Array.isArray(placeholderValue) &&\n placeholderValue.length > 0 &&\n placeholderValue.every(\n (msg) =>\n typeof msg === \"object\" && \"role\" in msg && \"content\" in msg,\n )\n ) {\n // Complete placeholder fill-in, replace with it\n messagesWithPlaceholdersReplaced.push(\n ...(placeholderValue as ChatMessage[]).map((msg) => {\n return {\n role: msg.role,\n content: this._transformToLangchainVariables(msg.content),\n };\n }),\n );\n } else if (\n Array.isArray(placeholderValue) &&\n placeholderValue.length === 0\n ) {\n // Skip empty array placeholder\n } else if (placeholderValue !== undefined) {\n // Non-standard placeholder value, just stringify and add directly\n messagesWithPlaceholdersReplaced.push(\n JSON.stringify(placeholderValue),\n );\n } else {\n // Convert unresolved placeholder to Langchain MessagesPlaceholder\n messagesWithPlaceholdersReplaced.push({\n variableName: item.name,\n optional: false,\n });\n }\n } else if (\n \"role\" in item &&\n \"content\" in item &&\n item.type === ChatMessageType.ChatMessage\n ) {\n messagesWithPlaceholdersReplaced.push({\n role: item.role,\n content: this._transformToLangchainVariables(item.content),\n });\n }\n }\n\n return messagesWithPlaceholdersReplaced;\n }\n\n public toJSON(): string {\n return JSON.stringify({\n name: this.name,\n prompt: this.promptResponse.prompt.map((item) => {\n if (\"type\" in item && item.type === ChatMessageType.ChatMessage) {\n const { type: _, ...messageWithoutType } = item;\n return messageWithoutType;\n }\n return item;\n }),\n version: this.version,\n isFallback: this.isFallback,\n tags: this.tags,\n labels: this.labels,\n type: this.type,\n config: this.config,\n });\n }\n}\n\nexport type LangfusePromptClient = TextPromptClient | ChatPromptClient;\n","import {\n ChatMessage,\n PlaceholderMessage,\n ChatMessageWithPlaceholders,\n CreatePromptRequest,\n} from \"@langfuse/core\";\n\nexport enum ChatMessageType {\n ChatMessage = \"chatmessage\",\n Placeholder = \"placeholder\",\n}\n\nexport type ChatMessageOrPlaceholder =\n | ChatMessage\n | ({ type: ChatMessageType.Placeholder } & PlaceholderMessage);\n\nexport type LangchainMessagesPlaceholder = {\n variableName: string;\n optional?: boolean;\n};\n\nexport type CreateChatPromptBodyWithPlaceholders = {\n type: \"chat\";\n} & Omit<CreatePromptRequest.Chat, \"type\" | \"prompt\"> & {\n prompt: (ChatMessage | ChatMessageWithPlaceholders)[];\n };\n","import {\n LangfuseAPIClient,\n IngestionEvent,\n getEnv,\n generateUUID,\n ScoreBody,\n getGlobalLogger,\n safeSetTimeout,\n IngestionResponse,\n} from \"@langfuse/core\";\nimport { Span, trace } from \"@opentelemetry/api\";\n\nconst MAX_QUEUE_SIZE = 100_000; // prevent memory leaks\nconst MAX_BATCH_SIZE = 100;\n\nexport class ScoreManager {\n private apiClient: LangfuseAPIClient;\n private eventQueue: IngestionEvent[] = [];\n private flushPromise: Promise<void> | null = null;\n private flushTimer: any = null;\n private flushAtCount: number;\n private flushIntervalSeconds: number;\n\n constructor(params: { apiClient: LangfuseAPIClient }) {\n this.apiClient = params.apiClient;\n\n const envFlushAtCount = getEnv(\"LANGFUSE_FLUSH_AT\");\n const envFlushIntervalSeconds = getEnv(\"LANGFUSE_FLUSH_INTERVAL\");\n\n this.flushAtCount = envFlushAtCount ? Number(envFlushAtCount) : 10;\n this.flushIntervalSeconds = envFlushIntervalSeconds\n ? Number(envFlushIntervalSeconds)\n : 1;\n }\n\n get logger() {\n return getGlobalLogger();\n }\n\n public create(data: ScoreBody): void {\n const scoreData: ScoreBody = {\n ...data,\n id: data.id ?? generateUUID(),\n environment: data.environment ?? getEnv(\"LANGFUSE_TRACING_ENVIRONMENT\"),\n };\n\n const scoreIngestionEvent: IngestionEvent = {\n id: generateUUID(),\n type: \"score-create\",\n timestamp: new Date().toISOString(),\n body: scoreData,\n };\n\n if (this.eventQueue.length >= MAX_QUEUE_SIZE) {\n this.logger.error(\n `Score queue is at max size ${MAX_QUEUE_SIZE}. Dropping score.`,\n );\n return;\n }\n\n this.eventQueue.push(scoreIngestionEvent);\n\n if (this.eventQueue.length >= this.flushAtCount) {\n this.flushPromise = this.flush();\n } else if (!this.flushTimer) {\n this.flushTimer = safeSetTimeout(() => {\n this.flushPromise = this.flush();\n }, this.flushIntervalSeconds * 1_000);\n }\n }\n\n public observation(\n observation: { otelSpan: Span },\n data: Omit<\n ScoreBody,\n \"traceId\" | \"sessionId\" | \"observationId\" | \"datasetRunId\"\n >,\n ) {\n const { spanId, traceId } = observation.otelSpan.spanContext();\n\n this.create({\n ...data,\n traceId,\n observationId: spanId,\n });\n }\n\n public trace(\n observation: { otelSpan: Span },\n data: Omit<\n ScoreBody,\n \"traceId\" | \"sessionId\" | \"observationId\" | \"datasetRunId\"\n >,\n ) {\n const { traceId } = observation.otelSpan.spanContext();\n\n this.create({\n ...data,\n traceId,\n });\n }\n\n public activeObservation(\n data: Omit<\n ScoreBody,\n \"traceId\" | \"sessionId\" | \"observationId\" | \"datasetRunId\"\n >,\n ) {\n const currentOtelSpan = trace.getActiveSpan();\n if (!currentOtelSpan) {\n this.logger.warn(\"No active span in context to score.\");\n\n return;\n }\n\n const { spanId, traceId } = currentOtelSpan.spanContext();\n\n this.create({\n ...data,\n traceId,\n observationId: spanId,\n });\n }\n\n public activeTrace(\n data: Omit<\n ScoreBody,\n \"traceId\" | \"sessionId\" | \"observationId\" | \"datasetRunId\"\n >,\n ) {\n const currentOtelSpan = trace.getActiveSpan();\n if (!currentOtelSpan) {\n this.logger.warn(\"No active span in context to score trace.\");\n\n return;\n }\n\n const { traceId } = currentOtelSpan.spanContext();\n\n this.create({\n ...data,\n traceId,\n });\n }\n\n private async handleFlush() {\n try {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n\n const promises: Promise<IngestionResponse | void>[] = [];\n\n while (this.eventQueue.length > 0) {\n const batch = this.eventQueue.splice(0, MAX_BATCH_SIZE);\n\n promises.push(\n this.apiClient.ingestion\n .batch({ batch })\n .then((res) => {\n if (res.errors?.length > 0) {\n this.logger.error(\"Error ingesting scores:\", res.errors);\n }\n })\n .catch((err) => {\n this.logger.error(\"Failed to export score batch:\", err);\n }),\n );\n }\n\n await Promise.all(promises);\n } catch (err) {\n this.logger.error(\"Error flushing Score Manager: \", err);\n } finally {\n this.flushPromise = null;\n }\n }\n\n public async flush() {\n return this.flushPromise ?? this.handleFlush();\n }\n\n public async shutdown() {\n await this.flush();\n }\n}\n"],"mappings":"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","names":["LangfuseAPIClient","getGlobalLogger","getEnv","obj","getGlobalLogger","getGlobalLogger","ChatMessageType","getGlobalLogger","getGlobalLogger","getGlobalLogger","getEnv","LangfuseAPIClient"]}
@@ -0,0 +1,65 @@
1
+ import { LangfuseAPIClient, ParsedMediaReference } from "@langfuse/core";
2
+ export type LangfuseMediaResolveMediaReferencesParams<T> = {
3
+ obj: T;
4
+ resolveWith: "base64DataUri";
5
+ maxDepth?: number;
6
+ };
7
+ export declare class MediaManager {
8
+ private apiClient;
9
+ constructor(params: {
10
+ apiClient: LangfuseAPIClient;
11
+ });
12
+ /**
13
+ * Replaces the media reference strings in an object with base64 data URIs for the media content.
14
+ *
15
+ * This method recursively traverses an object (up to a maximum depth of 10) looking for media reference strings
16
+ * in the format "@@@langfuseMedia:...@@@". When found, it fetches the actual media content using the provided
17
+ * Langfuse client and replaces the reference string with a base64 data URI.
18
+ *
19
+ * If fetching media content fails for a reference string, a warning is logged and the reference string is left unchanged.
20
+ *
21
+ * @param params - Configuration object
22
+ * @param params.obj - The object to process. Can be a primitive value, array, or nested object
23
+ * @param params.resolveWith - The representation of the media content to replace the media reference string with. Currently only "base64DataUri" is supported.
24
+ * @param params.maxDepth - Optional. Default is 10. The maximum depth to traverse the object.
25
+ *
26
+ * @returns A deep copy of the input object with all media references replaced with base64 data URIs where possible
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const obj = {
31
+ * image: "@@@langfuseMedia:type=image/jpeg|id=123|source=bytes@@@",
32
+ * nested: {
33
+ * pdf: "@@@langfuseMedia:type=application/pdf|id=456|source=bytes@@@"
34
+ * }
35
+ * };
36
+ *
37
+ * const result = await LangfuseMedia.resolveMediaReferences({
38
+ * obj,
39
+ * langfuseClient
40
+ * });
41
+ *
42
+ * // Result:
43
+ * // {
44
+ * // image: "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
45
+ * // nested: {
46
+ * // pdf: "data:application/pdf;base64,JVBERi0xLjcK..."
47
+ * // }
48
+ * // }
49
+ * ```
50
+ */
51
+ resolveReferences<T>(params: LangfuseMediaResolveMediaReferencesParams<T>): Promise<T>;
52
+ /**
53
+ * Parses a media reference string into a ParsedMediaReference.
54
+ *
55
+ * Example reference string:
56
+ * "@@@langfuseMedia:type=image/jpeg|id=some-uuid|source=base64DataUri@@@"
57
+ *
58
+ * @param referenceString - The reference string to parse.
59
+ * @returns An object with the mediaId, source, and contentType.
60
+ *
61
+ * @throws Error if the reference string is invalid or missing required fields.
62
+ */
63
+ static parseReferenceString(referenceString: string): ParsedMediaReference;
64
+ }
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAIrB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,yCAAyC,CAAC,CAAC,IAAI;IACzD,GAAG,EAAE,CAAC,CAAC;IACP,WAAW,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAoB;gBAEzB,MAAM,EAAE;QAAE,SAAS,EAAE,iBAAiB,CAAA;KAAE;IAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACU,iBAAiB,CAAC,CAAC,EAC9B,MAAM,EAAE,yCAAyC,CAAC,CAAC,CAAC,GACnD,OAAO,CAAC,CAAC,CAAC;IA4Fb;;;;;;;;;;OAUG;WACW,oBAAoB,CAChC,eAAe,EAAE,MAAM,GACtB,oBAAoB;CAoCxB"}
@@ -0,0 +1,136 @@
1
+ import { getGlobalLogger, uint8ArrayToBase64, } from "@langfuse/core";
2
+ export class MediaManager {
3
+ constructor(params) {
4
+ this.apiClient = params.apiClient;
5
+ }
6
+ /**
7
+ * Replaces the media reference strings in an object with base64 data URIs for the media content.
8
+ *
9
+ * This method recursively traverses an object (up to a maximum depth of 10) looking for media reference strings
10
+ * in the format "@@@langfuseMedia:...@@@". When found, it fetches the actual media content using the provided
11
+ * Langfuse client and replaces the reference string with a base64 data URI.
12
+ *
13
+ * If fetching media content fails for a reference string, a warning is logged and the reference string is left unchanged.
14
+ *
15
+ * @param params - Configuration object
16
+ * @param params.obj - The object to process. Can be a primitive value, array, or nested object
17
+ * @param params.resolveWith - The representation of the media content to replace the media reference string with. Currently only "base64DataUri" is supported.
18
+ * @param params.maxDepth - Optional. Default is 10. The maximum depth to traverse the object.
19
+ *
20
+ * @returns A deep copy of the input object with all media references replaced with base64 data URIs where possible
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const obj = {
25
+ * image: "@@@langfuseMedia:type=image/jpeg|id=123|source=bytes@@@",
26
+ * nested: {
27
+ * pdf: "@@@langfuseMedia:type=application/pdf|id=456|source=bytes@@@"
28
+ * }
29
+ * };
30
+ *
31
+ * const result = await LangfuseMedia.resolveMediaReferences({
32
+ * obj,
33
+ * langfuseClient
34
+ * });
35
+ *
36
+ * // Result:
37
+ * // {
38
+ * // image: "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
39
+ * // nested: {
40
+ * // pdf: "data:application/pdf;base64,JVBERi0xLjcK..."
41
+ * // }
42
+ * // }
43
+ * ```
44
+ */
45
+ async resolveReferences(params) {
46
+ const { obj, maxDepth = 10 } = params;
47
+ const traverse = async (obj, depth) => {
48
+ if (depth > maxDepth) {
49
+ return obj;
50
+ }
51
+ // Handle string with potential media references
52
+ if (typeof obj === "string") {
53
+ const regex = /@@@langfuseMedia:.+?@@@/g;
54
+ const referenceStringMatches = obj.match(regex);
55
+ if (!referenceStringMatches) {
56
+ return obj;
57
+ }
58
+ let result = obj;
59
+ const referenceStringToMediaContentMap = new Map();
60
+ await Promise.all(referenceStringMatches.map(async (referenceString) => {
61
+ try {
62
+ const parsedMediaReference = MediaManager.parseReferenceString(referenceString);
63
+ const mediaData = await this.apiClient.media.get(parsedMediaReference.mediaId);
64
+ const mediaContent = await fetch(mediaData.url, {
65
+ method: "GET",
66
+ headers: {},
67
+ });
68
+ if (mediaContent.status !== 200) {
69
+ throw new Error("Failed to fetch media content");
70
+ }
71
+ const uint8Content = new Uint8Array(await mediaContent.arrayBuffer());
72
+ const base64MediaContent = uint8ArrayToBase64(uint8Content);
73
+ const base64DataUri = `data:${mediaData.contentType};base64,${base64MediaContent}`;
74
+ referenceStringToMediaContentMap.set(referenceString, base64DataUri);
75
+ }
76
+ catch (error) {
77
+ getGlobalLogger().warn("Error fetching media content for reference string", referenceString, error);
78
+ }
79
+ }));
80
+ for (const [referenceString, base64MediaContent,] of referenceStringToMediaContentMap.entries()) {
81
+ result = result.replaceAll(referenceString, base64MediaContent);
82
+ }
83
+ return result;
84
+ }
85
+ // Handle arrays
86
+ if (Array.isArray(obj)) {
87
+ return Promise.all(obj.map(async (item) => await traverse(item, depth + 1)));
88
+ }
89
+ // Handle objects
90
+ if (typeof obj === "object" && obj !== null) {
91
+ return Object.fromEntries(await Promise.all(Object.entries(obj).map(async ([key, value]) => [
92
+ key,
93
+ await traverse(value, depth + 1),
94
+ ])));
95
+ }
96
+ return obj;
97
+ };
98
+ return traverse(obj, 0);
99
+ }
100
+ /**
101
+ * Parses a media reference string into a ParsedMediaReference.
102
+ *
103
+ * Example reference string:
104
+ * "@@@langfuseMedia:type=image/jpeg|id=some-uuid|source=base64DataUri@@@"
105
+ *
106
+ * @param referenceString - The reference string to parse.
107
+ * @returns An object with the mediaId, source, and contentType.
108
+ *
109
+ * @throws Error if the reference string is invalid or missing required fields.
110
+ */
111
+ static parseReferenceString(referenceString) {
112
+ const prefix = "@@@langfuseMedia:";
113
+ const suffix = "@@@";
114
+ if (!referenceString.startsWith(prefix)) {
115
+ throw new Error("Reference string does not start with '@@@langfuseMedia:type='");
116
+ }
117
+ if (!referenceString.endsWith(suffix)) {
118
+ throw new Error("Reference string does not end with '@@@'");
119
+ }
120
+ const content = referenceString.slice(prefix.length, -suffix.length);
121
+ const pairs = content.split("|");
122
+ const parsedData = {};
123
+ for (const pair of pairs) {
124
+ const [key, value] = pair.split("=", 2);
125
+ parsedData[key] = value;
126
+ }
127
+ if (!("type" in parsedData && "id" in parsedData && "source" in parsedData)) {
128
+ throw new Error("Missing required fields in reference string");
129
+ }
130
+ return {
131
+ mediaId: parsedData["id"],
132
+ source: parsedData["source"],
133
+ contentType: parsedData["type"],
134
+ };
135
+ }
136
+ }
@@ -0,0 +1,4 @@
1
+ export { PromptManager } from "./promptManager.js";
2
+ export { ChatPromptClient, TextPromptClient } from "./promptClients.js";
3
+ export * from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompt/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACxE,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { PromptManager } from "./promptManager.js";
2
+ export { ChatPromptClient, TextPromptClient } from "./promptClients.js";
3
+ export * from "./types.js";
@@ -0,0 +1,26 @@
1
+ import type { LangfusePromptClient } from "./promptClients.js";
2
+ export declare const DEFAULT_PROMPT_CACHE_TTL_SECONDS = 60;
3
+ declare class LangfusePromptCacheItem {
4
+ value: LangfusePromptClient;
5
+ private _expiry;
6
+ constructor(value: LangfusePromptClient, ttlSeconds: number);
7
+ get isExpired(): boolean;
8
+ }
9
+ export declare class LangfusePromptCache {
10
+ private _cache;
11
+ private _defaultTtlSeconds;
12
+ private _refreshingKeys;
13
+ constructor();
14
+ getIncludingExpired(key: string): LangfusePromptCacheItem | null;
15
+ createKey(params: {
16
+ name: string;
17
+ version?: number;
18
+ label?: string;
19
+ }): string;
20
+ set(key: string, value: LangfusePromptClient, ttlSeconds?: number): void;
21
+ addRefreshingPromise(key: string, promise: Promise<any>): void;
22
+ isRefreshing(key: string): boolean;
23
+ invalidate(promptName: string): void;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=promptCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptCache.d.ts","sourceRoot":"","sources":["../../src/prompt/promptCache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,cAAM,uBAAuB;IAIlB,KAAK,EAAE,oBAAoB;IAHpC,OAAO,CAAC,OAAO,CAAS;gBAGf,KAAK,EAAE,oBAAoB,EAClC,UAAU,EAAE,MAAM;IAKpB,IAAI,SAAS,IAAI,OAAO,CAEvB;CACF;AACD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,eAAe,CAA6B;;IAQ7C,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI;IAIhE,SAAS,CAAC,MAAM,EAAE;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,MAAM;IAeH,GAAG,CACR,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,oBAAoB,EAC3B,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI;IAQA,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI;IAW9D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIlC,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;CAa5C"}
@@ -0,0 +1,61 @@
1
+ import { getGlobalLogger } from "@langfuse/core";
2
+ export const DEFAULT_PROMPT_CACHE_TTL_SECONDS = 60;
3
+ class LangfusePromptCacheItem {
4
+ constructor(value, ttlSeconds) {
5
+ this.value = value;
6
+ this._expiry = Date.now() + ttlSeconds * 1000;
7
+ }
8
+ get isExpired() {
9
+ return Date.now() > this._expiry;
10
+ }
11
+ }
12
+ export class LangfusePromptCache {
13
+ constructor() {
14
+ this._cache = new Map();
15
+ this._defaultTtlSeconds = DEFAULT_PROMPT_CACHE_TTL_SECONDS;
16
+ this._refreshingKeys = new Map();
17
+ }
18
+ getIncludingExpired(key) {
19
+ var _a;
20
+ return (_a = this._cache.get(key)) !== null && _a !== void 0 ? _a : null;
21
+ }
22
+ createKey(params) {
23
+ const { name, version, label } = params;
24
+ const parts = [name];
25
+ if (version !== undefined) {
26
+ parts.push("version:" + version.toString());
27
+ }
28
+ else if (label !== undefined) {
29
+ parts.push("label:" + label);
30
+ }
31
+ else {
32
+ parts.push("label:production");
33
+ }
34
+ return parts.join("-");
35
+ }
36
+ set(key, value, ttlSeconds) {
37
+ const effectiveTtlSeconds = ttlSeconds !== null && ttlSeconds !== void 0 ? ttlSeconds : this._defaultTtlSeconds;
38
+ this._cache.set(key, new LangfusePromptCacheItem(value, effectiveTtlSeconds));
39
+ }
40
+ addRefreshingPromise(key, promise) {
41
+ this._refreshingKeys.set(key, promise);
42
+ promise
43
+ .then(() => {
44
+ this._refreshingKeys.delete(key);
45
+ })
46
+ .catch(() => {
47
+ this._refreshingKeys.delete(key);
48
+ });
49
+ }
50
+ isRefreshing(key) {
51
+ return this._refreshingKeys.has(key);
52
+ }
53
+ invalidate(promptName) {
54
+ getGlobalLogger().debug("Invalidating cache keys for", promptName, this._cache.keys());
55
+ for (const key of this._cache.keys()) {
56
+ if (key.startsWith(promptName)) {
57
+ this._cache.delete(key);
58
+ }
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,57 @@
1
+ import { Prompt, ChatMessage, BasePrompt, ChatMessageWithPlaceholders } from "@langfuse/core";
2
+ import { ChatMessageOrPlaceholder, LangchainMessagesPlaceholder } from "./types.js";
3
+ declare abstract class BasePromptClient {
4
+ readonly name: string;
5
+ readonly version: number;
6
+ readonly config: unknown;
7
+ readonly labels: string[];
8
+ readonly tags: string[];
9
+ readonly isFallback: boolean;
10
+ readonly type: "text" | "chat";
11
+ readonly commitMessage: string | null | undefined;
12
+ constructor(prompt: BasePrompt, isFallback: boolean | undefined, type: "text" | "chat");
13
+ abstract get prompt(): string | ChatMessageWithPlaceholders[];
14
+ abstract set prompt(value: string | ChatMessageWithPlaceholders[]);
15
+ abstract compile(variables?: Record<string, string>, placeholders?: Record<string, any>): string | ChatMessage[] | (ChatMessageOrPlaceholder | any)[];
16
+ abstract getLangchainPrompt(options?: {
17
+ placeholders?: Record<string, any>;
18
+ }): string | ChatMessage[] | ChatMessageOrPlaceholder[] | (ChatMessage | LangchainMessagesPlaceholder | any)[];
19
+ protected _transformToLangchainVariables(content: string): string;
20
+ /**
21
+ * Escapes every curly brace that is part of a JSON object by doubling it.
22
+ *
23
+ * A curly brace is considered “JSON-related” when, after skipping any immediate
24
+ * whitespace, the next non-whitespace character is a single (') or double (") quote.
25
+ *
26
+ * Braces that are already doubled (e.g. `{{variable}}` placeholders) are left untouched.
27
+ *
28
+ * @param text - Input string that may contain JSON snippets.
29
+ * @returns The string with JSON-related braces doubled.
30
+ */
31
+ protected escapeJsonForLangchain(text: string): string;
32
+ abstract toJSON(): string;
33
+ }
34
+ export declare class TextPromptClient extends BasePromptClient {
35
+ readonly promptResponse: Prompt.Text;
36
+ readonly prompt: string;
37
+ constructor(prompt: Prompt.Text, isFallback?: boolean);
38
+ compile(variables?: Record<string, string>, _placeholders?: Record<string, any>): string;
39
+ getLangchainPrompt(_options?: {
40
+ placeholders?: Record<string, any>;
41
+ }): string;
42
+ toJSON(): string;
43
+ }
44
+ export declare class ChatPromptClient extends BasePromptClient {
45
+ readonly promptResponse: Prompt.Chat;
46
+ readonly prompt: ChatMessageWithPlaceholders[];
47
+ constructor(prompt: Prompt.Chat, isFallback?: boolean);
48
+ private static normalizePrompt;
49
+ compile(variables?: Record<string, string>, placeholders?: Record<string, any>): (ChatMessageOrPlaceholder | any)[];
50
+ getLangchainPrompt(options?: {
51
+ placeholders?: Record<string, any>;
52
+ }): (ChatMessage | LangchainMessagesPlaceholder | any)[];
53
+ toJSON(): string;
54
+ }
55
+ export type LangfusePromptClient = TextPromptClient | ChatPromptClient;
56
+ export {};
57
+ //# sourceMappingURL=promptClients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptClients.d.ts","sourceRoot":"","sources":["../../src/prompt/promptClients.ts"],"names":[],"mappings":"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"}