@librechat/agents 3.1.95 → 3.1.97

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.
Files changed (67) hide show
  1. package/dist/cjs/graphs/Graph.cjs +54 -21
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/instrumentation.cjs +120 -9
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/langfuse.cjs +30 -226
  6. package/dist/cjs/langfuse.cjs.map +1 -1
  7. package/dist/cjs/langfuseToolOutputTracing.cjs +465 -0
  8. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -0
  9. package/dist/cjs/main.cjs +1 -0
  10. package/dist/cjs/main.cjs.map +1 -1
  11. package/dist/cjs/run.cjs +142 -69
  12. package/dist/cjs/run.cjs.map +1 -1
  13. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +29 -2
  14. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  15. package/dist/cjs/tools/ToolNode.cjs +20 -8
  16. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  17. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +10 -6
  18. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  19. package/dist/esm/graphs/Graph.mjs +56 -23
  20. package/dist/esm/graphs/Graph.mjs.map +1 -1
  21. package/dist/esm/instrumentation.mjs +118 -9
  22. package/dist/esm/instrumentation.mjs.map +1 -1
  23. package/dist/esm/langfuse.mjs +28 -224
  24. package/dist/esm/langfuse.mjs.map +1 -1
  25. package/dist/esm/langfuseToolOutputTracing.mjs +457 -0
  26. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -0
  27. package/dist/esm/main.mjs +1 -1
  28. package/dist/esm/run.mjs +144 -71
  29. package/dist/esm/run.mjs.map +1 -1
  30. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +29 -3
  31. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  32. package/dist/esm/tools/ToolNode.mjs +20 -8
  33. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  34. package/dist/esm/tools/subagent/SubagentExecutor.mjs +10 -6
  35. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  36. package/dist/types/graphs/Graph.d.ts +5 -1
  37. package/dist/types/instrumentation.d.ts +5 -1
  38. package/dist/types/langfuse.d.ts +6 -28
  39. package/dist/types/langfuseToolOutputTracing.d.ts +20 -0
  40. package/dist/types/run.d.ts +5 -1
  41. package/dist/types/tools/BashProgrammaticToolCalling.d.ts +1 -0
  42. package/dist/types/tools/ToolNode.d.ts +4 -1
  43. package/dist/types/tools/subagent/SubagentExecutor.d.ts +2 -0
  44. package/dist/types/types/graph.d.ts +30 -0
  45. package/dist/types/types/run.d.ts +6 -0
  46. package/dist/types/types/tools.d.ts +7 -0
  47. package/package.json +2 -1
  48. package/src/graphs/Graph.ts +90 -34
  49. package/src/instrumentation.ts +172 -11
  50. package/src/langfuse.ts +59 -324
  51. package/src/langfuseToolOutputTracing.ts +683 -0
  52. package/src/run.ts +190 -87
  53. package/src/specs/langfuse-callbacks.test.ts +178 -1
  54. package/src/specs/langfuse-config.test.ts +112 -76
  55. package/src/specs/langfuse-instrumentation.test.ts +283 -0
  56. package/src/specs/langfuse-metadata.test.ts +54 -1
  57. package/src/specs/langfuse-tool-output-tracing.test.ts +588 -0
  58. package/src/tools/BashProgrammaticToolCalling.ts +39 -5
  59. package/src/tools/ToolNode.ts +28 -7
  60. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +54 -0
  61. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +72 -4
  62. package/src/tools/__tests__/SubagentExecutor.test.ts +32 -0
  63. package/src/tools/__tests__/ToolNode.langfuse.test.ts +41 -0
  64. package/src/tools/subagent/SubagentExecutor.ts +11 -6
  65. package/src/types/graph.ts +32 -0
  66. package/src/types/run.ts +6 -0
  67. package/src/types/tools.ts +7 -0
@@ -1,16 +1,127 @@
1
1
  'use strict';
2
2
 
3
- var sdkNode = require('@opentelemetry/sdk-node');
4
- var otel = require('@langfuse/otel');
3
+ var tracing = require('@langfuse/tracing');
4
+ var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
5
+ var api = require('@opentelemetry/api');
6
+ var contextAsyncHooks = require('@opentelemetry/context-async-hooks');
7
+ var langfuse = require('./langfuse.cjs');
8
+ var langfuseToolOutputTracing = require('./langfuseToolOutputTracing.cjs');
5
9
  var misc = require('./utils/misc.cjs');
6
10
 
7
- if (misc.isPresent(process.env.LANGFUSE_SECRET_KEY) &&
8
- misc.isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
9
- misc.isPresent(process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL)) {
10
- const langfuseSpanProcessor = new otel.LangfuseSpanProcessor();
11
- const sdk = new sdkNode.NodeSDK({
12
- spanProcessors: [langfuseSpanProcessor],
11
+ let langfuseTracerProvider;
12
+ let langfuseRoutingSpanProcessor;
13
+ const contextManagerProbeKey = api.createContextKey('langfuse-context-manager-probe');
14
+ function hasActiveContextManager() {
15
+ return api.context.with(api.ROOT_CONTEXT.setValue(contextManagerProbeKey, true), () => api.context.active().getValue(contextManagerProbeKey) === true);
16
+ }
17
+ function ensureOpenTelemetryContextManager() {
18
+ if (hasActiveContextManager()) {
19
+ return;
20
+ }
21
+ const contextManager = new contextAsyncHooks.AsyncLocalStorageContextManager();
22
+ contextManager.enable();
23
+ if (!api.context.setGlobalContextManager(contextManager)) {
24
+ contextManager.disable();
25
+ }
26
+ }
27
+ function getLangfuseSpanProcessorParams(langfuse$1) {
28
+ if (langfuse$1?.enabled === false) {
29
+ return undefined;
30
+ }
31
+ if (langfuse.hasLangfuseConfigCredentials(langfuse$1)) {
32
+ return {
33
+ publicKey: langfuse$1.publicKey,
34
+ secretKey: langfuse$1.secretKey,
35
+ ...(misc.isPresent(langfuse$1.baseUrl) ? { baseUrl: langfuse$1.baseUrl } : {}),
36
+ };
37
+ }
38
+ if (langfuse.hasLangfuseEnvConfig()) {
39
+ const baseUrl = langfuse$1?.baseUrl ??
40
+ process.env.LANGFUSE_BASE_URL ??
41
+ process.env.LANGFUSE_BASEURL;
42
+ return {
43
+ publicKey: process.env.LANGFUSE_PUBLIC_KEY,
44
+ secretKey: process.env.LANGFUSE_SECRET_KEY,
45
+ ...(misc.isPresent(baseUrl) ? { baseUrl } : {}),
46
+ };
47
+ }
48
+ if (misc.isPresent(langfuse$1?.baseUrl) && langfuse.hasLangfuseEnvCredentials()) {
49
+ return {
50
+ publicKey: process.env.LANGFUSE_PUBLIC_KEY,
51
+ secretKey: process.env.LANGFUSE_SECRET_KEY,
52
+ baseUrl: langfuse$1.baseUrl,
53
+ };
54
+ }
55
+ return undefined;
56
+ }
57
+ function getLangfuseTracerProviderKey(params, langfuse) {
58
+ return JSON.stringify({
59
+ publicKey: params.publicKey,
60
+ secretKey: params.secretKey,
61
+ baseUrl: params.baseUrl,
62
+ environment: params.environment,
63
+ toolOutputTracing: langfuse?.toolOutputTracing,
64
+ });
65
+ }
66
+ class RoutingLangfuseSpanProcessor {
67
+ processors = new Map();
68
+ spanProcessors = new WeakMap();
69
+ ensureProcessor(langfuse) {
70
+ const params = getLangfuseSpanProcessorParams(langfuse);
71
+ if (params == null) {
72
+ return undefined;
73
+ }
74
+ const processorKey = getLangfuseTracerProviderKey(params, langfuse);
75
+ const existing = this.processors.get(processorKey);
76
+ if (existing != null) {
77
+ return existing;
78
+ }
79
+ const processor = langfuseToolOutputTracing.createLangfuseSpanProcessor(params, langfuse);
80
+ this.processors.set(processorKey, processor);
81
+ return processor;
82
+ }
83
+ onStart(span, parentContext) {
84
+ const processor = this.ensureProcessor(langfuseToolOutputTracing.getContextLangfuseConfig(parentContext));
85
+ if (processor == null) {
86
+ return;
87
+ }
88
+ this.spanProcessors.set(span, processor);
89
+ processor.onStart(span, parentContext);
90
+ }
91
+ onEnd(span) {
92
+ this.spanProcessors.get(span)?.onEnd(span);
93
+ }
94
+ async forceFlush() {
95
+ await Promise.all(Array.from(this.processors.values(), (processor) => processor.forceFlush()));
96
+ }
97
+ async shutdown() {
98
+ await Promise.all(Array.from(this.processors.values(), (processor) => processor.shutdown()));
99
+ }
100
+ }
101
+ function initializeLangfuseTracing(langfuse) {
102
+ const params = getLangfuseSpanProcessorParams(langfuse);
103
+ if (params == null) {
104
+ return undefined;
105
+ }
106
+ if (langfuseTracerProvider != null) {
107
+ langfuseRoutingSpanProcessor?.ensureProcessor(langfuse);
108
+ return langfuseTracerProvider;
109
+ }
110
+ ensureOpenTelemetryContextManager();
111
+ langfuseRoutingSpanProcessor = new RoutingLangfuseSpanProcessor();
112
+ langfuseRoutingSpanProcessor.ensureProcessor(langfuse);
113
+ langfuseTracerProvider = new sdkTraceBase.BasicTracerProvider({
114
+ spanProcessors: [langfuseRoutingSpanProcessor],
13
115
  });
14
- sdk.start();
116
+ tracing.setLangfuseTracerProvider(langfuseTracerProvider);
117
+ return langfuseTracerProvider;
15
118
  }
119
+ function initializeLangfuseTracingFromEnv() {
120
+ return initializeLangfuseTracing();
121
+ }
122
+ initializeLangfuseTracingFromEnv();
123
+
124
+ exports.ensureOpenTelemetryContextManager = ensureOpenTelemetryContextManager;
125
+ exports.initializeLangfuseTracing = initializeLangfuseTracing;
126
+ exports.initializeLangfuseTracingFromEnv = initializeLangfuseTracingFromEnv;
16
127
  //# sourceMappingURL=instrumentation.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.cjs","sources":["../../src/instrumentation.ts"],"sourcesContent":["import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { LangfuseSpanProcessor } from '@langfuse/otel';\nimport { isPresent } from '@/utils/misc';\n\nif (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL)\n) {\n const langfuseSpanProcessor = new LangfuseSpanProcessor();\n\n const sdk = new NodeSDK({\n spanProcessors: [langfuseSpanProcessor],\n });\n\n sdk.start();\n}\n"],"names":["isPresent","LangfuseSpanProcessor","NodeSDK"],"mappings":";;;;;;AAIA,IACEA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,IAAAA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,IAAAA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EACxE;AACA,IAAA,MAAM,qBAAqB,GAAG,IAAIC,0BAAqB,EAAE;AAEzD,IAAA,MAAM,GAAG,GAAG,IAAIC,eAAO,CAAC;QACtB,cAAc,EAAE,CAAC,qBAAqB,CAAC;AACxC,KAAA,CAAC;IAEF,GAAG,CAAC,KAAK,EAAE;AACb;;"}
1
+ {"version":3,"file":"instrumentation.cjs","sources":["../../src/instrumentation.ts"],"sourcesContent":["import { setLangfuseTracerProvider } from '@langfuse/tracing';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport { context, ROOT_CONTEXT, createContextKey } from '@opentelemetry/api';\nimport { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';\nimport {\n hasLangfuseConfigCredentials,\n hasLangfuseEnvCredentials,\n hasLangfuseEnvConfig,\n} from '@/langfuse';\nimport {\n createLangfuseSpanProcessor,\n getContextLangfuseConfig,\n} from '@/langfuseToolOutputTracing';\nimport { isPresent } from '@/utils/misc';\nimport type {\n ReadableSpan,\n Span,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Context } from '@opentelemetry/api';\nimport type * as t from '@/types';\n\nlet langfuseTracerProvider: BasicTracerProvider | undefined;\nlet langfuseRoutingSpanProcessor: RoutingLangfuseSpanProcessor | undefined;\nconst contextManagerProbeKey = createContextKey(\n 'langfuse-context-manager-probe'\n);\n\nfunction hasActiveContextManager(): boolean {\n return context.with(\n ROOT_CONTEXT.setValue(contextManagerProbeKey, true),\n () => context.active().getValue(contextManagerProbeKey) === true\n );\n}\n\nexport function ensureOpenTelemetryContextManager(): void {\n if (hasActiveContextManager()) {\n return;\n }\n\n const contextManager = new AsyncLocalStorageContextManager();\n contextManager.enable();\n if (!context.setGlobalContextManager(contextManager)) {\n contextManager.disable();\n }\n}\n\nfunction getLangfuseSpanProcessorParams(\n langfuse?: t.LangfuseConfig\n): LangfuseSpanProcessorParams | undefined {\n if (langfuse?.enabled === false) {\n return undefined;\n }\n if (hasLangfuseConfigCredentials(langfuse)) {\n return {\n publicKey: langfuse.publicKey,\n secretKey: langfuse.secretKey,\n ...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),\n };\n }\n if (hasLangfuseEnvConfig()) {\n const baseUrl =\n langfuse?.baseUrl ??\n process.env.LANGFUSE_BASE_URL ??\n process.env.LANGFUSE_BASEURL;\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n ...(isPresent(baseUrl) ? { baseUrl } : {}),\n };\n }\n if (isPresent(langfuse?.baseUrl) && hasLangfuseEnvCredentials()) {\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n baseUrl: langfuse.baseUrl,\n };\n }\n return undefined;\n}\n\nfunction getLangfuseTracerProviderKey(\n params: LangfuseSpanProcessorParams,\n langfuse?: t.LangfuseConfig\n): string {\n return JSON.stringify({\n publicKey: params.publicKey,\n secretKey: params.secretKey,\n baseUrl: params.baseUrl,\n environment: params.environment,\n toolOutputTracing: langfuse?.toolOutputTracing,\n });\n}\n\nclass RoutingLangfuseSpanProcessor implements SpanProcessor {\n private readonly processors = new Map<string, SpanProcessor>();\n private readonly spanProcessors = new WeakMap<object, SpanProcessor>();\n\n ensureProcessor(langfuse?: t.LangfuseConfig): SpanProcessor | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n\n const processorKey = getLangfuseTracerProviderKey(params, langfuse);\n const existing = this.processors.get(processorKey);\n if (existing != null) {\n return existing;\n }\n\n const processor = createLangfuseSpanProcessor(params, langfuse);\n this.processors.set(processorKey, processor);\n return processor;\n }\n\n onStart(span: Span, parentContext: Context): void {\n const processor = this.ensureProcessor(\n getContextLangfuseConfig(parentContext)\n );\n if (processor == null) {\n return;\n }\n\n this.spanProcessors.set(span, processor);\n processor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n this.spanProcessors.get(span)?.onEnd(span);\n }\n\n async forceFlush(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) =>\n processor.forceFlush()\n )\n );\n }\n\n async shutdown(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) => processor.shutdown())\n );\n }\n}\n\nexport function initializeLangfuseTracing(\n langfuse?: t.LangfuseConfig\n): BasicTracerProvider | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n\n if (langfuseTracerProvider != null) {\n langfuseRoutingSpanProcessor?.ensureProcessor(langfuse);\n return langfuseTracerProvider;\n }\n\n ensureOpenTelemetryContextManager();\n langfuseRoutingSpanProcessor = new RoutingLangfuseSpanProcessor();\n langfuseRoutingSpanProcessor.ensureProcessor(langfuse);\n langfuseTracerProvider = new BasicTracerProvider({\n spanProcessors: [langfuseRoutingSpanProcessor],\n });\n\n setLangfuseTracerProvider(langfuseTracerProvider);\n return langfuseTracerProvider;\n}\n\nexport function initializeLangfuseTracingFromEnv():\n | BasicTracerProvider\n | undefined {\n return initializeLangfuseTracing();\n}\n\ninitializeLangfuseTracingFromEnv();\n"],"names":["createContextKey","context","ROOT_CONTEXT","AsyncLocalStorageContextManager","langfuse","hasLangfuseConfigCredentials","isPresent","hasLangfuseEnvConfig","hasLangfuseEnvCredentials","createLangfuseSpanProcessor","getContextLangfuseConfig","BasicTracerProvider","setLangfuseTracerProvider"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var langchain = require('@langfuse/langchain');
4
- var otel = require('@langfuse/otel');
5
3
  var tracing = require('@langfuse/tracing');
6
- var base = require('@langchain/core/callbacks/base');
7
- var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
8
- var api = require('@opentelemetry/api');
4
+ var langchain = require('@langfuse/langchain');
9
5
  var misc = require('./utils/misc.cjs');
10
6
 
11
7
  const TRACE_METADATA_MAX_LENGTH = 200;
12
- const LANGFUSE_TRACER_NAME = 'langfuse-sdk';
13
- function getEnvLangfuseBaseUrl() {
14
- return process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL;
8
+ function hasLangfuseConfigCredentials(langfuse) {
9
+ return (langfuse != null &&
10
+ misc.isPresent(langfuse.publicKey) &&
11
+ misc.isPresent(langfuse.secretKey));
12
+ }
13
+ function hasLangfuseConfigBaseUrl(langfuse) {
14
+ return misc.isPresent(langfuse?.baseUrl);
15
15
  }
16
16
  function createTraceMetadata(metadata) {
17
17
  const traceMetadata = {};
@@ -36,250 +36,54 @@ function createLangfuseTraceMetadata({ messageId, parentMessageId, agentId, agen
36
36
  agentName,
37
37
  });
38
38
  }
39
- function getModelName(serialized) {
40
- const serializedRecord = serialized;
41
- const kwargs = serializedRecord.kwargs;
42
- const modelName = kwargs?.model ??
43
- kwargs?.model_name ??
44
- kwargs?.modelName ??
45
- kwargs?.model_id ??
46
- kwargs?.modelId ??
47
- serializedRecord.name;
48
- if (typeof modelName === 'string' && modelName.trim() !== '') {
49
- return modelName;
50
- }
51
- if (Array.isArray(serializedRecord.id) && serializedRecord.id.length > 0) {
52
- return String(serializedRecord.id[serializedRecord.id.length - 1]);
53
- }
54
- return 'ChatModel';
55
- }
56
- function getModelParameters(extraParams) {
57
- const invocationParams = extraParams?.invocation_params;
58
- const params = invocationParams != null && typeof invocationParams === 'object'
59
- ? invocationParams
60
- : (extraParams ?? {});
61
- return Object.fromEntries(Object.entries(params).filter(([, value]) => {
62
- return typeof value === 'string' || typeof value === 'number';
63
- }));
64
- }
65
- function getOutput(output) {
66
- return output.generations.map((generation) => generation.map((item) => {
67
- if ('message' in item && item.message != null) {
68
- return item.message.content;
69
- }
70
- return item.text;
71
- }));
72
- }
73
- function getUsageDetails(output) {
74
- const llmOutput = output.llmOutput;
75
- const usage = llmOutput?.tokenUsage ?? llmOutput?.usage;
76
- if (usage == null || typeof usage !== 'object') {
77
- return undefined;
78
- }
79
- const usageEntries = Object.entries(usage).filter(([, value]) => typeof value === 'number');
80
- return usageEntries.length > 0
81
- ? Object.fromEntries(usageEntries)
82
- : undefined;
83
- }
84
39
  function getLangfuseTraceName(traceMetadata, fallback = 'LibreChat Agent') {
85
40
  const agentName = traceMetadata?.agentName;
86
41
  return misc.isPresent(agentName) ? `${fallback}: ${agentName}` : fallback;
87
42
  }
88
- function getTraceAttributes({ userId, sessionId, traceMetadata, tags, }) {
89
- const attributes = {
90
- [tracing.LangfuseOtelSpanAttributes.TRACE_NAME]: getLangfuseTraceName(traceMetadata),
91
- };
92
- if (misc.isPresent(userId)) {
93
- attributes[tracing.LangfuseOtelSpanAttributes.TRACE_USER_ID] = userId;
94
- }
95
- if (misc.isPresent(sessionId)) {
96
- attributes[tracing.LangfuseOtelSpanAttributes.TRACE_SESSION_ID] = sessionId;
97
- }
98
- if (tags != null && tags.length > 0) {
99
- attributes[tracing.LangfuseOtelSpanAttributes.TRACE_TAGS] = tags;
100
- }
101
- for (const [key, value] of Object.entries(traceMetadata ?? {})) {
102
- attributes[`${tracing.LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`] = value;
103
- }
104
- return attributes;
105
- }
106
- class LangfuseAgentCallbackHandler extends base.BaseCallbackHandler {
107
- name = 'librechat_langfuse_agent_handler';
108
- provider;
109
- processor;
110
- userId;
111
- sessionId;
112
- traceMetadata;
113
- tags;
114
- spans = new Map();
115
- constructor({ langfuse, userId, sessionId, traceMetadata, tags, }) {
116
- super();
117
- this.userId = userId;
118
- this.sessionId = sessionId;
119
- this.traceMetadata = traceMetadata;
120
- this.tags = tags;
121
- this.processor = new otel.LangfuseSpanProcessor({
122
- publicKey: langfuse.publicKey,
123
- secretKey: langfuse.secretKey,
124
- ...(misc.isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),
125
- environment: process.env.LANGFUSE_TRACING_ENVIRONMENT ??
126
- process.env.NODE_ENV ??
127
- 'development',
128
- exportMode: 'immediate',
129
- shouldExportSpan: ({ otelSpan }) => otel.isDefaultExportSpan(otelSpan) ||
130
- otelSpan.instrumentationScope.name === LANGFUSE_TRACER_NAME,
131
- });
132
- this.provider = new sdkTraceBase.BasicTracerProvider({
133
- spanProcessors: [this.processor],
134
- });
135
- }
136
- startGenerationSpan({ llm, input, runId, extraParams, metadata, name, }) {
137
- if (this.spans.has(runId)) {
138
- return;
139
- }
140
- const tracer = this.provider.getTracer(LANGFUSE_TRACER_NAME);
141
- const spanName = typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);
142
- const span = tracer.startSpan(spanName, {
143
- attributes: {
144
- ...getTraceAttributes({
145
- userId: this.userId,
146
- sessionId: this.sessionId,
147
- traceMetadata: this.traceMetadata,
148
- tags: this.tags,
149
- }),
150
- ...tracing.createObservationAttributes('generation', {
151
- input,
152
- model: getModelName(llm),
153
- modelParameters: getModelParameters(extraParams),
154
- metadata: {
155
- ...metadata,
156
- ...this.traceMetadata,
157
- },
158
- }),
159
- },
160
- });
161
- this.spans.set(runId, span);
162
- }
163
- async handleChatModelStart(llm, messages, runId, _parentRunId, extraParams, _tags, metadata, name) {
164
- this.startGenerationSpan({
165
- llm,
166
- input: messages,
167
- runId,
168
- extraParams,
169
- metadata,
170
- name,
171
- });
172
- }
173
- async handleLLMStart(llm, prompts, runId, _parentRunId, extraParams, _tags, metadata, name) {
174
- this.startGenerationSpan({
175
- llm,
176
- input: prompts,
177
- runId,
178
- extraParams,
179
- metadata,
180
- name,
181
- });
182
- }
183
- async handleLLMEnd(output, runId) {
184
- const span = this.spans.get(runId);
185
- if (!span) {
186
- return;
187
- }
188
- span.setAttributes(tracing.createObservationAttributes('generation', {
189
- output: getOutput(output),
190
- usageDetails: getUsageDetails(output),
191
- }));
192
- span.end();
193
- this.spans.delete(runId);
194
- await this.flush();
195
- }
196
- async handleLLMError(err, runId) {
197
- const span = this.spans.get(runId);
198
- if (!span) {
199
- return;
200
- }
201
- const message = err instanceof Error ? err.message : String(err);
202
- span.setStatus({ code: api.SpanStatusCode.ERROR, message });
203
- span.setAttributes(tracing.createObservationAttributes('generation', {
204
- level: 'ERROR',
205
- statusMessage: message,
206
- }));
207
- span.end();
208
- this.spans.delete(runId);
209
- await this.flush();
210
- }
211
- async flush() {
212
- try {
213
- await this.provider.forceFlush();
214
- }
215
- catch (error) {
216
- process.emitWarning(`[LangfuseAgentCallbackHandler] Failed to flush Langfuse spans: ${error instanceof Error ? error.message : String(error)}`);
217
- }
218
- }
219
- async dispose() {
220
- for (const span of this.spans.values()) {
221
- span.end();
222
- }
223
- this.spans.clear();
224
- await this.flush();
225
- try {
226
- await this.provider.shutdown();
227
- }
228
- catch (error) {
229
- process.emitWarning(`[LangfuseAgentCallbackHandler] Failed to shut down Langfuse provider: ${error instanceof Error ? error.message : String(error)}`);
230
- }
231
- }
43
+ function hasLangfuseEnvConfig() {
44
+ return hasLangfuseEnvCredentials();
232
45
  }
233
- function hasRequiredLangfuseConfig(langfuse) {
234
- return (langfuse?.enabled === true &&
235
- misc.isPresent(langfuse.publicKey) &&
236
- misc.isPresent(langfuse.secretKey));
46
+ function hasLangfuseEnvCredentials() {
47
+ return (misc.isPresent(process.env.LANGFUSE_SECRET_KEY) &&
48
+ misc.isPresent(process.env.LANGFUSE_PUBLIC_KEY));
237
49
  }
238
- function createLegacyLangfuseHandler(params) {
239
- return new langchain.CallbackHandler(params);
50
+ function shouldCreateLangfuseHandler(langfuse) {
51
+ if (langfuse?.enabled === false) {
52
+ return false;
53
+ }
54
+ return (hasLangfuseEnvConfig() ||
55
+ hasLangfuseConfigCredentials(langfuse) ||
56
+ (hasLangfuseConfigBaseUrl(langfuse) && hasLangfuseEnvCredentials()));
240
57
  }
241
58
  function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, tags, }) {
242
- if (!hasRequiredLangfuseConfig(langfuse)) {
59
+ if (!shouldCreateLangfuseHandler(langfuse)) {
243
60
  return undefined;
244
61
  }
245
- return new LangfuseAgentCallbackHandler({
246
- langfuse,
62
+ return new langchain.CallbackHandler({
247
63
  userId,
248
64
  sessionId,
249
65
  traceMetadata,
250
66
  tags,
251
67
  });
252
68
  }
253
- function hasExplicitLangfuseConfig(contexts) {
254
- for (const context of contexts) {
255
- if (context.langfuse != null) {
256
- return true;
257
- }
258
- }
259
- return false;
260
- }
261
- function hasLangfuseEnvConfig() {
262
- return (misc.isPresent(process.env.LANGFUSE_SECRET_KEY) &&
263
- misc.isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
264
- misc.isPresent(getEnvLangfuseBaseUrl()));
265
- }
266
69
  function isLangfuseCallbackHandler(value) {
267
- return (value instanceof langchain.CallbackHandler ||
268
- value instanceof LangfuseAgentCallbackHandler);
70
+ return value instanceof langchain.CallbackHandler;
269
71
  }
270
72
  async function disposeLangfuseHandler(value) {
271
- if (value instanceof LangfuseAgentCallbackHandler) {
272
- await value.dispose();
73
+ if (value == null) {
74
+ return;
273
75
  }
76
+ const provider = tracing.getLangfuseTracerProvider();
77
+ await provider.forceFlush?.();
274
78
  }
275
79
 
276
- exports.LangfuseAgentCallbackHandler = LangfuseAgentCallbackHandler;
277
80
  exports.createLangfuseHandler = createLangfuseHandler;
278
81
  exports.createLangfuseTraceMetadata = createLangfuseTraceMetadata;
279
- exports.createLegacyLangfuseHandler = createLegacyLangfuseHandler;
280
82
  exports.disposeLangfuseHandler = disposeLangfuseHandler;
281
83
  exports.getLangfuseTraceName = getLangfuseTraceName;
282
- exports.hasExplicitLangfuseConfig = hasExplicitLangfuseConfig;
84
+ exports.hasLangfuseConfigCredentials = hasLangfuseConfigCredentials;
283
85
  exports.hasLangfuseEnvConfig = hasLangfuseEnvConfig;
86
+ exports.hasLangfuseEnvCredentials = hasLangfuseEnvCredentials;
284
87
  exports.isLangfuseCallbackHandler = isLangfuseCallbackHandler;
88
+ exports.shouldCreateLangfuseHandler = shouldCreateLangfuseHandler;
285
89
  //# sourceMappingURL=langfuse.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse.cjs","sources":["../../src/langfuse.ts"],"sourcesContent":["import { CallbackHandler } from '@langfuse/langchain';\nimport { isDefaultExportSpan, LangfuseSpanProcessor } from '@langfuse/otel';\nimport {\n LangfuseOtelSpanAttributes,\n createObservationAttributes,\n} from '@langfuse/tracing';\nimport { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport { SpanStatusCode } from '@opentelemetry/api';\nimport type { Serialized } from '@langchain/core/load/serializable';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport type { Attributes, Span } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport { isPresent } from '@/utils/misc';\n\nconst TRACE_METADATA_MAX_LENGTH = 200;\nconst LANGFUSE_TRACER_NAME = 'langfuse-sdk';\n\nexport type LangfuseTraceMetadata = Record<string, string>;\n\ntype LangfuseHandlerParams = {\n userId?: string;\n sessionId?: string;\n traceMetadata?: LangfuseTraceMetadata;\n tags?: string[];\n};\n\ntype AgentLangfuseHandlerParams = LangfuseHandlerParams & {\n langfuse?: t.LangfuseConfig;\n};\n\ntype ResolvedLangfuseConfig = t.LangfuseConfig & {\n enabled: true;\n publicKey: string;\n secretKey: string;\n};\n\nfunction getEnvLangfuseBaseUrl(): string | undefined {\n return process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL;\n}\n\nfunction createTraceMetadata(\n metadata: Record<string, unknown>\n): LangfuseTraceMetadata {\n const traceMetadata: LangfuseTraceMetadata = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (value == null) {\n continue;\n }\n const stringValue = typeof value === 'string' ? value : String(value);\n if (\n stringValue.trim() === '' ||\n stringValue.length > TRACE_METADATA_MAX_LENGTH\n ) {\n continue;\n }\n traceMetadata[key] = stringValue;\n }\n return traceMetadata;\n}\n\nexport function createLangfuseTraceMetadata({\n messageId,\n parentMessageId,\n agentId,\n agentName,\n}: {\n messageId?: unknown;\n parentMessageId?: unknown;\n agentId?: unknown;\n agentName?: unknown;\n}): LangfuseTraceMetadata {\n return createTraceMetadata({\n messageId,\n parentMessageId,\n agentId,\n agentName,\n });\n}\n\nfunction getModelName(serialized: Serialized): string {\n const serializedRecord = serialized as unknown as Record<string, unknown>;\n const kwargs = serializedRecord.kwargs as Record<string, unknown> | undefined;\n const modelName =\n kwargs?.model ??\n kwargs?.model_name ??\n kwargs?.modelName ??\n kwargs?.model_id ??\n kwargs?.modelId ??\n serializedRecord.name;\n\n if (typeof modelName === 'string' && modelName.trim() !== '') {\n return modelName;\n }\n\n if (Array.isArray(serializedRecord.id) && serializedRecord.id.length > 0) {\n return String(serializedRecord.id[serializedRecord.id.length - 1]);\n }\n\n return 'ChatModel';\n}\n\nfunction getModelParameters(\n extraParams?: Record<string, unknown>\n): Record<string, string | number> {\n const invocationParams = extraParams?.invocation_params;\n const params =\n invocationParams != null && typeof invocationParams === 'object'\n ? (invocationParams as Record<string, unknown>)\n : (extraParams ?? {});\n\n return Object.fromEntries(\n Object.entries(params).filter(([, value]) => {\n return typeof value === 'string' || typeof value === 'number';\n })\n ) as Record<string, string | number>;\n}\n\nfunction getOutput(output: LLMResult): unknown {\n return output.generations.map((generation) =>\n generation.map((item) => {\n if ('message' in item && item.message != null) {\n return (item.message as { content?: unknown }).content;\n }\n return item.text;\n })\n );\n}\n\nfunction getUsageDetails(\n output: LLMResult\n): Record<string, number> | undefined {\n const llmOutput = output.llmOutput as Record<string, unknown> | undefined;\n const usage = llmOutput?.tokenUsage ?? llmOutput?.usage;\n if (usage == null || typeof usage !== 'object') {\n return undefined;\n }\n\n const usageEntries = Object.entries(usage as Record<string, unknown>).filter(\n ([, value]) => typeof value === 'number'\n );\n\n return usageEntries.length > 0\n ? (Object.fromEntries(usageEntries) as Record<string, number>)\n : undefined;\n}\n\nexport function getLangfuseTraceName(\n traceMetadata?: LangfuseTraceMetadata,\n fallback: string = 'LibreChat Agent'\n): string {\n const agentName = traceMetadata?.agentName;\n return isPresent(agentName) ? `${fallback}: ${agentName}` : fallback;\n}\n\nfunction getTraceAttributes({\n userId,\n sessionId,\n traceMetadata,\n tags,\n}: LangfuseHandlerParams): Attributes {\n const attributes: Attributes = {\n [LangfuseOtelSpanAttributes.TRACE_NAME]:\n getLangfuseTraceName(traceMetadata),\n };\n\n if (isPresent(userId)) {\n attributes[LangfuseOtelSpanAttributes.TRACE_USER_ID] = userId;\n }\n if (isPresent(sessionId)) {\n attributes[LangfuseOtelSpanAttributes.TRACE_SESSION_ID] = sessionId;\n }\n if (tags != null && tags.length > 0) {\n attributes[LangfuseOtelSpanAttributes.TRACE_TAGS] = tags;\n }\n for (const [key, value] of Object.entries(traceMetadata ?? {})) {\n attributes[`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`] = value;\n }\n\n return attributes;\n}\n\nexport class LangfuseAgentCallbackHandler extends BaseCallbackHandler {\n name = 'librechat_langfuse_agent_handler';\n\n private readonly provider: BasicTracerProvider;\n private readonly processor: LangfuseSpanProcessor;\n private readonly userId?: string;\n private readonly sessionId?: string;\n private readonly traceMetadata?: LangfuseTraceMetadata;\n private readonly tags?: string[];\n private readonly spans = new Map<string, Span>();\n\n constructor({\n langfuse,\n userId,\n sessionId,\n traceMetadata,\n tags,\n }: LangfuseHandlerParams & { langfuse: ResolvedLangfuseConfig }) {\n super();\n this.userId = userId;\n this.sessionId = sessionId;\n this.traceMetadata = traceMetadata;\n this.tags = tags;\n this.processor = new LangfuseSpanProcessor({\n publicKey: langfuse.publicKey,\n secretKey: langfuse.secretKey,\n ...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),\n environment:\n process.env.LANGFUSE_TRACING_ENVIRONMENT ??\n process.env.NODE_ENV ??\n 'development',\n exportMode: 'immediate',\n shouldExportSpan: ({ otelSpan }): boolean =>\n isDefaultExportSpan(otelSpan) ||\n otelSpan.instrumentationScope.name === LANGFUSE_TRACER_NAME,\n });\n this.provider = new BasicTracerProvider({\n spanProcessors: [this.processor],\n });\n }\n\n private startGenerationSpan({\n llm,\n input,\n runId,\n extraParams,\n metadata,\n name,\n }: {\n llm: Serialized;\n input: unknown;\n runId: string;\n extraParams?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n name?: string;\n }): void {\n if (this.spans.has(runId)) {\n return;\n }\n\n const tracer = this.provider.getTracer(LANGFUSE_TRACER_NAME);\n const spanName =\n typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);\n const span = tracer.startSpan(spanName, {\n attributes: {\n ...getTraceAttributes({\n userId: this.userId,\n sessionId: this.sessionId,\n traceMetadata: this.traceMetadata,\n tags: this.tags,\n }),\n ...createObservationAttributes('generation', {\n input,\n model: getModelName(llm),\n modelParameters: getModelParameters(extraParams),\n metadata: {\n ...metadata,\n ...this.traceMetadata,\n },\n }),\n },\n });\n this.spans.set(runId, span);\n }\n\n async handleChatModelStart(\n llm: Serialized,\n messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n extraParams?: Record<string, unknown>,\n _tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ): Promise<void> {\n this.startGenerationSpan({\n llm,\n input: messages,\n runId,\n extraParams,\n metadata,\n name,\n });\n }\n\n async handleLLMStart(\n llm: Serialized,\n prompts: string[],\n runId: string,\n _parentRunId?: string,\n extraParams?: Record<string, unknown>,\n _tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ): Promise<void> {\n this.startGenerationSpan({\n llm,\n input: prompts,\n runId,\n extraParams,\n metadata,\n name,\n });\n }\n\n async handleLLMEnd(output: LLMResult, runId: string): Promise<void> {\n const span = this.spans.get(runId);\n if (!span) {\n return;\n }\n\n span.setAttributes(\n createObservationAttributes('generation', {\n output: getOutput(output),\n usageDetails: getUsageDetails(output),\n })\n );\n span.end();\n this.spans.delete(runId);\n await this.flush();\n }\n\n async handleLLMError(err: unknown, runId: string): Promise<void> {\n const span = this.spans.get(runId);\n if (!span) {\n return;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n span.setStatus({ code: SpanStatusCode.ERROR, message });\n span.setAttributes(\n createObservationAttributes('generation', {\n level: 'ERROR',\n statusMessage: message,\n })\n );\n span.end();\n this.spans.delete(runId);\n await this.flush();\n }\n\n private async flush(): Promise<void> {\n try {\n await this.provider.forceFlush();\n } catch (error) {\n process.emitWarning(\n `[LangfuseAgentCallbackHandler] Failed to flush Langfuse spans: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n }\n\n async dispose(): Promise<void> {\n for (const span of this.spans.values()) {\n span.end();\n }\n this.spans.clear();\n await this.flush();\n try {\n await this.provider.shutdown();\n } catch (error) {\n process.emitWarning(\n `[LangfuseAgentCallbackHandler] Failed to shut down Langfuse provider: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n }\n}\n\nfunction hasRequiredLangfuseConfig(\n langfuse?: t.LangfuseConfig\n): langfuse is ResolvedLangfuseConfig {\n return (\n langfuse?.enabled === true &&\n isPresent(langfuse.publicKey) &&\n isPresent(langfuse.secretKey)\n );\n}\n\nexport function createLegacyLangfuseHandler(\n params: LangfuseHandlerParams\n): CallbackHandler {\n return new CallbackHandler(params);\n}\n\nexport function createLangfuseHandler({\n langfuse,\n userId,\n sessionId,\n traceMetadata,\n tags,\n}: AgentLangfuseHandlerParams): LangfuseAgentCallbackHandler | undefined {\n if (!hasRequiredLangfuseConfig(langfuse)) {\n return undefined;\n }\n\n return new LangfuseAgentCallbackHandler({\n langfuse,\n userId,\n sessionId,\n traceMetadata,\n tags,\n });\n}\n\nexport function hasExplicitLangfuseConfig(\n contexts: Iterable<{ langfuse?: t.LangfuseConfig }>\n): boolean {\n for (const context of contexts) {\n if (context.langfuse != null) {\n return true;\n }\n }\n return false;\n}\n\nexport function hasLangfuseEnvConfig(): boolean {\n return (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(getEnvLangfuseBaseUrl())\n );\n}\n\nexport function isLangfuseCallbackHandler(value: unknown): boolean {\n return (\n value instanceof CallbackHandler ||\n value instanceof LangfuseAgentCallbackHandler\n );\n}\n\nexport async function disposeLangfuseHandler(value: unknown): Promise<void> {\n if (value instanceof LangfuseAgentCallbackHandler) {\n await value.dispose();\n }\n}\n"],"names":["isPresent","LangfuseOtelSpanAttributes","BaseCallbackHandler","LangfuseSpanProcessor","isDefaultExportSpan","BasicTracerProvider","createObservationAttributes","SpanStatusCode","CallbackHandler"],"mappings":";;;;;;;;;;AAgBA,MAAM,yBAAyB,GAAG,GAAG;AACrC,MAAM,oBAAoB,GAAG,cAAc;AAqB3C,SAAS,qBAAqB,GAAA;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;AACtE;AAEA,SAAS,mBAAmB,CAC1B,QAAiC,EAAA;IAEjC,MAAM,aAAa,GAA0B,EAAE;AAC/C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AACnD,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB;QACF;AACA,QAAA,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrE,QAAA,IACE,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;AACzB,YAAA,WAAW,CAAC,MAAM,GAAG,yBAAyB,EAC9C;YACA;QACF;AACA,QAAA,aAAa,CAAC,GAAG,CAAC,GAAG,WAAW;IAClC;AACA,IAAA,OAAO,aAAa;AACtB;AAEM,SAAU,2BAA2B,CAAC,EAC1C,SAAS,EACT,eAAe,EACf,OAAO,EACP,SAAS,GAMV,EAAA;AACC,IAAA,OAAO,mBAAmB,CAAC;QACzB,SAAS;QACT,eAAe;QACf,OAAO;QACP,SAAS;AACV,KAAA,CAAC;AACJ;AAEA,SAAS,YAAY,CAAC,UAAsB,EAAA;IAC1C,MAAM,gBAAgB,GAAG,UAAgD;AACzE,IAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAA6C;AAC7E,IAAA,MAAM,SAAS,GACb,MAAM,EAAE,KAAK;AACb,QAAA,MAAM,EAAE,UAAU;AAClB,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,MAAM,EAAE,OAAO;QACf,gBAAgB,CAAC,IAAI;AAEvB,IAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AAC5D,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;AACxE,QAAA,OAAO,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpE;AAEA,IAAA,OAAO,WAAW;AACpB;AAEA,SAAS,kBAAkB,CACzB,WAAqC,EAAA;AAErC,IAAA,MAAM,gBAAgB,GAAG,WAAW,EAAE,iBAAiB;IACvD,MAAM,MAAM,GACV,gBAAgB,IAAI,IAAI,IAAI,OAAO,gBAAgB,KAAK;AACtD,UAAG;AACH,WAAG,WAAW,IAAI,EAAE,CAAC;AAEzB,IAAA,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,KAAI;QAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;IAC/D,CAAC,CAAC,CACgC;AACtC;AAEA,SAAS,SAAS,CAAC,MAAiB,EAAA;AAClC,IAAA,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,KACvC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;QACtB,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE;AAC7C,YAAA,OAAQ,IAAI,CAAC,OAAiC,CAAC,OAAO;QACxD;QACA,OAAO,IAAI,CAAC,IAAI;IAClB,CAAC,CAAC,CACH;AACH;AAEA,SAAS,eAAe,CACtB,MAAiB,EAAA;AAEjB,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAgD;IACzE,MAAM,KAAK,GAAG,SAAS,EAAE,UAAU,IAAI,SAAS,EAAE,KAAK;IACvD,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC9C,QAAA,OAAO,SAAS;IAClB;IAEA,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,MAAM,CAC1E,CAAC,GAAG,KAAK,CAAC,KAAK,OAAO,KAAK,KAAK,QAAQ,CACzC;AAED,IAAA,OAAO,YAAY,CAAC,MAAM,GAAG;AAC3B,UAAG,MAAM,CAAC,WAAW,CAAC,YAAY;UAChC,SAAS;AACf;SAEgB,oBAAoB,CAClC,aAAqC,EACrC,WAAmB,iBAAiB,EAAA;AAEpC,IAAA,MAAM,SAAS,GAAG,aAAa,EAAE,SAAS;AAC1C,IAAA,OAAOA,cAAS,CAAC,SAAS,CAAC,GAAG,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE,GAAG,QAAQ;AACtE;AAEA,SAAS,kBAAkB,CAAC,EAC1B,MAAM,EACN,SAAS,EACT,aAAa,EACb,IAAI,GACkB,EAAA;AACtB,IAAA,MAAM,UAAU,GAAe;QAC7B,CAACC,kCAA0B,CAAC,UAAU,GACpC,oBAAoB,CAAC,aAAa,CAAC;KACtC;AAED,IAAA,IAAID,cAAS,CAAC,MAAM,CAAC,EAAE;AACrB,QAAA,UAAU,CAACC,kCAA0B,CAAC,aAAa,CAAC,GAAG,MAAM;IAC/D;AACA,IAAA,IAAID,cAAS,CAAC,SAAS,CAAC,EAAE;AACxB,QAAA,UAAU,CAACC,kCAA0B,CAAC,gBAAgB,CAAC,GAAG,SAAS;IACrE;IACA,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACnC,QAAA,UAAU,CAACA,kCAA0B,CAAC,UAAU,CAAC,GAAG,IAAI;IAC1D;AACA,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE;QAC9D,UAAU,CAAC,CAAA,EAAGA,kCAA0B,CAAC,cAAc,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC,GAAG,KAAK;IAC3E;AAEA,IAAA,OAAO,UAAU;AACnB;AAEM,MAAO,4BAA6B,SAAQC,wBAAmB,CAAA;IACnE,IAAI,GAAG,kCAAkC;AAExB,IAAA,QAAQ;AACR,IAAA,SAAS;AACT,IAAA,MAAM;AACN,IAAA,SAAS;AACT,IAAA,aAAa;AACb,IAAA,IAAI;AACJ,IAAA,KAAK,GAAG,IAAI,GAAG,EAAgB;IAEhD,WAAA,CAAY,EACV,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EACb,IAAI,GACyD,EAAA;AAC7D,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;AAC1B,QAAA,IAAI,CAAC,aAAa,GAAG,aAAa;AAClC,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAIC,0BAAqB,CAAC;YACzC,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,IAAIH,cAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;AACrE,YAAA,WAAW,EACT,OAAO,CAAC,GAAG,CAAC,4BAA4B;gBACxC,OAAO,CAAC,GAAG,CAAC,QAAQ;gBACpB,aAAa;AACf,YAAA,UAAU,EAAE,WAAW;YACvB,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,KAC7BI,wBAAmB,CAAC,QAAQ,CAAC;AAC7B,gBAAA,QAAQ,CAAC,oBAAoB,CAAC,IAAI,KAAK,oBAAoB;AAC9D,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAIC,gCAAmB,CAAC;AACtC,YAAA,cAAc,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;AACjC,SAAA,CAAC;IACJ;AAEQ,IAAA,mBAAmB,CAAC,EAC1B,GAAG,EACH,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAI,GAQL,EAAA;QACC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACzB;QACF;QAEA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,oBAAoB,CAAC;QAC5D,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC;AAC3E,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;AACtC,YAAA,UAAU,EAAE;AACV,gBAAA,GAAG,kBAAkB,CAAC;oBACpB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC;gBACF,GAAGC,mCAA2B,CAAC,YAAY,EAAE;oBAC3C,KAAK;AACL,oBAAA,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC;AACxB,oBAAA,eAAe,EAAE,kBAAkB,CAAC,WAAW,CAAC;AAChD,oBAAA,QAAQ,EAAE;AACR,wBAAA,GAAG,QAAQ;wBACX,GAAG,IAAI,CAAC,aAAa;AACtB,qBAAA;iBACF,CAAC;AACH,aAAA;AACF,SAAA,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC;IAC7B;AAEA,IAAA,MAAM,oBAAoB,CACxB,GAAe,EACf,QAAyB,EACzB,KAAa,EACb,YAAqB,EACrB,WAAqC,EACrC,KAAgB,EAChB,QAAkC,EAClC,IAAa,EAAA;QAEb,IAAI,CAAC,mBAAmB,CAAC;YACvB,GAAG;AACH,YAAA,KAAK,EAAE,QAAQ;YACf,KAAK;YACL,WAAW;YACX,QAAQ;YACR,IAAI;AACL,SAAA,CAAC;IACJ;AAEA,IAAA,MAAM,cAAc,CAClB,GAAe,EACf,OAAiB,EACjB,KAAa,EACb,YAAqB,EACrB,WAAqC,EACrC,KAAgB,EAChB,QAAkC,EAClC,IAAa,EAAA;QAEb,IAAI,CAAC,mBAAmB,CAAC;YACvB,GAAG;AACH,YAAA,KAAK,EAAE,OAAO;YACd,KAAK;YACL,WAAW;YACX,QAAQ;YACR,IAAI;AACL,SAAA,CAAC;IACJ;AAEA,IAAA,MAAM,YAAY,CAAC,MAAiB,EAAE,KAAa,EAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AAEA,QAAA,IAAI,CAAC,aAAa,CAChBA,mCAA2B,CAAC,YAAY,EAAE;AACxC,YAAA,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;AACzB,YAAA,YAAY,EAAE,eAAe,CAAC,MAAM,CAAC;AACtC,SAAA,CAAC,CACH;QACD,IAAI,CAAC,GAAG,EAAE;AACV,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AACxB,QAAA,MAAM,IAAI,CAAC,KAAK,EAAE;IACpB;AAEA,IAAA,MAAM,cAAc,CAAC,GAAY,EAAE,KAAa,EAAA;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC;AAChE,QAAA,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAEC,kBAAc,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;AACvD,QAAA,IAAI,CAAC,aAAa,CAChBD,mCAA2B,CAAC,YAAY,EAAE;AACxC,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,aAAa,EAAE,OAAO;AACvB,SAAA,CAAC,CACH;QACD,IAAI,CAAC,GAAG,EAAE;AACV,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AACxB,QAAA,MAAM,IAAI,CAAC,KAAK,EAAE;IACpB;AAEQ,IAAA,MAAM,KAAK,GAAA;AACjB,QAAA,IAAI;AACF,YAAA,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;QAClC;QAAE,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,WAAW,CACjB,CAAA,+DAAA,EACE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CACvD,CAAA,CAAE,CACH;QACH;IACF;AAEA,IAAA,MAAM,OAAO,GAAA;QACX,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,GAAG,EAAE;QACZ;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AAClB,QAAA,MAAM,IAAI,CAAC,KAAK,EAAE;AAClB,QAAA,IAAI;AACF,YAAA,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;QAChC;QAAE,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,WAAW,CACjB,CAAA,sEAAA,EACE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CACvD,CAAA,CAAE,CACH;QACH;IACF;AACD;AAED,SAAS,yBAAyB,CAChC,QAA2B,EAAA;AAE3B,IAAA,QACE,QAAQ,EAAE,OAAO,KAAK,IAAI;AAC1B,QAAAN,cAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAC7B,QAAAA,cAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAEjC;AAEM,SAAU,2BAA2B,CACzC,MAA6B,EAAA;AAE7B,IAAA,OAAO,IAAIQ,yBAAe,CAAC,MAAM,CAAC;AACpC;AAEM,SAAU,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EACb,IAAI,GACuB,EAAA;AAC3B,IAAA,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,EAAE;AACxC,QAAA,OAAO,SAAS;IAClB;IAEA,OAAO,IAAI,4BAA4B,CAAC;QACtC,QAAQ;QACR,MAAM;QACN,SAAS;QACT,aAAa;QACb,IAAI;AACL,KAAA,CAAC;AACJ;AAEM,SAAU,yBAAyB,CACvC,QAAmD,EAAA;AAEnD,IAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;AAC9B,QAAA,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE;AAC5B,YAAA,OAAO,IAAI;QACb;IACF;AACA,IAAA,OAAO,KAAK;AACd;SAEgB,oBAAoB,GAAA;IAClC,QACER,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,QAAAA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,QAAAA,cAAS,CAAC,qBAAqB,EAAE,CAAC;AAEtC;AAEM,SAAU,yBAAyB,CAAC,KAAc,EAAA;IACtD,QACE,KAAK,YAAYQ,yBAAe;QAChC,KAAK,YAAY,4BAA4B;AAEjD;AAEO,eAAe,sBAAsB,CAAC,KAAc,EAAA;AACzD,IAAA,IAAI,KAAK,YAAY,4BAA4B,EAAE;AACjD,QAAA,MAAM,KAAK,CAAC,OAAO,EAAE;IACvB;AACF;;;;;;;;;;;;"}
1
+ {"version":3,"file":"langfuse.cjs","sources":["../../src/langfuse.ts"],"sourcesContent":["import { getLangfuseTracerProvider } from '@langfuse/tracing';\nimport { CallbackHandler } from '@langfuse/langchain';\nimport type * as t from '@/types';\nimport { isPresent } from '@/utils/misc';\n\nconst TRACE_METADATA_MAX_LENGTH = 200;\n\nexport type LangfuseTraceMetadata = Record<string, string>;\n\ntype LangfuseHandlerParams = {\n userId?: string;\n sessionId?: string;\n traceMetadata?: LangfuseTraceMetadata;\n tags?: string[];\n};\n\ntype AgentLangfuseHandlerParams = LangfuseHandlerParams & {\n langfuse?: t.LangfuseConfig;\n};\n\ntype FlushableTracerProvider = {\n forceFlush?: () => Promise<void> | void;\n};\n\nfunction hasLangfuseTracingConfig(langfuse?: t.LangfuseConfig): boolean {\n return (\n langfuse?.toolNodeTracing != null || langfuse?.toolOutputTracing != null\n );\n}\n\nexport function hasLangfuseConfigCredentials(\n langfuse?: t.LangfuseConfig\n): langfuse is t.LangfuseConfig & {\n publicKey: string;\n secretKey: string;\n} {\n return (\n langfuse != null &&\n isPresent(langfuse.publicKey) &&\n isPresent(langfuse.secretKey)\n );\n}\n\nfunction hasLangfuseConfigBaseUrl(langfuse?: t.LangfuseConfig): boolean {\n return isPresent(langfuse?.baseUrl);\n}\n\nexport function isExplicitLangfuseConfig(\n langfuse?: t.LangfuseConfig\n): boolean {\n return (\n langfuse?.enabled != null ||\n isPresent(langfuse?.publicKey) ||\n isPresent(langfuse?.secretKey) ||\n isPresent(langfuse?.baseUrl) ||\n hasLangfuseTracingConfig(langfuse)\n );\n}\n\nfunction createTraceMetadata(\n metadata: Record<string, unknown>\n): LangfuseTraceMetadata {\n const traceMetadata: LangfuseTraceMetadata = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (value == null) {\n continue;\n }\n const stringValue = typeof value === 'string' ? value : String(value);\n if (\n stringValue.trim() === '' ||\n stringValue.length > TRACE_METADATA_MAX_LENGTH\n ) {\n continue;\n }\n traceMetadata[key] = stringValue;\n }\n return traceMetadata;\n}\n\nexport function createLangfuseTraceMetadata({\n messageId,\n parentMessageId,\n agentId,\n agentName,\n}: {\n messageId?: unknown;\n parentMessageId?: unknown;\n agentId?: unknown;\n agentName?: unknown;\n}): LangfuseTraceMetadata {\n return createTraceMetadata({\n messageId,\n parentMessageId,\n agentId,\n agentName,\n });\n}\n\nexport function getLangfuseTraceName(\n traceMetadata?: LangfuseTraceMetadata,\n fallback: string = 'LibreChat Agent'\n): string {\n const agentName = traceMetadata?.agentName;\n return isPresent(agentName) ? `${fallback}: ${agentName}` : fallback;\n}\n\nexport function hasLangfuseEnvConfig(): boolean {\n return hasLangfuseEnvCredentials();\n}\n\nexport function hasLangfuseEnvCredentials(): boolean {\n return (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY)\n );\n}\n\nexport function shouldCreateLangfuseHandler(\n langfuse?: t.LangfuseConfig\n): boolean {\n if (langfuse?.enabled === false) {\n return false;\n }\n return (\n hasLangfuseEnvConfig() ||\n hasLangfuseConfigCredentials(langfuse) ||\n (hasLangfuseConfigBaseUrl(langfuse) && hasLangfuseEnvCredentials())\n );\n}\n\nexport function createLegacyLangfuseHandler(\n params: LangfuseHandlerParams\n): CallbackHandler {\n return new CallbackHandler(params);\n}\n\nexport function createLangfuseHandler({\n langfuse,\n userId,\n sessionId,\n traceMetadata,\n tags,\n}: AgentLangfuseHandlerParams): CallbackHandler | undefined {\n if (!shouldCreateLangfuseHandler(langfuse)) {\n return undefined;\n }\n return new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n tags,\n });\n}\n\nexport function hasExplicitLangfuseConfig(\n contexts: Iterable<{ langfuse?: t.LangfuseConfig }>\n): boolean {\n for (const context of contexts) {\n if (isExplicitLangfuseConfig(context.langfuse)) {\n return true;\n }\n }\n return false;\n}\n\nexport function isLangfuseCallbackHandler(value: unknown): boolean {\n return value instanceof CallbackHandler;\n}\n\nexport async function disposeLangfuseHandler(value: unknown): Promise<void> {\n if (value == null) {\n return;\n }\n const provider = getLangfuseTracerProvider() as FlushableTracerProvider;\n await provider.forceFlush?.();\n}\n"],"names":["isPresent","CallbackHandler","getLangfuseTracerProvider"],"mappings":";;;;;;AAKA,MAAM,yBAAyB,GAAG,GAAG;AAyB/B,SAAU,4BAA4B,CAC1C,QAA2B,EAAA;IAK3B,QACE,QAAQ,IAAI,IAAI;AAChB,QAAAA,cAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAC7B,QAAAA,cAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAEjC;AAEA,SAAS,wBAAwB,CAAC,QAA2B,EAAA;AAC3D,IAAA,OAAOA,cAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;AACrC;AAcA,SAAS,mBAAmB,CAC1B,QAAiC,EAAA;IAEjC,MAAM,aAAa,GAA0B,EAAE;AAC/C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AACnD,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB;QACF;AACA,QAAA,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrE,QAAA,IACE,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;AACzB,YAAA,WAAW,CAAC,MAAM,GAAG,yBAAyB,EAC9C;YACA;QACF;AACA,QAAA,aAAa,CAAC,GAAG,CAAC,GAAG,WAAW;IAClC;AACA,IAAA,OAAO,aAAa;AACtB;AAEM,SAAU,2BAA2B,CAAC,EAC1C,SAAS,EACT,eAAe,EACf,OAAO,EACP,SAAS,GAMV,EAAA;AACC,IAAA,OAAO,mBAAmB,CAAC;QACzB,SAAS;QACT,eAAe;QACf,OAAO;QACP,SAAS;AACV,KAAA,CAAC;AACJ;SAEgB,oBAAoB,CAClC,aAAqC,EACrC,WAAmB,iBAAiB,EAAA;AAEpC,IAAA,MAAM,SAAS,GAAG,aAAa,EAAE,SAAS;AAC1C,IAAA,OAAOA,cAAS,CAAC,SAAS,CAAC,GAAG,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE,GAAG,QAAQ;AACtE;SAEgB,oBAAoB,GAAA;IAClC,OAAO,yBAAyB,EAAE;AACpC;SAEgB,yBAAyB,GAAA;IACvC,QACEA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAC1CA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAE9C;AAEM,SAAU,2BAA2B,CACzC,QAA2B,EAAA;AAE3B,IAAA,IAAI,QAAQ,EAAE,OAAO,KAAK,KAAK,EAAE;AAC/B,QAAA,OAAO,KAAK;IACd;IACA,QACE,oBAAoB,EAAE;QACtB,4BAA4B,CAAC,QAAQ,CAAC;SACrC,wBAAwB,CAAC,QAAQ,CAAC,IAAI,yBAAyB,EAAE,CAAC;AAEvE;AAQM,SAAU,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EACb,IAAI,GACuB,EAAA;AAC3B,IAAA,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,EAAE;AAC1C,QAAA,OAAO,SAAS;IAClB;IACA,OAAO,IAAIC,yBAAe,CAAC;QACzB,MAAM;QACN,SAAS;QACT,aAAa;QACb,IAAI;AACL,KAAA,CAAC;AACJ;AAaM,SAAU,yBAAyB,CAAC,KAAc,EAAA;IACtD,OAAO,KAAK,YAAYA,yBAAe;AACzC;AAEO,eAAe,sBAAsB,CAAC,KAAc,EAAA;AACzD,IAAA,IAAI,KAAK,IAAI,IAAI,EAAE;QACjB;IACF;AACA,IAAA,MAAM,QAAQ,GAAGC,iCAAyB,EAA6B;AACvE,IAAA,MAAM,QAAQ,CAAC,UAAU,IAAI;AAC/B;;;;;;;;;;;;"}