@librechat/agents 3.1.91 → 3.1.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/graphs/Graph.cjs +5 -3
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +2 -7
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +62 -11
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/run.cjs +33 -19
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/utils/callbacks.cjs +27 -0
- package/dist/cjs/utils/callbacks.cjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +6 -4
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +2 -7
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +63 -14
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/run.mjs +34 -20
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/utils/callbacks.mjs +24 -0
- package/dist/esm/utils/callbacks.mjs.map +1 -0
- package/dist/types/langfuse.d.ts +13 -4
- package/dist/types/types/run.d.ts +2 -2
- package/dist/types/utils/callbacks.d.ts +5 -0
- package/package.json +4 -4
- package/src/graphs/Graph.ts +10 -6
- package/src/instrumentation.ts +2 -7
- package/src/langfuse.ts +98 -15
- package/src/run.ts +53 -29
- package/src/specs/langfuse-callbacks.test.ts +75 -0
- package/src/specs/langfuse-config.test.ts +58 -1
- package/src/types/run.ts +2 -7
- package/src/utils/callbacks.ts +39 -0
package/dist/esm/langfuse.mjs
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
import { CallbackHandler } from '@langfuse/langchain';
|
|
2
|
-
import { LangfuseSpanProcessor } from '@langfuse/otel';
|
|
3
|
-
import { createObservationAttributes,
|
|
2
|
+
import { LangfuseSpanProcessor, isDefaultExportSpan } from '@langfuse/otel';
|
|
3
|
+
import { createObservationAttributes, LangfuseOtelSpanAttributes } from '@langfuse/tracing';
|
|
4
4
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
5
5
|
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
|
|
6
6
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
7
7
|
import { isPresent } from './utils/misc.mjs';
|
|
8
8
|
|
|
9
|
+
const TRACE_METADATA_MAX_LENGTH = 200;
|
|
10
|
+
const LANGFUSE_TRACER_NAME = 'langfuse-sdk';
|
|
11
|
+
function getEnvLangfuseBaseUrl() {
|
|
12
|
+
return process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL;
|
|
13
|
+
}
|
|
14
|
+
function createTraceMetadata(metadata) {
|
|
15
|
+
const traceMetadata = {};
|
|
16
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
17
|
+
if (value == null) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const stringValue = typeof value === 'string' ? value : String(value);
|
|
21
|
+
if (stringValue.trim() === '' ||
|
|
22
|
+
stringValue.length > TRACE_METADATA_MAX_LENGTH) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
traceMetadata[key] = stringValue;
|
|
26
|
+
}
|
|
27
|
+
return traceMetadata;
|
|
28
|
+
}
|
|
29
|
+
function createLangfuseTraceMetadata({ messageId, parentMessageId, agentId, agentName, }) {
|
|
30
|
+
return createTraceMetadata({
|
|
31
|
+
messageId,
|
|
32
|
+
parentMessageId,
|
|
33
|
+
agentId,
|
|
34
|
+
agentName,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
9
37
|
function getModelName(serialized) {
|
|
10
38
|
const serializedRecord = serialized;
|
|
11
39
|
const kwargs = serializedRecord.kwargs;
|
|
@@ -51,11 +79,27 @@ function getUsageDetails(output) {
|
|
|
51
79
|
? Object.fromEntries(usageEntries)
|
|
52
80
|
: undefined;
|
|
53
81
|
}
|
|
54
|
-
function
|
|
82
|
+
function getLangfuseTraceName(traceMetadata, fallback = 'LibreChat Agent') {
|
|
55
83
|
const agentName = traceMetadata?.agentName;
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
84
|
+
return isPresent(agentName) ? `${fallback}: ${agentName}` : fallback;
|
|
85
|
+
}
|
|
86
|
+
function getTraceAttributes({ userId, sessionId, traceMetadata, tags, }) {
|
|
87
|
+
const attributes = {
|
|
88
|
+
[LangfuseOtelSpanAttributes.TRACE_NAME]: getLangfuseTraceName(traceMetadata),
|
|
89
|
+
};
|
|
90
|
+
if (isPresent(userId)) {
|
|
91
|
+
attributes[LangfuseOtelSpanAttributes.TRACE_USER_ID] = userId;
|
|
92
|
+
}
|
|
93
|
+
if (isPresent(sessionId)) {
|
|
94
|
+
attributes[LangfuseOtelSpanAttributes.TRACE_SESSION_ID] = sessionId;
|
|
95
|
+
}
|
|
96
|
+
if (tags != null && tags.length > 0) {
|
|
97
|
+
attributes[LangfuseOtelSpanAttributes.TRACE_TAGS] = tags;
|
|
98
|
+
}
|
|
99
|
+
for (const [key, value] of Object.entries(traceMetadata ?? {})) {
|
|
100
|
+
attributes[`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`] = value;
|
|
101
|
+
}
|
|
102
|
+
return attributes;
|
|
59
103
|
}
|
|
60
104
|
class LangfuseAgentCallbackHandler extends BaseCallbackHandler {
|
|
61
105
|
name = 'librechat_langfuse_agent_handler';
|
|
@@ -64,12 +108,14 @@ class LangfuseAgentCallbackHandler extends BaseCallbackHandler {
|
|
|
64
108
|
userId;
|
|
65
109
|
sessionId;
|
|
66
110
|
traceMetadata;
|
|
111
|
+
tags;
|
|
67
112
|
spans = new Map();
|
|
68
|
-
constructor({ langfuse, userId, sessionId, traceMetadata, }) {
|
|
113
|
+
constructor({ langfuse, userId, sessionId, traceMetadata, tags, }) {
|
|
69
114
|
super();
|
|
70
115
|
this.userId = userId;
|
|
71
116
|
this.sessionId = sessionId;
|
|
72
117
|
this.traceMetadata = traceMetadata;
|
|
118
|
+
this.tags = tags;
|
|
73
119
|
this.processor = new LangfuseSpanProcessor({
|
|
74
120
|
publicKey: langfuse.publicKey,
|
|
75
121
|
secretKey: langfuse.secretKey,
|
|
@@ -78,6 +124,8 @@ class LangfuseAgentCallbackHandler extends BaseCallbackHandler {
|
|
|
78
124
|
process.env.NODE_ENV ??
|
|
79
125
|
'development',
|
|
80
126
|
exportMode: 'immediate',
|
|
127
|
+
shouldExportSpan: ({ otelSpan }) => isDefaultExportSpan(otelSpan) ||
|
|
128
|
+
otelSpan.instrumentationScope.name === LANGFUSE_TRACER_NAME,
|
|
81
129
|
});
|
|
82
130
|
this.provider = new BasicTracerProvider({
|
|
83
131
|
spanProcessors: [this.processor],
|
|
@@ -87,15 +135,15 @@ class LangfuseAgentCallbackHandler extends BaseCallbackHandler {
|
|
|
87
135
|
if (this.spans.has(runId)) {
|
|
88
136
|
return;
|
|
89
137
|
}
|
|
90
|
-
const tracer = this.provider.getTracer(
|
|
138
|
+
const tracer = this.provider.getTracer(LANGFUSE_TRACER_NAME);
|
|
91
139
|
const spanName = typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);
|
|
92
140
|
const span = tracer.startSpan(spanName, {
|
|
93
141
|
attributes: {
|
|
94
|
-
...
|
|
95
|
-
name: getTraceName(this.traceMetadata),
|
|
142
|
+
...getTraceAttributes({
|
|
96
143
|
userId: this.userId,
|
|
97
144
|
sessionId: this.sessionId,
|
|
98
|
-
|
|
145
|
+
traceMetadata: this.traceMetadata,
|
|
146
|
+
tags: this.tags,
|
|
99
147
|
}),
|
|
100
148
|
...createObservationAttributes('generation', {
|
|
101
149
|
input,
|
|
@@ -188,7 +236,7 @@ function hasRequiredLangfuseConfig(langfuse) {
|
|
|
188
236
|
function createLegacyLangfuseHandler(params) {
|
|
189
237
|
return new CallbackHandler(params);
|
|
190
238
|
}
|
|
191
|
-
function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, }) {
|
|
239
|
+
function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, tags, }) {
|
|
192
240
|
if (!hasRequiredLangfuseConfig(langfuse)) {
|
|
193
241
|
return undefined;
|
|
194
242
|
}
|
|
@@ -197,6 +245,7 @@ function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, })
|
|
|
197
245
|
userId,
|
|
198
246
|
sessionId,
|
|
199
247
|
traceMetadata,
|
|
248
|
+
tags,
|
|
200
249
|
});
|
|
201
250
|
}
|
|
202
251
|
function hasExplicitLangfuseConfig(contexts) {
|
|
@@ -210,7 +259,7 @@ function hasExplicitLangfuseConfig(contexts) {
|
|
|
210
259
|
function hasLangfuseEnvConfig() {
|
|
211
260
|
return (isPresent(process.env.LANGFUSE_SECRET_KEY) &&
|
|
212
261
|
isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
|
|
213
|
-
isPresent(
|
|
262
|
+
isPresent(getEnvLangfuseBaseUrl()));
|
|
214
263
|
}
|
|
215
264
|
function isLangfuseCallbackHandler(value) {
|
|
216
265
|
return (value instanceof CallbackHandler ||
|
|
@@ -222,5 +271,5 @@ async function disposeLangfuseHandler(value) {
|
|
|
222
271
|
}
|
|
223
272
|
}
|
|
224
273
|
|
|
225
|
-
export { LangfuseAgentCallbackHandler, createLangfuseHandler, createLegacyLangfuseHandler, disposeLangfuseHandler, hasExplicitLangfuseConfig, hasLangfuseEnvConfig, isLangfuseCallbackHandler };
|
|
274
|
+
export { LangfuseAgentCallbackHandler, createLangfuseHandler, createLangfuseTraceMetadata, createLegacyLangfuseHandler, disposeLangfuseHandler, getLangfuseTraceName, hasExplicitLangfuseConfig, hasLangfuseEnvConfig, isLangfuseCallbackHandler };
|
|
226
275
|
//# sourceMappingURL=langfuse.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langfuse.mjs","sources":["../../src/langfuse.ts"],"sourcesContent":["import { CallbackHandler } from '@langfuse/langchain';\nimport { LangfuseSpanProcessor } from '@langfuse/otel';\nimport {\n createObservationAttributes,\n createTraceAttributes,\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 { Span } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport { isPresent } from '@/utils/misc';\n\ntype TraceMetadata = Record<string, unknown>;\n\ntype LangfuseHandlerParams = {\n userId?: string;\n sessionId?: string;\n traceMetadata?: TraceMetadata;\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 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\nfunction getTraceName(traceMetadata?: TraceMetadata): string {\n const agentName = traceMetadata?.agentName;\n return typeof agentName === 'string' && agentName.trim() !== ''\n ? `LibreChat Agent: ${agentName}`\n : 'LibreChat Agent';\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?: TraceMetadata;\n private readonly spans = new Map<string, Span>();\n\n constructor({\n langfuse,\n userId,\n sessionId,\n traceMetadata,\n }: LangfuseHandlerParams & { langfuse: ResolvedLangfuseConfig }) {\n super();\n this.userId = userId;\n this.sessionId = sessionId;\n this.traceMetadata = traceMetadata;\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 });\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('librechat-agents-langfuse');\n const spanName =\n typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);\n const span = tracer.startSpan(spanName, {\n attributes: {\n ...createTraceAttributes({\n name: getTraceName(this.traceMetadata),\n userId: this.userId,\n sessionId: this.sessionId,\n metadata: this.traceMetadata,\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}: 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 });\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(process.env.LANGFUSE_BASE_URL)\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":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"langfuse.mjs","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":[],"mappings":"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"}
|
package/dist/esm/run.mjs
CHANGED
|
@@ -15,7 +15,8 @@ import { HandlerRegistry } from './events.mjs';
|
|
|
15
15
|
import { executeHooks } from './hooks/executeHooks.mjs';
|
|
16
16
|
import './hooks/createWorkspacePolicyHook.mjs';
|
|
17
17
|
import { isOpenAILike } from './utils/llm.mjs';
|
|
18
|
-
import {
|
|
18
|
+
import { appendCallbacks, findCallback } from './utils/callbacks.mjs';
|
|
19
|
+
import { hasLangfuseEnvConfig, hasExplicitLangfuseConfig, createLangfuseTraceMetadata, createLegacyLangfuseHandler, getLangfuseTraceName, createLangfuseHandler, isLangfuseCallbackHandler, disposeLangfuseHandler } from './langfuse.mjs';
|
|
19
20
|
|
|
20
21
|
// src/run.ts
|
|
21
22
|
const defaultOmitOptions = new Set([
|
|
@@ -460,33 +461,36 @@ class Run {
|
|
|
460
461
|
this.hookRegistry?.clearHaltSignal(this.id);
|
|
461
462
|
/** Custom event callback to intercept and handle custom events */
|
|
462
463
|
const customEventCallback = this.createCustomEventCallback();
|
|
463
|
-
const baseCallbacks = config.callbacks ?? [];
|
|
464
464
|
const streamCallbacks = streamOptions?.callbacks
|
|
465
465
|
? this.getCallbacks(streamOptions.callbacks)
|
|
466
|
-
:
|
|
466
|
+
: undefined;
|
|
467
467
|
const customHandler = BaseCallbackHandler.fromMethods({
|
|
468
468
|
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
469
469
|
});
|
|
470
470
|
customHandler.awaitHandlers = true;
|
|
471
|
-
config.callbacks =
|
|
472
|
-
.concat(streamCallbacks)
|
|
473
|
-
.concat(customHandler);
|
|
471
|
+
config.callbacks = appendCallbacks(config.callbacks, streamCallbacks ? [streamCallbacks, customHandler] : [customHandler]);
|
|
474
472
|
if (hasLangfuseEnvConfig() &&
|
|
475
473
|
!hasExplicitLangfuseConfig(this.Graph.agentContexts.values())) {
|
|
476
|
-
const userId = config.configurable?.user_id
|
|
477
|
-
|
|
474
|
+
const userId = typeof config.configurable?.user_id === 'string'
|
|
475
|
+
? config.configurable.user_id
|
|
476
|
+
: undefined;
|
|
477
|
+
const sessionId = typeof config.configurable?.thread_id === 'string'
|
|
478
|
+
? config.configurable.thread_id
|
|
479
|
+
: undefined;
|
|
478
480
|
const primaryContext = this.Graph.agentContexts.get(this.Graph.defaultAgentId);
|
|
479
|
-
const traceMetadata = {
|
|
481
|
+
const traceMetadata = createLangfuseTraceMetadata({
|
|
480
482
|
messageId: this.id,
|
|
481
483
|
parentMessageId: config.configurable?.requestBody?.parentMessageId,
|
|
482
484
|
agentName: primaryContext?.name,
|
|
483
|
-
};
|
|
485
|
+
});
|
|
484
486
|
const handler = createLegacyLangfuseHandler({
|
|
485
487
|
userId,
|
|
486
488
|
sessionId,
|
|
487
489
|
traceMetadata,
|
|
490
|
+
tags: ['librechat', 'agent'],
|
|
488
491
|
});
|
|
489
|
-
config.
|
|
492
|
+
config.runName = config.runName ?? getLangfuseTraceName(traceMetadata);
|
|
493
|
+
config.callbacks = appendCallbacks(config.callbacks, [handler]);
|
|
490
494
|
}
|
|
491
495
|
if (!this.id) {
|
|
492
496
|
throw new Error('Run ID not provided');
|
|
@@ -886,14 +890,21 @@ class Run {
|
|
|
886
890
|
}
|
|
887
891
|
async generateTitle({ provider, inputText, contentParts, titlePrompt, clientOptions, chainOptions, skipLanguage, titleMethod = TitleMethod.COMPLETION, titlePromptTemplate, }) {
|
|
888
892
|
let titleLangfuseHandler;
|
|
893
|
+
const titleContext = this.Graph == null
|
|
894
|
+
? undefined
|
|
895
|
+
: this.Graph.agentContexts.get(this.Graph.defaultAgentId);
|
|
896
|
+
const traceMetadata = createLangfuseTraceMetadata({
|
|
897
|
+
messageId: 'title-' + this.id,
|
|
898
|
+
agentName: titleContext?.name,
|
|
899
|
+
});
|
|
900
|
+
const titleRunName = getLangfuseTraceName(traceMetadata, 'LibreChat Title');
|
|
889
901
|
if (chainOptions != null) {
|
|
890
|
-
const userId = chainOptions.configurable?.user_id
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
};
|
|
902
|
+
const userId = typeof chainOptions.configurable?.user_id === 'string'
|
|
903
|
+
? chainOptions.configurable.user_id
|
|
904
|
+
: undefined;
|
|
905
|
+
const sessionId = typeof chainOptions.configurable?.thread_id === 'string'
|
|
906
|
+
? chainOptions.configurable.thread_id
|
|
907
|
+
: undefined;
|
|
897
908
|
const hasExplicitLangfuse = this.Graph != null &&
|
|
898
909
|
hasExplicitLangfuseConfig(this.Graph.agentContexts.values());
|
|
899
910
|
if (titleContext?.langfuse != null) {
|
|
@@ -902,6 +913,7 @@ class Run {
|
|
|
902
913
|
userId,
|
|
903
914
|
sessionId,
|
|
904
915
|
traceMetadata,
|
|
916
|
+
tags: ['librechat', 'title'],
|
|
905
917
|
});
|
|
906
918
|
}
|
|
907
919
|
else if (hasLangfuseEnvConfig() && !hasExplicitLangfuse) {
|
|
@@ -909,10 +921,11 @@ class Run {
|
|
|
909
921
|
userId,
|
|
910
922
|
sessionId,
|
|
911
923
|
traceMetadata,
|
|
924
|
+
tags: ['librechat', 'title'],
|
|
912
925
|
});
|
|
913
926
|
}
|
|
914
927
|
if (titleLangfuseHandler != null) {
|
|
915
|
-
chainOptions.callbacks = (chainOptions.callbacks
|
|
928
|
+
chainOptions.callbacks = appendCallbacks(chainOptions.callbacks, [
|
|
916
929
|
titleLangfuseHandler,
|
|
917
930
|
]);
|
|
918
931
|
}
|
|
@@ -959,6 +972,7 @@ class Run {
|
|
|
959
972
|
const invokeConfig = Object.assign({}, chainOptions, {
|
|
960
973
|
run_id: this.id,
|
|
961
974
|
runId: this.id,
|
|
975
|
+
runName: chainOptions?.runName ?? titleRunName,
|
|
962
976
|
});
|
|
963
977
|
try {
|
|
964
978
|
try {
|
|
@@ -967,7 +981,7 @@ class Run {
|
|
|
967
981
|
catch (_e) {
|
|
968
982
|
// Fallback: strip callbacks to avoid EventStream tracer errors in certain environments
|
|
969
983
|
// but preserve Langfuse tracing if it exists.
|
|
970
|
-
const langfuseHandler = invokeConfig.callbacks
|
|
984
|
+
const langfuseHandler = findCallback(invokeConfig.callbacks, isLangfuseCallbackHandler);
|
|
971
985
|
const { callbacks: _cb, ...rest } = invokeConfig;
|
|
972
986
|
const safeConfig = Object.assign({}, rest, {
|
|
973
987
|
callbacks: langfuseHandler ? [langfuseHandler] : [],
|