@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.
- package/dist/cjs/graphs/Graph.cjs +54 -21
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +120 -9
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +30 -226
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +465 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -0
- package/dist/cjs/main.cjs +1 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/run.cjs +142 -69
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +29 -2
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +20 -8
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +10 -6
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +56 -23
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +118 -9
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +28 -224
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +457 -0
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -0
- package/dist/esm/main.mjs +1 -1
- package/dist/esm/run.mjs +144 -71
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +29 -3
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +20 -8
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +10 -6
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +5 -1
- package/dist/types/instrumentation.d.ts +5 -1
- package/dist/types/langfuse.d.ts +6 -28
- package/dist/types/langfuseToolOutputTracing.d.ts +20 -0
- package/dist/types/run.d.ts +5 -1
- package/dist/types/tools/BashProgrammaticToolCalling.d.ts +1 -0
- package/dist/types/tools/ToolNode.d.ts +4 -1
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +2 -0
- package/dist/types/types/graph.d.ts +30 -0
- package/dist/types/types/run.d.ts +6 -0
- package/dist/types/types/tools.d.ts +7 -0
- package/package.json +2 -1
- package/src/graphs/Graph.ts +90 -34
- package/src/instrumentation.ts +172 -11
- package/src/langfuse.ts +59 -324
- package/src/langfuseToolOutputTracing.ts +683 -0
- package/src/run.ts +190 -87
- package/src/specs/langfuse-callbacks.test.ts +178 -1
- package/src/specs/langfuse-config.test.ts +112 -76
- package/src/specs/langfuse-instrumentation.test.ts +283 -0
- package/src/specs/langfuse-metadata.test.ts +54 -1
- package/src/specs/langfuse-tool-output-tracing.test.ts +588 -0
- package/src/tools/BashProgrammaticToolCalling.ts +39 -5
- package/src/tools/ToolNode.ts +28 -7
- package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +54 -0
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +72 -4
- package/src/tools/__tests__/SubagentExecutor.test.ts +32 -0
- package/src/tools/__tests__/ToolNode.langfuse.test.ts +41 -0
- package/src/tools/subagent/SubagentExecutor.ts +11 -6
- package/src/types/graph.ts +32 -0
- package/src/types/run.ts +6 -0
- package/src/types/tools.ts +7 -0
package/src/langfuse.ts
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
+
import { getLangfuseTracerProvider } from '@langfuse/tracing';
|
|
1
2
|
import { CallbackHandler } from '@langfuse/langchain';
|
|
2
|
-
import { isDefaultExportSpan, LangfuseSpanProcessor } from '@langfuse/otel';
|
|
3
|
-
import {
|
|
4
|
-
LangfuseOtelSpanAttributes,
|
|
5
|
-
createObservationAttributes,
|
|
6
|
-
} from '@langfuse/tracing';
|
|
7
|
-
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
8
|
-
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
|
|
9
|
-
import { SpanStatusCode } from '@opentelemetry/api';
|
|
10
|
-
import type { Serialized } from '@langchain/core/load/serializable';
|
|
11
|
-
import type { BaseMessage } from '@langchain/core/messages';
|
|
12
|
-
import type { LLMResult } from '@langchain/core/outputs';
|
|
13
|
-
import type { Attributes, Span } from '@opentelemetry/api';
|
|
14
3
|
import type * as t from '@/types';
|
|
15
4
|
import { isPresent } from '@/utils/misc';
|
|
16
5
|
|
|
17
6
|
const TRACE_METADATA_MAX_LENGTH = 200;
|
|
18
|
-
const LANGFUSE_TRACER_NAME = 'langfuse-sdk';
|
|
19
7
|
|
|
20
8
|
export type LangfuseTraceMetadata = Record<string, string>;
|
|
21
9
|
|
|
@@ -30,14 +18,43 @@ type AgentLangfuseHandlerParams = LangfuseHandlerParams & {
|
|
|
30
18
|
langfuse?: t.LangfuseConfig;
|
|
31
19
|
};
|
|
32
20
|
|
|
33
|
-
type
|
|
34
|
-
|
|
21
|
+
type FlushableTracerProvider = {
|
|
22
|
+
forceFlush?: () => Promise<void> | void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function hasLangfuseTracingConfig(langfuse?: t.LangfuseConfig): boolean {
|
|
26
|
+
return (
|
|
27
|
+
langfuse?.toolNodeTracing != null || langfuse?.toolOutputTracing != null
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function hasLangfuseConfigCredentials(
|
|
32
|
+
langfuse?: t.LangfuseConfig
|
|
33
|
+
): langfuse is t.LangfuseConfig & {
|
|
35
34
|
publicKey: string;
|
|
36
35
|
secretKey: string;
|
|
37
|
-
}
|
|
36
|
+
} {
|
|
37
|
+
return (
|
|
38
|
+
langfuse != null &&
|
|
39
|
+
isPresent(langfuse.publicKey) &&
|
|
40
|
+
isPresent(langfuse.secretKey)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function hasLangfuseConfigBaseUrl(langfuse?: t.LangfuseConfig): boolean {
|
|
45
|
+
return isPresent(langfuse?.baseUrl);
|
|
46
|
+
}
|
|
38
47
|
|
|
39
|
-
function
|
|
40
|
-
|
|
48
|
+
export function isExplicitLangfuseConfig(
|
|
49
|
+
langfuse?: t.LangfuseConfig
|
|
50
|
+
): boolean {
|
|
51
|
+
return (
|
|
52
|
+
langfuse?.enabled != null ||
|
|
53
|
+
isPresent(langfuse?.publicKey) ||
|
|
54
|
+
isPresent(langfuse?.secretKey) ||
|
|
55
|
+
isPresent(langfuse?.baseUrl) ||
|
|
56
|
+
hasLangfuseTracingConfig(langfuse)
|
|
57
|
+
);
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
function createTraceMetadata(
|
|
@@ -79,73 +96,6 @@ export function createLangfuseTraceMetadata({
|
|
|
79
96
|
});
|
|
80
97
|
}
|
|
81
98
|
|
|
82
|
-
function getModelName(serialized: Serialized): string {
|
|
83
|
-
const serializedRecord = serialized as unknown as Record<string, unknown>;
|
|
84
|
-
const kwargs = serializedRecord.kwargs as Record<string, unknown> | undefined;
|
|
85
|
-
const modelName =
|
|
86
|
-
kwargs?.model ??
|
|
87
|
-
kwargs?.model_name ??
|
|
88
|
-
kwargs?.modelName ??
|
|
89
|
-
kwargs?.model_id ??
|
|
90
|
-
kwargs?.modelId ??
|
|
91
|
-
serializedRecord.name;
|
|
92
|
-
|
|
93
|
-
if (typeof modelName === 'string' && modelName.trim() !== '') {
|
|
94
|
-
return modelName;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (Array.isArray(serializedRecord.id) && serializedRecord.id.length > 0) {
|
|
98
|
-
return String(serializedRecord.id[serializedRecord.id.length - 1]);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return 'ChatModel';
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function getModelParameters(
|
|
105
|
-
extraParams?: Record<string, unknown>
|
|
106
|
-
): Record<string, string | number> {
|
|
107
|
-
const invocationParams = extraParams?.invocation_params;
|
|
108
|
-
const params =
|
|
109
|
-
invocationParams != null && typeof invocationParams === 'object'
|
|
110
|
-
? (invocationParams as Record<string, unknown>)
|
|
111
|
-
: (extraParams ?? {});
|
|
112
|
-
|
|
113
|
-
return Object.fromEntries(
|
|
114
|
-
Object.entries(params).filter(([, value]) => {
|
|
115
|
-
return typeof value === 'string' || typeof value === 'number';
|
|
116
|
-
})
|
|
117
|
-
) as Record<string, string | number>;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function getOutput(output: LLMResult): unknown {
|
|
121
|
-
return output.generations.map((generation) =>
|
|
122
|
-
generation.map((item) => {
|
|
123
|
-
if ('message' in item && item.message != null) {
|
|
124
|
-
return (item.message as { content?: unknown }).content;
|
|
125
|
-
}
|
|
126
|
-
return item.text;
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function getUsageDetails(
|
|
132
|
-
output: LLMResult
|
|
133
|
-
): Record<string, number> | undefined {
|
|
134
|
-
const llmOutput = output.llmOutput as Record<string, unknown> | undefined;
|
|
135
|
-
const usage = llmOutput?.tokenUsage ?? llmOutput?.usage;
|
|
136
|
-
if (usage == null || typeof usage !== 'object') {
|
|
137
|
-
return undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const usageEntries = Object.entries(usage as Record<string, unknown>).filter(
|
|
141
|
-
([, value]) => typeof value === 'number'
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
return usageEntries.length > 0
|
|
145
|
-
? (Object.fromEntries(usageEntries) as Record<string, number>)
|
|
146
|
-
: undefined;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
99
|
export function getLangfuseTraceName(
|
|
150
100
|
traceMetadata?: LangfuseTraceMetadata,
|
|
151
101
|
fallback: string = 'LibreChat Agent'
|
|
@@ -154,231 +104,27 @@ export function getLangfuseTraceName(
|
|
|
154
104
|
return isPresent(agentName) ? `${fallback}: ${agentName}` : fallback;
|
|
155
105
|
}
|
|
156
106
|
|
|
157
|
-
function
|
|
158
|
-
|
|
159
|
-
sessionId,
|
|
160
|
-
traceMetadata,
|
|
161
|
-
tags,
|
|
162
|
-
}: LangfuseHandlerParams): Attributes {
|
|
163
|
-
const attributes: Attributes = {
|
|
164
|
-
[LangfuseOtelSpanAttributes.TRACE_NAME]:
|
|
165
|
-
getLangfuseTraceName(traceMetadata),
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
if (isPresent(userId)) {
|
|
169
|
-
attributes[LangfuseOtelSpanAttributes.TRACE_USER_ID] = userId;
|
|
170
|
-
}
|
|
171
|
-
if (isPresent(sessionId)) {
|
|
172
|
-
attributes[LangfuseOtelSpanAttributes.TRACE_SESSION_ID] = sessionId;
|
|
173
|
-
}
|
|
174
|
-
if (tags != null && tags.length > 0) {
|
|
175
|
-
attributes[LangfuseOtelSpanAttributes.TRACE_TAGS] = tags;
|
|
176
|
-
}
|
|
177
|
-
for (const [key, value] of Object.entries(traceMetadata ?? {})) {
|
|
178
|
-
attributes[`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`] = value;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return attributes;
|
|
107
|
+
export function hasLangfuseEnvConfig(): boolean {
|
|
108
|
+
return hasLangfuseEnvCredentials();
|
|
182
109
|
}
|
|
183
110
|
|
|
184
|
-
export
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
private readonly userId?: string;
|
|
190
|
-
private readonly sessionId?: string;
|
|
191
|
-
private readonly traceMetadata?: LangfuseTraceMetadata;
|
|
192
|
-
private readonly tags?: string[];
|
|
193
|
-
private readonly spans = new Map<string, Span>();
|
|
194
|
-
|
|
195
|
-
constructor({
|
|
196
|
-
langfuse,
|
|
197
|
-
userId,
|
|
198
|
-
sessionId,
|
|
199
|
-
traceMetadata,
|
|
200
|
-
tags,
|
|
201
|
-
}: LangfuseHandlerParams & { langfuse: ResolvedLangfuseConfig }) {
|
|
202
|
-
super();
|
|
203
|
-
this.userId = userId;
|
|
204
|
-
this.sessionId = sessionId;
|
|
205
|
-
this.traceMetadata = traceMetadata;
|
|
206
|
-
this.tags = tags;
|
|
207
|
-
this.processor = new LangfuseSpanProcessor({
|
|
208
|
-
publicKey: langfuse.publicKey,
|
|
209
|
-
secretKey: langfuse.secretKey,
|
|
210
|
-
...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),
|
|
211
|
-
environment:
|
|
212
|
-
process.env.LANGFUSE_TRACING_ENVIRONMENT ??
|
|
213
|
-
process.env.NODE_ENV ??
|
|
214
|
-
'development',
|
|
215
|
-
exportMode: 'immediate',
|
|
216
|
-
shouldExportSpan: ({ otelSpan }): boolean =>
|
|
217
|
-
isDefaultExportSpan(otelSpan) ||
|
|
218
|
-
otelSpan.instrumentationScope.name === LANGFUSE_TRACER_NAME,
|
|
219
|
-
});
|
|
220
|
-
this.provider = new BasicTracerProvider({
|
|
221
|
-
spanProcessors: [this.processor],
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
private startGenerationSpan({
|
|
226
|
-
llm,
|
|
227
|
-
input,
|
|
228
|
-
runId,
|
|
229
|
-
extraParams,
|
|
230
|
-
metadata,
|
|
231
|
-
name,
|
|
232
|
-
}: {
|
|
233
|
-
llm: Serialized;
|
|
234
|
-
input: unknown;
|
|
235
|
-
runId: string;
|
|
236
|
-
extraParams?: Record<string, unknown>;
|
|
237
|
-
metadata?: Record<string, unknown>;
|
|
238
|
-
name?: string;
|
|
239
|
-
}): void {
|
|
240
|
-
if (this.spans.has(runId)) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const tracer = this.provider.getTracer(LANGFUSE_TRACER_NAME);
|
|
245
|
-
const spanName =
|
|
246
|
-
typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);
|
|
247
|
-
const span = tracer.startSpan(spanName, {
|
|
248
|
-
attributes: {
|
|
249
|
-
...getTraceAttributes({
|
|
250
|
-
userId: this.userId,
|
|
251
|
-
sessionId: this.sessionId,
|
|
252
|
-
traceMetadata: this.traceMetadata,
|
|
253
|
-
tags: this.tags,
|
|
254
|
-
}),
|
|
255
|
-
...createObservationAttributes('generation', {
|
|
256
|
-
input,
|
|
257
|
-
model: getModelName(llm),
|
|
258
|
-
modelParameters: getModelParameters(extraParams),
|
|
259
|
-
metadata: {
|
|
260
|
-
...metadata,
|
|
261
|
-
...this.traceMetadata,
|
|
262
|
-
},
|
|
263
|
-
}),
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
this.spans.set(runId, span);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async handleChatModelStart(
|
|
270
|
-
llm: Serialized,
|
|
271
|
-
messages: BaseMessage[][],
|
|
272
|
-
runId: string,
|
|
273
|
-
_parentRunId?: string,
|
|
274
|
-
extraParams?: Record<string, unknown>,
|
|
275
|
-
_tags?: string[],
|
|
276
|
-
metadata?: Record<string, unknown>,
|
|
277
|
-
name?: string
|
|
278
|
-
): Promise<void> {
|
|
279
|
-
this.startGenerationSpan({
|
|
280
|
-
llm,
|
|
281
|
-
input: messages,
|
|
282
|
-
runId,
|
|
283
|
-
extraParams,
|
|
284
|
-
metadata,
|
|
285
|
-
name,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async handleLLMStart(
|
|
290
|
-
llm: Serialized,
|
|
291
|
-
prompts: string[],
|
|
292
|
-
runId: string,
|
|
293
|
-
_parentRunId?: string,
|
|
294
|
-
extraParams?: Record<string, unknown>,
|
|
295
|
-
_tags?: string[],
|
|
296
|
-
metadata?: Record<string, unknown>,
|
|
297
|
-
name?: string
|
|
298
|
-
): Promise<void> {
|
|
299
|
-
this.startGenerationSpan({
|
|
300
|
-
llm,
|
|
301
|
-
input: prompts,
|
|
302
|
-
runId,
|
|
303
|
-
extraParams,
|
|
304
|
-
metadata,
|
|
305
|
-
name,
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async handleLLMEnd(output: LLMResult, runId: string): Promise<void> {
|
|
310
|
-
const span = this.spans.get(runId);
|
|
311
|
-
if (!span) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
span.setAttributes(
|
|
316
|
-
createObservationAttributes('generation', {
|
|
317
|
-
output: getOutput(output),
|
|
318
|
-
usageDetails: getUsageDetails(output),
|
|
319
|
-
})
|
|
320
|
-
);
|
|
321
|
-
span.end();
|
|
322
|
-
this.spans.delete(runId);
|
|
323
|
-
await this.flush();
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
async handleLLMError(err: unknown, runId: string): Promise<void> {
|
|
327
|
-
const span = this.spans.get(runId);
|
|
328
|
-
if (!span) {
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
333
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
334
|
-
span.setAttributes(
|
|
335
|
-
createObservationAttributes('generation', {
|
|
336
|
-
level: 'ERROR',
|
|
337
|
-
statusMessage: message,
|
|
338
|
-
})
|
|
339
|
-
);
|
|
340
|
-
span.end();
|
|
341
|
-
this.spans.delete(runId);
|
|
342
|
-
await this.flush();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
private async flush(): Promise<void> {
|
|
346
|
-
try {
|
|
347
|
-
await this.provider.forceFlush();
|
|
348
|
-
} catch (error) {
|
|
349
|
-
process.emitWarning(
|
|
350
|
-
`[LangfuseAgentCallbackHandler] Failed to flush Langfuse spans: ${
|
|
351
|
-
error instanceof Error ? error.message : String(error)
|
|
352
|
-
}`
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
async dispose(): Promise<void> {
|
|
358
|
-
for (const span of this.spans.values()) {
|
|
359
|
-
span.end();
|
|
360
|
-
}
|
|
361
|
-
this.spans.clear();
|
|
362
|
-
await this.flush();
|
|
363
|
-
try {
|
|
364
|
-
await this.provider.shutdown();
|
|
365
|
-
} catch (error) {
|
|
366
|
-
process.emitWarning(
|
|
367
|
-
`[LangfuseAgentCallbackHandler] Failed to shut down Langfuse provider: ${
|
|
368
|
-
error instanceof Error ? error.message : String(error)
|
|
369
|
-
}`
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
111
|
+
export function hasLangfuseEnvCredentials(): boolean {
|
|
112
|
+
return (
|
|
113
|
+
isPresent(process.env.LANGFUSE_SECRET_KEY) &&
|
|
114
|
+
isPresent(process.env.LANGFUSE_PUBLIC_KEY)
|
|
115
|
+
);
|
|
373
116
|
}
|
|
374
117
|
|
|
375
|
-
function
|
|
118
|
+
export function shouldCreateLangfuseHandler(
|
|
376
119
|
langfuse?: t.LangfuseConfig
|
|
377
|
-
):
|
|
120
|
+
): boolean {
|
|
121
|
+
if (langfuse?.enabled === false) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
378
124
|
return (
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
125
|
+
hasLangfuseEnvConfig() ||
|
|
126
|
+
hasLangfuseConfigCredentials(langfuse) ||
|
|
127
|
+
(hasLangfuseConfigBaseUrl(langfuse) && hasLangfuseEnvCredentials())
|
|
382
128
|
);
|
|
383
129
|
}
|
|
384
130
|
|
|
@@ -394,13 +140,11 @@ export function createLangfuseHandler({
|
|
|
394
140
|
sessionId,
|
|
395
141
|
traceMetadata,
|
|
396
142
|
tags,
|
|
397
|
-
}: AgentLangfuseHandlerParams):
|
|
398
|
-
if (!
|
|
143
|
+
}: AgentLangfuseHandlerParams): CallbackHandler | undefined {
|
|
144
|
+
if (!shouldCreateLangfuseHandler(langfuse)) {
|
|
399
145
|
return undefined;
|
|
400
146
|
}
|
|
401
|
-
|
|
402
|
-
return new LangfuseAgentCallbackHandler({
|
|
403
|
-
langfuse,
|
|
147
|
+
return new CallbackHandler({
|
|
404
148
|
userId,
|
|
405
149
|
sessionId,
|
|
406
150
|
traceMetadata,
|
|
@@ -412,30 +156,21 @@ export function hasExplicitLangfuseConfig(
|
|
|
412
156
|
contexts: Iterable<{ langfuse?: t.LangfuseConfig }>
|
|
413
157
|
): boolean {
|
|
414
158
|
for (const context of contexts) {
|
|
415
|
-
if (context.langfuse
|
|
159
|
+
if (isExplicitLangfuseConfig(context.langfuse)) {
|
|
416
160
|
return true;
|
|
417
161
|
}
|
|
418
162
|
}
|
|
419
163
|
return false;
|
|
420
164
|
}
|
|
421
165
|
|
|
422
|
-
export function hasLangfuseEnvConfig(): boolean {
|
|
423
|
-
return (
|
|
424
|
-
isPresent(process.env.LANGFUSE_SECRET_KEY) &&
|
|
425
|
-
isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
|
|
426
|
-
isPresent(getEnvLangfuseBaseUrl())
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
166
|
export function isLangfuseCallbackHandler(value: unknown): boolean {
|
|
431
|
-
return
|
|
432
|
-
value instanceof CallbackHandler ||
|
|
433
|
-
value instanceof LangfuseAgentCallbackHandler
|
|
434
|
-
);
|
|
167
|
+
return value instanceof CallbackHandler;
|
|
435
168
|
}
|
|
436
169
|
|
|
437
170
|
export async function disposeLangfuseHandler(value: unknown): Promise<void> {
|
|
438
|
-
if (value
|
|
439
|
-
|
|
171
|
+
if (value == null) {
|
|
172
|
+
return;
|
|
440
173
|
}
|
|
174
|
+
const provider = getLangfuseTracerProvider() as FlushableTracerProvider;
|
|
175
|
+
await provider.forceFlush?.();
|
|
441
176
|
}
|