@librechat/agents 3.1.90 → 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/agents/AgentContext.cjs +9 -5
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +48 -14
- 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 +285 -0
- package/dist/cjs/langfuse.cjs.map +1 -0
- package/dist/cjs/main.cjs +25 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/run.cjs +75 -44
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +10 -3
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +380 -0
- package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -0
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +997 -0
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -0
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +575 -0
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -0
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +165 -0
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -0
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs +17 -5
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +110 -6
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/utils/callbacks.cjs +27 -0
- package/dist/cjs/utils/callbacks.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +9 -5
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +48 -14
- 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 +275 -0
- package/dist/esm/langfuse.mjs.map +1 -0
- package/dist/esm/main.mjs +5 -1
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/run.mjs +75 -44
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +10 -3
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +378 -0
- package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -0
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +994 -0
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -0
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +566 -0
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -0
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +155 -0
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -0
- package/dist/esm/tools/local/LocalExecutionEngine.mjs +17 -6
- package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +111 -7
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/utils/callbacks.mjs +24 -0
- package/dist/esm/utils/callbacks.mjs.map +1 -0
- package/dist/types/agents/AgentContext.d.ts +4 -1
- package/dist/types/graphs/Graph.d.ts +6 -5
- package/dist/types/index.d.ts +1 -0
- package/dist/types/langfuse.d.ts +57 -0
- package/dist/types/tools/cloudflare/CloudflareBridgeRuntime.d.ts +23 -0
- package/dist/types/tools/cloudflare/CloudflareProgrammaticToolCalling.d.ts +4 -0
- package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +21 -0
- package/dist/types/tools/cloudflare/CloudflareSandboxTools.d.ts +22 -0
- package/dist/types/tools/cloudflare/index.d.ts +4 -0
- package/dist/types/tools/local/LocalExecutionEngine.d.ts +1 -0
- package/dist/types/types/graph.d.ts +8 -0
- package/dist/types/types/run.d.ts +2 -2
- package/dist/types/types/tools.d.ts +118 -2
- package/dist/types/utils/callbacks.d.ts +5 -0
- package/package.json +4 -4
- package/src/__tests__/stream.eagerEventExecution.test.ts +66 -0
- package/src/agents/AgentContext.ts +13 -3
- package/src/graphs/Graph.ts +57 -16
- package/src/index.ts +1 -0
- package/src/instrumentation.ts +2 -7
- package/src/langfuse.ts +441 -0
- package/src/run.ts +105 -59
- package/src/specs/langfuse-callbacks.test.ts +75 -0
- package/src/specs/langfuse-config.test.ts +114 -0
- package/src/specs/langfuse-metadata.test.ts +19 -1
- package/src/stream.ts +13 -3
- package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +537 -0
- package/src/tools/cloudflare/CloudflareBridgeRuntime.ts +480 -0
- package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +1162 -0
- package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +744 -0
- package/src/tools/cloudflare/CloudflareSandboxTools.ts +225 -0
- package/src/tools/cloudflare/index.ts +4 -0
- package/src/tools/local/LocalExecutionEngine.ts +20 -4
- package/src/tools/local/resolveLocalExecutionTools.ts +169 -7
- package/src/types/graph.ts +9 -0
- package/src/types/run.ts +2 -7
- package/src/types/tools.ts +141 -2
- package/src/utils/callbacks.ts +39 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { CallbackHandler } from '@langfuse/langchain';
|
|
2
|
+
import { LangfuseSpanProcessor, isDefaultExportSpan } from '@langfuse/otel';
|
|
3
|
+
import { createObservationAttributes, LangfuseOtelSpanAttributes } from '@langfuse/tracing';
|
|
4
|
+
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
5
|
+
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
|
|
6
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
7
|
+
import { isPresent } from './utils/misc.mjs';
|
|
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
|
+
}
|
|
37
|
+
function getModelName(serialized) {
|
|
38
|
+
const serializedRecord = serialized;
|
|
39
|
+
const kwargs = serializedRecord.kwargs;
|
|
40
|
+
const modelName = kwargs?.model ??
|
|
41
|
+
kwargs?.model_name ??
|
|
42
|
+
kwargs?.modelName ??
|
|
43
|
+
kwargs?.model_id ??
|
|
44
|
+
kwargs?.modelId ??
|
|
45
|
+
serializedRecord.name;
|
|
46
|
+
if (typeof modelName === 'string' && modelName.trim() !== '') {
|
|
47
|
+
return modelName;
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(serializedRecord.id) && serializedRecord.id.length > 0) {
|
|
50
|
+
return String(serializedRecord.id[serializedRecord.id.length - 1]);
|
|
51
|
+
}
|
|
52
|
+
return 'ChatModel';
|
|
53
|
+
}
|
|
54
|
+
function getModelParameters(extraParams) {
|
|
55
|
+
const invocationParams = extraParams?.invocation_params;
|
|
56
|
+
const params = invocationParams != null && typeof invocationParams === 'object'
|
|
57
|
+
? invocationParams
|
|
58
|
+
: (extraParams ?? {});
|
|
59
|
+
return Object.fromEntries(Object.entries(params).filter(([, value]) => {
|
|
60
|
+
return typeof value === 'string' || typeof value === 'number';
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
function getOutput(output) {
|
|
64
|
+
return output.generations.map((generation) => generation.map((item) => {
|
|
65
|
+
if ('message' in item && item.message != null) {
|
|
66
|
+
return item.message.content;
|
|
67
|
+
}
|
|
68
|
+
return item.text;
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
function getUsageDetails(output) {
|
|
72
|
+
const llmOutput = output.llmOutput;
|
|
73
|
+
const usage = llmOutput?.tokenUsage ?? llmOutput?.usage;
|
|
74
|
+
if (usage == null || typeof usage !== 'object') {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
const usageEntries = Object.entries(usage).filter(([, value]) => typeof value === 'number');
|
|
78
|
+
return usageEntries.length > 0
|
|
79
|
+
? Object.fromEntries(usageEntries)
|
|
80
|
+
: undefined;
|
|
81
|
+
}
|
|
82
|
+
function getLangfuseTraceName(traceMetadata, fallback = 'LibreChat Agent') {
|
|
83
|
+
const agentName = traceMetadata?.agentName;
|
|
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;
|
|
103
|
+
}
|
|
104
|
+
class LangfuseAgentCallbackHandler extends BaseCallbackHandler {
|
|
105
|
+
name = 'librechat_langfuse_agent_handler';
|
|
106
|
+
provider;
|
|
107
|
+
processor;
|
|
108
|
+
userId;
|
|
109
|
+
sessionId;
|
|
110
|
+
traceMetadata;
|
|
111
|
+
tags;
|
|
112
|
+
spans = new Map();
|
|
113
|
+
constructor({ langfuse, userId, sessionId, traceMetadata, tags, }) {
|
|
114
|
+
super();
|
|
115
|
+
this.userId = userId;
|
|
116
|
+
this.sessionId = sessionId;
|
|
117
|
+
this.traceMetadata = traceMetadata;
|
|
118
|
+
this.tags = tags;
|
|
119
|
+
this.processor = new LangfuseSpanProcessor({
|
|
120
|
+
publicKey: langfuse.publicKey,
|
|
121
|
+
secretKey: langfuse.secretKey,
|
|
122
|
+
...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),
|
|
123
|
+
environment: process.env.LANGFUSE_TRACING_ENVIRONMENT ??
|
|
124
|
+
process.env.NODE_ENV ??
|
|
125
|
+
'development',
|
|
126
|
+
exportMode: 'immediate',
|
|
127
|
+
shouldExportSpan: ({ otelSpan }) => isDefaultExportSpan(otelSpan) ||
|
|
128
|
+
otelSpan.instrumentationScope.name === LANGFUSE_TRACER_NAME,
|
|
129
|
+
});
|
|
130
|
+
this.provider = new BasicTracerProvider({
|
|
131
|
+
spanProcessors: [this.processor],
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
startGenerationSpan({ llm, input, runId, extraParams, metadata, name, }) {
|
|
135
|
+
if (this.spans.has(runId)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const tracer = this.provider.getTracer(LANGFUSE_TRACER_NAME);
|
|
139
|
+
const spanName = typeof name === 'string' && name.trim() !== '' ? name : getModelName(llm);
|
|
140
|
+
const span = tracer.startSpan(spanName, {
|
|
141
|
+
attributes: {
|
|
142
|
+
...getTraceAttributes({
|
|
143
|
+
userId: this.userId,
|
|
144
|
+
sessionId: this.sessionId,
|
|
145
|
+
traceMetadata: this.traceMetadata,
|
|
146
|
+
tags: this.tags,
|
|
147
|
+
}),
|
|
148
|
+
...createObservationAttributes('generation', {
|
|
149
|
+
input,
|
|
150
|
+
model: getModelName(llm),
|
|
151
|
+
modelParameters: getModelParameters(extraParams),
|
|
152
|
+
metadata: {
|
|
153
|
+
...metadata,
|
|
154
|
+
...this.traceMetadata,
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
this.spans.set(runId, span);
|
|
160
|
+
}
|
|
161
|
+
async handleChatModelStart(llm, messages, runId, _parentRunId, extraParams, _tags, metadata, name) {
|
|
162
|
+
this.startGenerationSpan({
|
|
163
|
+
llm,
|
|
164
|
+
input: messages,
|
|
165
|
+
runId,
|
|
166
|
+
extraParams,
|
|
167
|
+
metadata,
|
|
168
|
+
name,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async handleLLMStart(llm, prompts, runId, _parentRunId, extraParams, _tags, metadata, name) {
|
|
172
|
+
this.startGenerationSpan({
|
|
173
|
+
llm,
|
|
174
|
+
input: prompts,
|
|
175
|
+
runId,
|
|
176
|
+
extraParams,
|
|
177
|
+
metadata,
|
|
178
|
+
name,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async handleLLMEnd(output, runId) {
|
|
182
|
+
const span = this.spans.get(runId);
|
|
183
|
+
if (!span) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
span.setAttributes(createObservationAttributes('generation', {
|
|
187
|
+
output: getOutput(output),
|
|
188
|
+
usageDetails: getUsageDetails(output),
|
|
189
|
+
}));
|
|
190
|
+
span.end();
|
|
191
|
+
this.spans.delete(runId);
|
|
192
|
+
await this.flush();
|
|
193
|
+
}
|
|
194
|
+
async handleLLMError(err, runId) {
|
|
195
|
+
const span = this.spans.get(runId);
|
|
196
|
+
if (!span) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
200
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
201
|
+
span.setAttributes(createObservationAttributes('generation', {
|
|
202
|
+
level: 'ERROR',
|
|
203
|
+
statusMessage: message,
|
|
204
|
+
}));
|
|
205
|
+
span.end();
|
|
206
|
+
this.spans.delete(runId);
|
|
207
|
+
await this.flush();
|
|
208
|
+
}
|
|
209
|
+
async flush() {
|
|
210
|
+
try {
|
|
211
|
+
await this.provider.forceFlush();
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
process.emitWarning(`[LangfuseAgentCallbackHandler] Failed to flush Langfuse spans: ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async dispose() {
|
|
218
|
+
for (const span of this.spans.values()) {
|
|
219
|
+
span.end();
|
|
220
|
+
}
|
|
221
|
+
this.spans.clear();
|
|
222
|
+
await this.flush();
|
|
223
|
+
try {
|
|
224
|
+
await this.provider.shutdown();
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
process.emitWarning(`[LangfuseAgentCallbackHandler] Failed to shut down Langfuse provider: ${error instanceof Error ? error.message : String(error)}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function hasRequiredLangfuseConfig(langfuse) {
|
|
232
|
+
return (langfuse?.enabled === true &&
|
|
233
|
+
isPresent(langfuse.publicKey) &&
|
|
234
|
+
isPresent(langfuse.secretKey));
|
|
235
|
+
}
|
|
236
|
+
function createLegacyLangfuseHandler(params) {
|
|
237
|
+
return new CallbackHandler(params);
|
|
238
|
+
}
|
|
239
|
+
function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, tags, }) {
|
|
240
|
+
if (!hasRequiredLangfuseConfig(langfuse)) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
return new LangfuseAgentCallbackHandler({
|
|
244
|
+
langfuse,
|
|
245
|
+
userId,
|
|
246
|
+
sessionId,
|
|
247
|
+
traceMetadata,
|
|
248
|
+
tags,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function hasExplicitLangfuseConfig(contexts) {
|
|
252
|
+
for (const context of contexts) {
|
|
253
|
+
if (context.langfuse != null) {
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
function hasLangfuseEnvConfig() {
|
|
260
|
+
return (isPresent(process.env.LANGFUSE_SECRET_KEY) &&
|
|
261
|
+
isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
|
|
262
|
+
isPresent(getEnvLangfuseBaseUrl()));
|
|
263
|
+
}
|
|
264
|
+
function isLangfuseCallbackHandler(value) {
|
|
265
|
+
return (value instanceof CallbackHandler ||
|
|
266
|
+
value instanceof LangfuseAgentCallbackHandler);
|
|
267
|
+
}
|
|
268
|
+
async function disposeLangfuseHandler(value) {
|
|
269
|
+
if (value instanceof LangfuseAgentCallbackHandler) {
|
|
270
|
+
await value.dispose();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export { LangfuseAgentCallbackHandler, createLangfuseHandler, createLangfuseTraceMetadata, createLegacyLangfuseHandler, disposeLangfuseHandler, getLangfuseTraceName, hasExplicitLangfuseConfig, hasLangfuseEnvConfig, isLangfuseCallbackHandler };
|
|
275
|
+
//# sourceMappingURL=langfuse.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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/main.mjs
CHANGED
|
@@ -34,7 +34,7 @@ export { handleServerToolResult, handleToolCallChunks, handleToolCalls, toolResu
|
|
|
34
34
|
export { CompileCheckToolName, createCompileCheckTool, createCompileCheckToolDefinition } from './tools/local/CompileCheckTool.mjs';
|
|
35
35
|
export { LocalFileCheckpointerImpl, createLocalFileCheckpointer } from './tools/local/FileCheckpointer.mjs';
|
|
36
36
|
export { LocalEditFileToolName, LocalEditFileToolSchema, LocalGlobSearchToolName, LocalGlobSearchToolSchema, LocalGrepSearchToolName, LocalGrepSearchToolSchema, LocalListDirectoryToolName, LocalListDirectoryToolSchema, LocalReadFileToolSchema, LocalWriteFileToolName, LocalWriteFileToolSchema, _resetRipgrepCacheForTests, createLocalCodingToolBundle, createLocalCodingToolDefinitions, createLocalCodingToolRegistry, createLocalCodingTools, createLocalEditFileTool, createLocalGlobSearchTool, createLocalGrepSearchTool, createLocalListDirectoryTool, createLocalReadFileTool, createLocalWriteFileTool } from './tools/local/LocalCodingTools.mjs';
|
|
37
|
-
export { _resetLocalEngineWarningsForTests, buildSandboxRuntimeConfig, executeLocalBash, executeLocalBashWithArgs, executeLocalCode, getLocalCwd, getLocalSessionId, getReadRoots, getSpawn, getWorkspaceFS, getWorkspaceRoots, getWriteRoots, resolveLocalExecutionConfig, resolveWorkspacePath, resolveWorkspacePathSafe, shellQuote, spawnLocalProcess, truncateLocalOutput, validateBashCommand } from './tools/local/LocalExecutionEngine.mjs';
|
|
37
|
+
export { LOCAL_SPAWN_TIMEOUT_MS, _resetLocalEngineWarningsForTests, buildSandboxRuntimeConfig, executeLocalBash, executeLocalBashWithArgs, executeLocalCode, getLocalCwd, getLocalSessionId, getReadRoots, getSpawn, getWorkspaceFS, getWorkspaceRoots, getWriteRoots, resolveLocalExecutionConfig, resolveWorkspacePath, resolveWorkspacePathSafe, shellQuote, spawnLocalProcess, truncateLocalOutput, validateBashCommand } from './tools/local/LocalExecutionEngine.mjs';
|
|
38
38
|
export { LocalBashExecutionToolDescription, LocalCodeExecutionToolDescription, createLocalBashExecutionTool, createLocalCodeExecutionTool } from './tools/local/LocalExecutionTools.mjs';
|
|
39
39
|
export { _createBashProgramForTests, applyPreToolUseHooksForBridge, createLocalBashProgrammaticToolCallingTool, createLocalProgrammaticToolCallingTool } from './tools/local/LocalProgrammaticToolCalling.mjs';
|
|
40
40
|
export { resolveLocalExecutionTools, resolveLocalToolRegistry, resolveLocalToolsForBinding } from './tools/local/resolveLocalExecutionTools.mjs';
|
|
@@ -43,6 +43,10 @@ export { bashAstFindingsToErrors, runBashAstChecks } from './tools/local/bashAst
|
|
|
43
43
|
export { applyEdit, locateEdit } from './tools/local/editStrategies.mjs';
|
|
44
44
|
export { _resetSyntaxCheckProbeCacheForTests, runPostEditSyntaxCheck } from './tools/local/syntaxCheck.mjs';
|
|
45
45
|
export { decodeFile, encodeFile } from './tools/local/textEncoding.mjs';
|
|
46
|
+
export { createCloudflareBridgeRuntime } from './tools/cloudflare/CloudflareBridgeRuntime.mjs';
|
|
47
|
+
export { createCloudflareBashProgrammaticToolCallingTool, createCloudflareProgrammaticToolCallingTool } from './tools/cloudflare/CloudflareProgrammaticToolCalling.mjs';
|
|
48
|
+
export { createCloudflareLocalExecutionConfig, createCloudflareWorkspaceFS, executeCloudflareBash, executeCloudflareCode, formatCloudflareOutput, getCloudflareWorkspaceRoot, resolveCloudflareSandbox, validateCloudflareBashCommand } from './tools/cloudflare/CloudflareSandboxExecutionEngine.mjs';
|
|
49
|
+
export { CLOUDFLARE_BASH_CODING_TOOL_NAMES, CLOUDFLARE_CODING_TOOL_NAMES, CloudflareBashExecutionToolDescription, CloudflareCodeExecutionToolDescription, createCloudflareBashExecutionTool, createCloudflareCodeExecutionTool, createCloudflareCodingToolBundle, createCloudflareCodingTools, createCloudflareExecutionTool } from './tools/cloudflare/CloudflareSandboxTools.mjs';
|
|
46
50
|
export { createSearchTool } from './tools/search/tool.mjs';
|
|
47
51
|
export { DATE_RANGE, DEFAULT_COUNTRY_DESCRIPTION, DEFAULT_QUERY_DESCRIPTION, WebSearchToolDefinition, WebSearchToolDescription, WebSearchToolName, WebSearchToolSchema, countrySchema, dateSchema, imagesSchema, newsSchema, querySchema, videosSchema } from './tools/search/schema.mjs';
|
|
48
52
|
export { ANTHROPIC_TOOL_TOKEN_MULTIPLIER, DEFAULT_TOOL_TOKEN_MULTIPLIER } from './common/constants.mjs';
|
package/dist/esm/main.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/esm/run.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import './instrumentation.mjs';
|
|
2
|
-
import { CallbackHandler } from '@langfuse/langchain';
|
|
3
2
|
import { PromptTemplate } from '@langchain/core/prompts';
|
|
4
3
|
import { RunnableLambda } from '@langchain/core/runnables';
|
|
5
4
|
import { ChatOpenAI as ChatOpenAI$1, AzureChatOpenAI as AzureChatOpenAI$1 } from '@langchain/openai';
|
|
@@ -16,7 +15,8 @@ import { HandlerRegistry } from './events.mjs';
|
|
|
16
15
|
import { executeHooks } from './hooks/executeHooks.mjs';
|
|
17
16
|
import './hooks/createWorkspacePolicyHook.mjs';
|
|
18
17
|
import { isOpenAILike } from './utils/llm.mjs';
|
|
19
|
-
import {
|
|
18
|
+
import { appendCallbacks, findCallback } from './utils/callbacks.mjs';
|
|
19
|
+
import { hasLangfuseEnvConfig, hasExplicitLangfuseConfig, createLangfuseTraceMetadata, createLegacyLangfuseHandler, getLangfuseTraceName, createLangfuseHandler, isLangfuseCallbackHandler, disposeLangfuseHandler } from './langfuse.mjs';
|
|
20
20
|
|
|
21
21
|
// src/run.ts
|
|
22
22
|
const defaultOmitOptions = new Set([
|
|
@@ -461,34 +461,36 @@ class Run {
|
|
|
461
461
|
this.hookRegistry?.clearHaltSignal(this.id);
|
|
462
462
|
/** Custom event callback to intercept and handle custom events */
|
|
463
463
|
const customEventCallback = this.createCustomEventCallback();
|
|
464
|
-
const baseCallbacks = config.callbacks ?? [];
|
|
465
464
|
const streamCallbacks = streamOptions?.callbacks
|
|
466
465
|
? this.getCallbacks(streamOptions.callbacks)
|
|
467
|
-
:
|
|
466
|
+
: undefined;
|
|
468
467
|
const customHandler = BaseCallbackHandler.fromMethods({
|
|
469
468
|
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
470
469
|
});
|
|
471
470
|
customHandler.awaitHandlers = true;
|
|
472
|
-
config.callbacks =
|
|
473
|
-
|
|
474
|
-
.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const
|
|
479
|
-
|
|
471
|
+
config.callbacks = appendCallbacks(config.callbacks, streamCallbacks ? [streamCallbacks, customHandler] : [customHandler]);
|
|
472
|
+
if (hasLangfuseEnvConfig() &&
|
|
473
|
+
!hasExplicitLangfuseConfig(this.Graph.agentContexts.values())) {
|
|
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;
|
|
480
480
|
const primaryContext = this.Graph.agentContexts.get(this.Graph.defaultAgentId);
|
|
481
|
-
const traceMetadata = {
|
|
481
|
+
const traceMetadata = createLangfuseTraceMetadata({
|
|
482
482
|
messageId: this.id,
|
|
483
483
|
parentMessageId: config.configurable?.requestBody?.parentMessageId,
|
|
484
484
|
agentName: primaryContext?.name,
|
|
485
|
-
};
|
|
486
|
-
const handler =
|
|
485
|
+
});
|
|
486
|
+
const handler = createLegacyLangfuseHandler({
|
|
487
487
|
userId,
|
|
488
488
|
sessionId,
|
|
489
489
|
traceMetadata,
|
|
490
|
+
tags: ['librechat', 'agent'],
|
|
490
491
|
});
|
|
491
|
-
config.
|
|
492
|
+
config.runName = config.runName ?? getLangfuseTraceName(traceMetadata);
|
|
493
|
+
config.callbacks = appendCallbacks(config.callbacks, [handler]);
|
|
492
494
|
}
|
|
493
495
|
if (!this.id) {
|
|
494
496
|
throw new Error('Run ID not provided');
|
|
@@ -887,23 +889,46 @@ class Run {
|
|
|
887
889
|
};
|
|
888
890
|
}
|
|
889
891
|
async generateTitle({ provider, inputText, contentParts, titlePrompt, clientOptions, chainOptions, skipLanguage, titleMethod = TitleMethod.COMPLETION, titlePromptTemplate, }) {
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
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');
|
|
901
|
+
if (chainOptions != null) {
|
|
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;
|
|
908
|
+
const hasExplicitLangfuse = this.Graph != null &&
|
|
909
|
+
hasExplicitLangfuseConfig(this.Graph.agentContexts.values());
|
|
910
|
+
if (titleContext?.langfuse != null) {
|
|
911
|
+
titleLangfuseHandler = createLangfuseHandler({
|
|
912
|
+
langfuse: titleContext.langfuse,
|
|
913
|
+
userId,
|
|
914
|
+
sessionId,
|
|
915
|
+
traceMetadata,
|
|
916
|
+
tags: ['librechat', 'title'],
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
else if (hasLangfuseEnvConfig() && !hasExplicitLangfuse) {
|
|
920
|
+
titleLangfuseHandler = createLegacyLangfuseHandler({
|
|
921
|
+
userId,
|
|
922
|
+
sessionId,
|
|
923
|
+
traceMetadata,
|
|
924
|
+
tags: ['librechat', 'title'],
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
if (titleLangfuseHandler != null) {
|
|
928
|
+
chainOptions.callbacks = appendCallbacks(chainOptions.callbacks, [
|
|
929
|
+
titleLangfuseHandler,
|
|
930
|
+
]);
|
|
931
|
+
}
|
|
907
932
|
}
|
|
908
933
|
const convoTemplate = PromptTemplate.fromTemplate(titlePromptTemplate ?? 'User: {input}\nAI: {output}');
|
|
909
934
|
const response = contentParts
|
|
@@ -947,19 +972,25 @@ class Run {
|
|
|
947
972
|
const invokeConfig = Object.assign({}, chainOptions, {
|
|
948
973
|
run_id: this.id,
|
|
949
974
|
runId: this.id,
|
|
975
|
+
runName: chainOptions?.runName ?? titleRunName,
|
|
950
976
|
});
|
|
951
977
|
try {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
978
|
+
try {
|
|
979
|
+
return await fullChain.invoke({ input: inputText, output: response }, invokeConfig);
|
|
980
|
+
}
|
|
981
|
+
catch (_e) {
|
|
982
|
+
// Fallback: strip callbacks to avoid EventStream tracer errors in certain environments
|
|
983
|
+
// but preserve Langfuse tracing if it exists.
|
|
984
|
+
const langfuseHandler = findCallback(invokeConfig.callbacks, isLangfuseCallbackHandler);
|
|
985
|
+
const { callbacks: _cb, ...rest } = invokeConfig;
|
|
986
|
+
const safeConfig = Object.assign({}, rest, {
|
|
987
|
+
callbacks: langfuseHandler ? [langfuseHandler] : [],
|
|
988
|
+
});
|
|
989
|
+
return await fullChain.invoke({ input: inputText, output: response }, safeConfig);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
finally {
|
|
993
|
+
await disposeLangfuseHandler(titleLangfuseHandler);
|
|
963
994
|
}
|
|
964
995
|
}
|
|
965
996
|
}
|