@librechat/agents 3.1.96 → 3.1.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/cjs/graphs/Graph.cjs +60 -21
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/instrumentation.cjs +120 -9
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/langfuse.cjs +30 -226
  6. package/dist/cjs/langfuse.cjs.map +1 -1
  7. package/dist/cjs/langfuseToolOutputTracing.cjs +476 -0
  8. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -0
  9. package/dist/cjs/llm/bedrock/index.cjs +10 -0
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/toolCache.cjs +125 -0
  12. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -0
  13. package/dist/cjs/messages/cache.cjs +17 -9
  14. package/dist/cjs/messages/cache.cjs.map +1 -1
  15. package/dist/cjs/run.cjs +142 -69
  16. package/dist/cjs/run.cjs.map +1 -1
  17. package/dist/cjs/tools/ToolNode.cjs +26 -9
  18. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  19. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +10 -6
  20. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  21. package/dist/esm/graphs/Graph.mjs +62 -23
  22. package/dist/esm/graphs/Graph.mjs.map +1 -1
  23. package/dist/esm/instrumentation.mjs +118 -9
  24. package/dist/esm/instrumentation.mjs.map +1 -1
  25. package/dist/esm/langfuse.mjs +28 -224
  26. package/dist/esm/langfuse.mjs.map +1 -1
  27. package/dist/esm/langfuseToolOutputTracing.mjs +468 -0
  28. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -0
  29. package/dist/esm/llm/bedrock/index.mjs +10 -0
  30. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  31. package/dist/esm/llm/bedrock/toolCache.mjs +122 -0
  32. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -0
  33. package/dist/esm/messages/cache.mjs +17 -9
  34. package/dist/esm/messages/cache.mjs.map +1 -1
  35. package/dist/esm/run.mjs +144 -71
  36. package/dist/esm/run.mjs.map +1 -1
  37. package/dist/esm/tools/ToolNode.mjs +26 -9
  38. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  39. package/dist/esm/tools/subagent/SubagentExecutor.mjs +10 -6
  40. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  41. package/dist/types/graphs/Graph.d.ts +5 -1
  42. package/dist/types/instrumentation.d.ts +5 -1
  43. package/dist/types/langfuse.d.ts +6 -28
  44. package/dist/types/langfuseToolOutputTracing.d.ts +20 -0
  45. package/dist/types/llm/bedrock/index.d.ts +16 -0
  46. package/dist/types/llm/bedrock/toolCache.d.ts +4 -0
  47. package/dist/types/messages/cache.d.ts +2 -2
  48. package/dist/types/run.d.ts +5 -1
  49. package/dist/types/tools/ToolNode.d.ts +4 -1
  50. package/dist/types/tools/subagent/SubagentExecutor.d.ts +2 -0
  51. package/dist/types/types/graph.d.ts +30 -0
  52. package/dist/types/types/llm.d.ts +2 -2
  53. package/dist/types/types/run.d.ts +6 -0
  54. package/dist/types/types/tools.d.ts +7 -0
  55. package/package.json +2 -1
  56. package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +332 -0
  57. package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +504 -0
  58. package/src/graphs/Graph.ts +104 -34
  59. package/src/instrumentation.ts +172 -11
  60. package/src/langfuse.ts +59 -324
  61. package/src/langfuseToolOutputTracing.ts +702 -0
  62. package/src/llm/bedrock/index.ts +32 -1
  63. package/src/llm/bedrock/llm.spec.ts +154 -1
  64. package/src/llm/bedrock/toolCache.test.ts +131 -0
  65. package/src/llm/bedrock/toolCache.ts +191 -0
  66. package/src/messages/cache.test.ts +97 -38
  67. package/src/messages/cache.ts +18 -10
  68. package/src/run.ts +190 -87
  69. package/src/specs/langfuse-callbacks.test.ts +178 -1
  70. package/src/specs/langfuse-config.test.ts +112 -76
  71. package/src/specs/langfuse-instrumentation.test.ts +283 -0
  72. package/src/specs/langfuse-metadata.test.ts +54 -1
  73. package/src/specs/langfuse-tool-output-tracing.test.ts +616 -0
  74. package/src/tools/ToolNode.ts +35 -8
  75. package/src/tools/__tests__/SubagentExecutor.test.ts +32 -0
  76. package/src/tools/__tests__/ToolNode.langfuse.test.ts +47 -0
  77. package/src/tools/subagent/SubagentExecutor.ts +11 -6
  78. package/src/types/graph.ts +32 -0
  79. package/src/types/llm.ts +2 -2
  80. package/src/types/run.ts +6 -0
  81. package/src/types/tools.ts +7 -0
@@ -0,0 +1,476 @@
1
+ 'use strict';
2
+
3
+ var api = require('@opentelemetry/api');
4
+ var otel = require('@langfuse/otel');
5
+ var tracing = require('@langfuse/tracing');
6
+ var node_async_hooks = require('node:async_hooks');
7
+
8
+ const LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT = '[tool output redacted]';
9
+ const langfuseToolOutputTracingConfigKey = api.createContextKey('librechat.langfuse.tool-output-tracing');
10
+ const langfuseConfigKey = api.createContextKey('librechat.langfuse.config');
11
+ const toolOutputTracingStorage = new node_async_hooks.AsyncLocalStorage();
12
+ const langfuseConfigStorage = new node_async_hooks.AsyncLocalStorage();
13
+ const LANGGRAPH_TOOL_NODE_PREFIX = 'tools=';
14
+ const CHAT_ROLES = new Set([
15
+ 'assistant',
16
+ 'developer',
17
+ 'human',
18
+ 'system',
19
+ 'user',
20
+ ]);
21
+ const TOOL_OUTPUT_FIELD_KEYS = ['content', 'artifact'];
22
+ function isRecord(value) {
23
+ return value != null && typeof value === 'object' && !Array.isArray(value);
24
+ }
25
+ function isPresent(value) {
26
+ return typeof value === 'string' && value.trim() !== '';
27
+ }
28
+ function parseBoolean(value) {
29
+ if (value == null) {
30
+ return undefined;
31
+ }
32
+ const normalized = value.trim().toLowerCase();
33
+ if (['1', 'true', 'yes', 'on'].includes(normalized)) {
34
+ return true;
35
+ }
36
+ if (['0', 'false', 'no', 'off'].includes(normalized)) {
37
+ return false;
38
+ }
39
+ return undefined;
40
+ }
41
+ function normalizeToolName(name) {
42
+ return name.trim().toLowerCase();
43
+ }
44
+ function normalizeToolNames(names) {
45
+ const normalized = new Set();
46
+ for (const name of names ?? []) {
47
+ if (isPresent(name)) {
48
+ normalized.add(normalizeToolName(name));
49
+ }
50
+ }
51
+ return normalized;
52
+ }
53
+ function parseToolNames(value) {
54
+ if (!isPresent(value)) {
55
+ return undefined;
56
+ }
57
+ return value
58
+ .split(',')
59
+ .map((name) => name.trim())
60
+ .filter((name) => name !== '');
61
+ }
62
+ function getEnvToolOutputTracingEnabled() {
63
+ const traceToolOutputs = parseBoolean(process.env.LANGFUSE_TRACE_TOOL_OUTPUTS);
64
+ if (traceToolOutputs != null) {
65
+ return traceToolOutputs;
66
+ }
67
+ const redactToolOutputs = parseBoolean(process.env.LANGFUSE_REDACT_TOOL_OUTPUTS);
68
+ if (redactToolOutputs != null) {
69
+ return !redactToolOutputs;
70
+ }
71
+ return parseBoolean(process.env.LANGFUSE_TOOL_OUTPUT_TRACING_ENABLED);
72
+ }
73
+ function getEnvRedactedToolNames() {
74
+ return (parseToolNames(process.env.LANGFUSE_REDACT_TOOL_OUTPUT_NAMES) ??
75
+ parseToolNames(process.env.LANGFUSE_REDACT_TOOL_NAMES));
76
+ }
77
+ function getEnvRedactionText() {
78
+ return isPresent(process.env.LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT)
79
+ ? process.env.LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT
80
+ : undefined;
81
+ }
82
+ function getEnvToolNameMatchMode() {
83
+ const mode = (process.env.LANGFUSE_REDACT_TOOL_OUTPUT_NAME_MATCH_MODE ??
84
+ process.env.LANGFUSE_REDACT_TOOL_NAME_MATCH_MODE)
85
+ ?.trim()
86
+ .toLowerCase();
87
+ if (mode === 'exact' || mode === 'partial') {
88
+ return mode;
89
+ }
90
+ return undefined;
91
+ }
92
+ function resolveToolOutputTracingConfig(runLangfuse, agentLangfuse) {
93
+ const runConfig = runLangfuse?.toolOutputTracing;
94
+ const agentConfig = agentLangfuse?.toolOutputTracing;
95
+ return {
96
+ enabled: agentConfig?.enabled ??
97
+ runConfig?.enabled ??
98
+ getEnvToolOutputTracingEnabled() ??
99
+ true,
100
+ redactedToolNames: normalizeToolNames(agentConfig?.redactedToolNames ??
101
+ runConfig?.redactedToolNames ??
102
+ getEnvRedactedToolNames()),
103
+ redactedToolNameMatchMode: agentConfig?.redactedToolNameMatchMode ??
104
+ runConfig?.redactedToolNameMatchMode ??
105
+ getEnvToolNameMatchMode() ??
106
+ 'exact',
107
+ redactionText: agentConfig?.redactionText ??
108
+ runConfig?.redactionText ??
109
+ getEnvRedactionText() ??
110
+ LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT,
111
+ };
112
+ }
113
+ function shouldApplyToolOutputRedaction(config) {
114
+ return config.enabled === false || config.redactedToolNames.size > 0;
115
+ }
116
+ function toolNameMatches(toolName, config) {
117
+ if (!isPresent(toolName)) {
118
+ return false;
119
+ }
120
+ const normalizedToolName = normalizeToolName(toolName);
121
+ if (config.redactedToolNameMatchMode === 'partial') {
122
+ for (const redactedToolName of config.redactedToolNames) {
123
+ if (normalizedToolName.includes(redactedToolName)) {
124
+ return true;
125
+ }
126
+ }
127
+ return false;
128
+ }
129
+ return config.redactedToolNames.has(normalizedToolName);
130
+ }
131
+ function shouldRedactTool(toolName, config) {
132
+ return config.enabled === false || toolNameMatches(toolName, config);
133
+ }
134
+ function getStringField(value, key) {
135
+ const field = value[key];
136
+ return typeof field === 'string' ? field : undefined;
137
+ }
138
+ function getNestedStringField(value, objectKey, fieldKey) {
139
+ const nested = value[objectKey];
140
+ if (!isRecord(nested)) {
141
+ return undefined;
142
+ }
143
+ return getStringField(nested, fieldKey);
144
+ }
145
+ function getSerializedToolCallId(value) {
146
+ return (getStringField(value, 'tool_call_id') ??
147
+ getNestedStringField(value, 'kwargs', 'tool_call_id') ??
148
+ getNestedStringField(value, 'additional_kwargs', 'tool_call_id') ??
149
+ getNestedStringField(value, 'data', 'tool_call_id') ??
150
+ (typeof value.id === 'string' ? value.id : undefined));
151
+ }
152
+ function getSerializedToolName(value, redactionContext) {
153
+ const role = getStringField(value, 'role');
154
+ const explicitName = getStringField(value, 'name') ??
155
+ getStringField(value, 'tool_name') ??
156
+ getNestedStringField(value, 'function', 'name') ??
157
+ getNestedStringField(value, 'kwargs', 'name') ??
158
+ getNestedStringField(value, 'additional_kwargs', 'name') ??
159
+ getNestedStringField(value, 'data', 'name') ??
160
+ (role != null && role.toLowerCase() !== 'tool' ? role : undefined);
161
+ if (explicitName != null) {
162
+ return explicitName;
163
+ }
164
+ const toolCallId = getSerializedToolCallId(value);
165
+ return toolCallId != null
166
+ ? redactionContext?.toolNamesByCallId.get(toolCallId)
167
+ : undefined;
168
+ }
169
+ function hasToolMessageIdentity(value) {
170
+ const type = getStringField(value, 'type') ?? getStringField(value, '_type');
171
+ if (type === 'tool' || type === 'tool_message') {
172
+ return true;
173
+ }
174
+ const id = value.id;
175
+ if (Array.isArray(id) &&
176
+ id.some((part) => typeof part === 'string' && part.includes('ToolMessage'))) {
177
+ return true;
178
+ }
179
+ if ('tool_call_id' in value ||
180
+ getNestedStringField(value, 'kwargs', 'tool_call_id') != null ||
181
+ getNestedStringField(value, 'additional_kwargs', 'tool_call_id') != null) {
182
+ return true;
183
+ }
184
+ const role = getStringField(value, 'role');
185
+ return (role != null &&
186
+ !CHAT_ROLES.has(role.toLowerCase()) &&
187
+ ('content' in value || isRecord(value.kwargs) || isRecord(value.data)));
188
+ }
189
+ function redactToolContentFields(value, config) {
190
+ const next = { ...value };
191
+ for (const outputKey of TOOL_OUTPUT_FIELD_KEYS) {
192
+ if (outputKey in next) {
193
+ next[outputKey] = config.redactionText;
194
+ }
195
+ }
196
+ for (const nestedKey of ['kwargs', 'data', 'additional_kwargs']) {
197
+ const nested = next[nestedKey];
198
+ if (!isRecord(nested)) {
199
+ continue;
200
+ }
201
+ const nextNested = { ...nested };
202
+ let changed = false;
203
+ for (const outputKey of TOOL_OUTPUT_FIELD_KEYS) {
204
+ if (outputKey in nextNested) {
205
+ nextNested[outputKey] = config.redactionText;
206
+ changed = true;
207
+ }
208
+ }
209
+ if (changed) {
210
+ next[nestedKey] = nextNested;
211
+ }
212
+ }
213
+ return next;
214
+ }
215
+ function collectToolCallNames(value, redactionContext) {
216
+ if (Array.isArray(value)) {
217
+ for (const item of value) {
218
+ collectToolCallNames(item, redactionContext);
219
+ }
220
+ return;
221
+ }
222
+ if (!isRecord(value)) {
223
+ return;
224
+ }
225
+ const toolCallId = getSerializedToolCallId(value);
226
+ const toolName = getSerializedToolName(value);
227
+ if (toolCallId != null && toolName != null) {
228
+ redactionContext.toolNamesByCallId.set(toolCallId, toolName);
229
+ }
230
+ for (const child of Object.values(value)) {
231
+ collectToolCallNames(child, redactionContext);
232
+ }
233
+ }
234
+ function redactValue(value, config, redactionContext) {
235
+ if (Array.isArray(value)) {
236
+ let changed = false;
237
+ const next = [];
238
+ for (const item of value) {
239
+ const result = redactValue(item, config, redactionContext);
240
+ if (result.changed) {
241
+ changed = true;
242
+ }
243
+ next.push(result.value);
244
+ }
245
+ return changed ? { value: next, changed } : { value, changed };
246
+ }
247
+ if (!isRecord(value)) {
248
+ return { value, changed: false };
249
+ }
250
+ const toolName = getSerializedToolName(value, redactionContext);
251
+ if (hasToolMessageIdentity(value) && shouldRedactTool(toolName, config)) {
252
+ return {
253
+ value: redactToolContentFields(value, config),
254
+ changed: true,
255
+ };
256
+ }
257
+ let changed = false;
258
+ const next = {};
259
+ for (const [key, child] of Object.entries(value)) {
260
+ const result = redactValue(child, config, redactionContext);
261
+ if (result.changed) {
262
+ changed = true;
263
+ }
264
+ next[key] = result.value;
265
+ }
266
+ return changed ? { value: next, changed } : { value, changed };
267
+ }
268
+ function redactSerializedValue(value, config) {
269
+ const redactionContext = {
270
+ toolNamesByCallId: new Map(),
271
+ };
272
+ if (typeof value !== 'string') {
273
+ collectToolCallNames(value, redactionContext);
274
+ return redactValue(value, config, redactionContext);
275
+ }
276
+ const trimmed = value.trim();
277
+ if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
278
+ return { value, changed: false };
279
+ }
280
+ try {
281
+ const parsed = JSON.parse(value);
282
+ collectToolCallNames(parsed, redactionContext);
283
+ const result = redactValue(parsed, config, redactionContext);
284
+ return result.changed
285
+ ? { value: JSON.stringify(result.value), changed: true }
286
+ : { value, changed: false };
287
+ }
288
+ catch {
289
+ return { value, changed: false };
290
+ }
291
+ }
292
+ function redactAttribute(attributes, key, config) {
293
+ if (!(key in attributes)) {
294
+ return;
295
+ }
296
+ const result = redactSerializedValue(attributes[key], config);
297
+ if (result.changed) {
298
+ attributes[key] = result.value;
299
+ }
300
+ }
301
+ function isToolObservation(attributes) {
302
+ const type = attributes[tracing.LangfuseOtelSpanAttributes.OBSERVATION_TYPE];
303
+ return typeof type === 'string' && type.toLowerCase() === 'tool';
304
+ }
305
+ function classifyLangGraphToolNodeSpan(attributes) {
306
+ const type = attributes[tracing.LangfuseOtelSpanAttributes.OBSERVATION_TYPE];
307
+ if (typeof type !== 'string' || type.toLowerCase() !== 'span') {
308
+ return;
309
+ }
310
+ const langGraphNode = attributes[`${tracing.LangfuseOtelSpanAttributes.OBSERVATION_METADATA}.langgraph_node`];
311
+ if (typeof langGraphNode === 'string' &&
312
+ langGraphNode.startsWith(LANGGRAPH_TOOL_NODE_PREFIX)) {
313
+ attributes[tracing.LangfuseOtelSpanAttributes.OBSERVATION_TYPE] = 'tool';
314
+ }
315
+ }
316
+ function redactToolObservationOutput(span, attributes, config) {
317
+ if (!(isToolObservation(attributes) &&
318
+ shouldRedactTool(span.name, config) &&
319
+ tracing.LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT in attributes)) {
320
+ return;
321
+ }
322
+ attributes[tracing.LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT] =
323
+ config.redactionText;
324
+ }
325
+ function redactLangfuseSpanToolOutputs(span, config) {
326
+ const attributes = span.attributes;
327
+ classifyLangGraphToolNodeSpan(attributes);
328
+ if (!shouldApplyToolOutputRedaction(config)) {
329
+ return;
330
+ }
331
+ redactToolObservationOutput(span, attributes, config);
332
+ for (const key of [
333
+ tracing.LangfuseOtelSpanAttributes.OBSERVATION_INPUT,
334
+ tracing.LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT,
335
+ tracing.LangfuseOtelSpanAttributes.TRACE_INPUT,
336
+ tracing.LangfuseOtelSpanAttributes.TRACE_OUTPUT,
337
+ ]) {
338
+ redactAttribute(attributes, key, config);
339
+ }
340
+ }
341
+ function getContextToolOutputTracingConfig(activeContext) {
342
+ const asyncConfig = toolOutputTracingStorage.getStore();
343
+ if (asyncConfig != null) {
344
+ return asyncConfig;
345
+ }
346
+ const value = activeContext.getValue(langfuseToolOutputTracingConfigKey);
347
+ return isRecord(value)
348
+ ? value
349
+ : undefined;
350
+ }
351
+ function getContextLangfuseConfig(activeContext) {
352
+ const asyncConfig = langfuseConfigStorage.getStore();
353
+ if (asyncConfig != null) {
354
+ return asyncConfig;
355
+ }
356
+ const value = activeContext.getValue(langfuseConfigKey);
357
+ return isRecord(value) ? value : undefined;
358
+ }
359
+ class ToolOutputRedactingLangfuseSpanProcessor {
360
+ processor;
361
+ fallbackConfig;
362
+ spanConfigs = new WeakMap();
363
+ constructor(params, fallbackConfig) {
364
+ this.processor = new otel.LangfuseSpanProcessor(params);
365
+ this.fallbackConfig = fallbackConfig;
366
+ }
367
+ onStart(span, parentContext) {
368
+ const config = getContextToolOutputTracingConfig(parentContext) ?? this.fallbackConfig;
369
+ if (config != null) {
370
+ this.spanConfigs.set(span, config);
371
+ }
372
+ this.processor.onStart(span, parentContext);
373
+ }
374
+ onEnd(span) {
375
+ const config = this.spanConfigs.get(span) ??
376
+ toolOutputTracingStorage.getStore() ??
377
+ this.fallbackConfig ??
378
+ resolveToolOutputTracingConfig();
379
+ redactLangfuseSpanToolOutputs(span, config);
380
+ this.processor.onEnd(span);
381
+ }
382
+ forceFlush() {
383
+ return this.processor.forceFlush();
384
+ }
385
+ shutdown() {
386
+ return this.processor.shutdown();
387
+ }
388
+ }
389
+ function createLangfuseSpanProcessor(params, runLangfuse, agentLangfuse) {
390
+ const fallbackConfig = runLangfuse != null || agentLangfuse != null
391
+ ? resolveToolOutputTracingConfig(runLangfuse, agentLangfuse)
392
+ : undefined;
393
+ return new ToolOutputRedactingLangfuseSpanProcessor(params, fallbackConfig);
394
+ }
395
+ function withLangfuseToolOutputTracingConfig(runLangfuse, action, agentLangfuse) {
396
+ const langfuse = resolveLangfuseConfig(runLangfuse, agentLangfuse);
397
+ const hasNoToolOutputConfig = runLangfuse?.toolOutputTracing == null &&
398
+ agentLangfuse?.toolOutputTracing == null;
399
+ if (langfuse == null && hasNoToolOutputConfig) {
400
+ return action();
401
+ }
402
+ const config = hasNoToolOutputConfig
403
+ ? undefined
404
+ : resolveToolOutputTracingConfig(runLangfuse, agentLangfuse);
405
+ let activeContext = api.context.active();
406
+ if (langfuse != null) {
407
+ activeContext = activeContext.setValue(langfuseConfigKey, langfuse);
408
+ }
409
+ if (config != null) {
410
+ activeContext = activeContext.setValue(langfuseToolOutputTracingConfigKey, config);
411
+ }
412
+ const runWithContext = () => api.context.with(activeContext, action);
413
+ const runWithToolOutputConfig = () => config != null
414
+ ? toolOutputTracingStorage.run(config, runWithContext)
415
+ : runWithContext();
416
+ return langfuse != null
417
+ ? langfuseConfigStorage.run(langfuse, runWithToolOutputConfig)
418
+ : runWithToolOutputConfig();
419
+ }
420
+ function hasLangfuseEnvKeys() {
421
+ return (isPresent(process.env.LANGFUSE_SECRET_KEY) &&
422
+ isPresent(process.env.LANGFUSE_PUBLIC_KEY));
423
+ }
424
+ function hasLangfuseConfigKeys(langfuse) {
425
+ if (langfuse == null) {
426
+ return false;
427
+ }
428
+ return isPresent(langfuse.secretKey) && isPresent(langfuse.publicKey);
429
+ }
430
+ function shouldTraceToolNodeForLangfuse({ runLangfuse, agentLangfuse, }) {
431
+ const langfuse = resolveLangfuseConfig(runLangfuse, agentLangfuse);
432
+ if (langfuse?.enabled === false) {
433
+ return false;
434
+ }
435
+ const explicit = langfuse?.toolNodeTracing?.enabled;
436
+ if (explicit != null) {
437
+ return (explicit && (hasLangfuseConfigKeys(langfuse) || hasLangfuseEnvKeys()));
438
+ }
439
+ return hasLangfuseConfigKeys(langfuse) || hasLangfuseEnvKeys();
440
+ }
441
+ function resolveLangfuseConfig(runLangfuse, agentLangfuse) {
442
+ if (runLangfuse == null) {
443
+ return agentLangfuse;
444
+ }
445
+ if (agentLangfuse == null) {
446
+ return runLangfuse;
447
+ }
448
+ const toolNodeTracing = runLangfuse.toolNodeTracing != null || agentLangfuse.toolNodeTracing != null
449
+ ? {
450
+ ...runLangfuse.toolNodeTracing,
451
+ ...agentLangfuse.toolNodeTracing,
452
+ }
453
+ : undefined;
454
+ const toolOutputTracing = runLangfuse.toolOutputTracing != null ||
455
+ agentLangfuse.toolOutputTracing != null
456
+ ? {
457
+ ...runLangfuse.toolOutputTracing,
458
+ ...agentLangfuse.toolOutputTracing,
459
+ }
460
+ : undefined;
461
+ return {
462
+ ...runLangfuse,
463
+ ...agentLangfuse,
464
+ ...(toolNodeTracing != null ? { toolNodeTracing } : {}),
465
+ ...(toolOutputTracing != null ? { toolOutputTracing } : {}),
466
+ };
467
+ }
468
+
469
+ exports.LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT = LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT;
470
+ exports.createLangfuseSpanProcessor = createLangfuseSpanProcessor;
471
+ exports.getContextLangfuseConfig = getContextLangfuseConfig;
472
+ exports.redactLangfuseSpanToolOutputs = redactLangfuseSpanToolOutputs;
473
+ exports.resolveLangfuseConfig = resolveLangfuseConfig;
474
+ exports.shouldTraceToolNodeForLangfuse = shouldTraceToolNodeForLangfuse;
475
+ exports.withLangfuseToolOutputTracingConfig = withLangfuseToolOutputTracingConfig;
476
+ //# sourceMappingURL=langfuseToolOutputTracing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langfuseToolOutputTracing.cjs","sources":["../../src/langfuseToolOutputTracing.ts"],"sourcesContent":["import { context, createContextKey } from '@opentelemetry/api';\nimport { LangfuseSpanProcessor } from '@langfuse/otel';\nimport { LangfuseOtelSpanAttributes } from '@langfuse/tracing';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type {\n ReadableSpan,\n Span,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Context } from '@opentelemetry/api';\nimport type * as t from '@/types';\n\nexport const LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT = '[tool output redacted]';\n\nconst langfuseToolOutputTracingConfigKey = createContextKey(\n 'librechat.langfuse.tool-output-tracing'\n);\nconst langfuseConfigKey = createContextKey('librechat.langfuse.config');\nconst toolOutputTracingStorage =\n new AsyncLocalStorage<ResolvedLangfuseToolOutputTracingConfig>();\nconst langfuseConfigStorage = new AsyncLocalStorage<t.LangfuseConfig>();\nconst LANGGRAPH_TOOL_NODE_PREFIX = 'tools=';\n\nconst CHAT_ROLES = new Set([\n 'assistant',\n 'developer',\n 'human',\n 'system',\n 'user',\n]);\n\nexport type ResolvedLangfuseToolOutputTracingConfig = {\n enabled: boolean;\n redactedToolNames: Set<string>;\n redactedToolNameMatchMode: 'exact' | 'partial';\n redactionText: string;\n};\n\ntype SpanWithAttributes = ReadableSpan & {\n attributes: Record<string, unknown>;\n};\n\ntype RedactionResult = {\n value: unknown;\n changed: boolean;\n};\n\ntype RedactionContext = {\n toolNamesByCallId: Map<string, string>;\n};\n\nconst TOOL_OUTPUT_FIELD_KEYS = ['content', 'artifact'];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isPresent(value: unknown): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) {\n return undefined;\n }\n\n const normalized = value.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true;\n }\n if (['0', 'false', 'no', 'off'].includes(normalized)) {\n return false;\n }\n\n return undefined;\n}\n\nfunction normalizeToolName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nfunction normalizeToolNames(names: string[] | undefined): Set<string> {\n const normalized = new Set<string>();\n for (const name of names ?? []) {\n if (isPresent(name)) {\n normalized.add(normalizeToolName(name));\n }\n }\n return normalized;\n}\n\nfunction parseToolNames(value: string | undefined): string[] | undefined {\n if (!isPresent(value)) {\n return undefined;\n }\n\n return value\n .split(',')\n .map((name) => name.trim())\n .filter((name) => name !== '');\n}\n\nfunction getEnvToolOutputTracingEnabled(): boolean | undefined {\n const traceToolOutputs = parseBoolean(\n process.env.LANGFUSE_TRACE_TOOL_OUTPUTS\n );\n if (traceToolOutputs != null) {\n return traceToolOutputs;\n }\n\n const redactToolOutputs = parseBoolean(\n process.env.LANGFUSE_REDACT_TOOL_OUTPUTS\n );\n if (redactToolOutputs != null) {\n return !redactToolOutputs;\n }\n\n return parseBoolean(process.env.LANGFUSE_TOOL_OUTPUT_TRACING_ENABLED);\n}\n\nfunction getEnvRedactedToolNames(): string[] | undefined {\n return (\n parseToolNames(process.env.LANGFUSE_REDACT_TOOL_OUTPUT_NAMES) ??\n parseToolNames(process.env.LANGFUSE_REDACT_TOOL_NAMES)\n );\n}\n\nfunction getEnvRedactionText(): string | undefined {\n return isPresent(process.env.LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT)\n ? process.env.LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT\n : undefined;\n}\n\nfunction getEnvToolNameMatchMode(): 'exact' | 'partial' | undefined {\n const mode = (\n process.env.LANGFUSE_REDACT_TOOL_OUTPUT_NAME_MATCH_MODE ??\n process.env.LANGFUSE_REDACT_TOOL_NAME_MATCH_MODE\n )\n ?.trim()\n .toLowerCase();\n if (mode === 'exact' || mode === 'partial') {\n return mode;\n }\n return undefined;\n}\n\nfunction resolveToolOutputTracingConfig(\n runLangfuse?: t.LangfuseConfig,\n agentLangfuse?: t.LangfuseConfig\n): ResolvedLangfuseToolOutputTracingConfig {\n const runConfig = runLangfuse?.toolOutputTracing;\n const agentConfig = agentLangfuse?.toolOutputTracing;\n\n return {\n enabled:\n agentConfig?.enabled ??\n runConfig?.enabled ??\n getEnvToolOutputTracingEnabled() ??\n true,\n redactedToolNames: normalizeToolNames(\n agentConfig?.redactedToolNames ??\n runConfig?.redactedToolNames ??\n getEnvRedactedToolNames()\n ),\n redactedToolNameMatchMode:\n agentConfig?.redactedToolNameMatchMode ??\n runConfig?.redactedToolNameMatchMode ??\n getEnvToolNameMatchMode() ??\n 'exact',\n redactionText:\n agentConfig?.redactionText ??\n runConfig?.redactionText ??\n getEnvRedactionText() ??\n LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT,\n };\n}\n\nfunction shouldApplyToolOutputRedaction(\n config: ResolvedLangfuseToolOutputTracingConfig\n): boolean {\n return config.enabled === false || config.redactedToolNames.size > 0;\n}\n\nfunction toolNameMatches(\n toolName: string | undefined,\n config: ResolvedLangfuseToolOutputTracingConfig\n): boolean {\n if (!isPresent(toolName)) {\n return false;\n }\n\n const normalizedToolName = normalizeToolName(toolName);\n if (config.redactedToolNameMatchMode === 'partial') {\n for (const redactedToolName of config.redactedToolNames) {\n if (normalizedToolName.includes(redactedToolName)) {\n return true;\n }\n }\n return false;\n }\n\n return config.redactedToolNames.has(normalizedToolName);\n}\n\nfunction shouldRedactTool(\n toolName: string | undefined,\n config: ResolvedLangfuseToolOutputTracingConfig\n): boolean {\n return config.enabled === false || toolNameMatches(toolName, config);\n}\n\nfunction getStringField(\n value: Record<string, unknown>,\n key: string\n): string | undefined {\n const field = value[key];\n return typeof field === 'string' ? field : undefined;\n}\n\nfunction getNestedStringField(\n value: Record<string, unknown>,\n objectKey: string,\n fieldKey: string\n): string | undefined {\n const nested = value[objectKey];\n if (!isRecord(nested)) {\n return undefined;\n }\n return getStringField(nested, fieldKey);\n}\n\nfunction getSerializedToolCallId(\n value: Record<string, unknown>\n): string | undefined {\n return (\n getStringField(value, 'tool_call_id') ??\n getNestedStringField(value, 'kwargs', 'tool_call_id') ??\n getNestedStringField(value, 'additional_kwargs', 'tool_call_id') ??\n getNestedStringField(value, 'data', 'tool_call_id') ??\n (typeof value.id === 'string' ? value.id : undefined)\n );\n}\n\nfunction getSerializedToolName(\n value: Record<string, unknown>,\n redactionContext?: RedactionContext\n): string | undefined {\n const role = getStringField(value, 'role');\n const explicitName =\n getStringField(value, 'name') ??\n getStringField(value, 'tool_name') ??\n getNestedStringField(value, 'function', 'name') ??\n getNestedStringField(value, 'kwargs', 'name') ??\n getNestedStringField(value, 'additional_kwargs', 'name') ??\n getNestedStringField(value, 'data', 'name') ??\n (role != null && role.toLowerCase() !== 'tool' ? role : undefined);\n\n if (explicitName != null) {\n return explicitName;\n }\n\n const toolCallId = getSerializedToolCallId(value);\n return toolCallId != null\n ? redactionContext?.toolNamesByCallId.get(toolCallId)\n : undefined;\n}\n\nfunction hasToolMessageIdentity(value: Record<string, unknown>): boolean {\n const type = getStringField(value, 'type') ?? getStringField(value, '_type');\n if (type === 'tool' || type === 'tool_message') {\n return true;\n }\n\n const id = value.id;\n if (\n Array.isArray(id) &&\n id.some((part) => typeof part === 'string' && part.includes('ToolMessage'))\n ) {\n return true;\n }\n\n if (\n 'tool_call_id' in value ||\n getNestedStringField(value, 'kwargs', 'tool_call_id') != null ||\n getNestedStringField(value, 'additional_kwargs', 'tool_call_id') != null\n ) {\n return true;\n }\n\n const role = getStringField(value, 'role');\n return (\n role != null &&\n !CHAT_ROLES.has(role.toLowerCase()) &&\n ('content' in value || isRecord(value.kwargs) || isRecord(value.data))\n );\n}\n\nfunction redactToolContentFields(\n value: Record<string, unknown>,\n config: ResolvedLangfuseToolOutputTracingConfig\n): Record<string, unknown> {\n const next = { ...value };\n\n for (const outputKey of TOOL_OUTPUT_FIELD_KEYS) {\n if (outputKey in next) {\n next[outputKey] = config.redactionText;\n }\n }\n\n for (const nestedKey of ['kwargs', 'data', 'additional_kwargs']) {\n const nested = next[nestedKey];\n if (!isRecord(nested)) {\n continue;\n }\n const nextNested = { ...nested };\n let changed = false;\n for (const outputKey of TOOL_OUTPUT_FIELD_KEYS) {\n if (outputKey in nextNested) {\n nextNested[outputKey] = config.redactionText;\n changed = true;\n }\n }\n if (changed) {\n next[nestedKey] = nextNested;\n }\n }\n\n return next;\n}\n\nfunction collectToolCallNames(\n value: unknown,\n redactionContext: RedactionContext\n): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n collectToolCallNames(item, redactionContext);\n }\n return;\n }\n\n if (!isRecord(value)) {\n return;\n }\n\n const toolCallId = getSerializedToolCallId(value);\n const toolName = getSerializedToolName(value);\n if (toolCallId != null && toolName != null) {\n redactionContext.toolNamesByCallId.set(toolCallId, toolName);\n }\n\n for (const child of Object.values(value)) {\n collectToolCallNames(child, redactionContext);\n }\n}\n\nfunction redactValue(\n value: unknown,\n config: ResolvedLangfuseToolOutputTracingConfig,\n redactionContext: RedactionContext\n): RedactionResult {\n if (Array.isArray(value)) {\n let changed = false;\n const next: unknown[] = [];\n for (const item of value) {\n const result = redactValue(item, config, redactionContext);\n if (result.changed) {\n changed = true;\n }\n next.push(result.value);\n }\n return changed ? { value: next, changed } : { value, changed };\n }\n\n if (!isRecord(value)) {\n return { value, changed: false };\n }\n\n const toolName = getSerializedToolName(value, redactionContext);\n if (hasToolMessageIdentity(value) && shouldRedactTool(toolName, config)) {\n return {\n value: redactToolContentFields(value, config),\n changed: true,\n };\n }\n\n let changed = false;\n const next: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n const result = redactValue(child, config, redactionContext);\n if (result.changed) {\n changed = true;\n }\n next[key] = result.value;\n }\n\n return changed ? { value: next, changed } : { value, changed };\n}\n\nfunction redactSerializedValue(\n value: unknown,\n config: ResolvedLangfuseToolOutputTracingConfig\n): RedactionResult {\n const redactionContext: RedactionContext = {\n toolNamesByCallId: new Map(),\n };\n if (typeof value !== 'string') {\n collectToolCallNames(value, redactionContext);\n return redactValue(value, config, redactionContext);\n }\n\n const trimmed = value.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return { value, changed: false };\n }\n\n try {\n const parsed = JSON.parse(value) as unknown;\n collectToolCallNames(parsed, redactionContext);\n const result = redactValue(parsed, config, redactionContext);\n return result.changed\n ? { value: JSON.stringify(result.value), changed: true }\n : { value, changed: false };\n } catch {\n return { value, changed: false };\n }\n}\n\nfunction redactAttribute(\n attributes: Record<string, unknown>,\n key: string,\n config: ResolvedLangfuseToolOutputTracingConfig\n): void {\n if (!(key in attributes)) {\n return;\n }\n\n const result = redactSerializedValue(attributes[key], config);\n if (result.changed) {\n attributes[key] = result.value;\n }\n}\n\nfunction isToolObservation(attributes: Record<string, unknown>): boolean {\n const type = attributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE];\n return typeof type === 'string' && type.toLowerCase() === 'tool';\n}\n\nfunction classifyLangGraphToolNodeSpan(\n attributes: Record<string, unknown>\n): void {\n const type = attributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE];\n if (typeof type !== 'string' || type.toLowerCase() !== 'span') {\n return;\n }\n\n const langGraphNode =\n attributes[\n `${LangfuseOtelSpanAttributes.OBSERVATION_METADATA}.langgraph_node`\n ];\n if (\n typeof langGraphNode === 'string' &&\n langGraphNode.startsWith(LANGGRAPH_TOOL_NODE_PREFIX)\n ) {\n attributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE] = 'tool';\n }\n}\n\nfunction redactToolObservationOutput(\n span: ReadableSpan,\n attributes: Record<string, unknown>,\n config: ResolvedLangfuseToolOutputTracingConfig\n): void {\n if (\n !(\n isToolObservation(attributes) &&\n shouldRedactTool(span.name, config) &&\n LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT in attributes\n )\n ) {\n return;\n }\n\n attributes[LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT] =\n config.redactionText;\n}\n\nexport function redactLangfuseSpanToolOutputs(\n span: ReadableSpan,\n config: ResolvedLangfuseToolOutputTracingConfig\n): void {\n const attributes = (span as SpanWithAttributes).attributes;\n classifyLangGraphToolNodeSpan(attributes);\n\n if (!shouldApplyToolOutputRedaction(config)) {\n return;\n }\n\n redactToolObservationOutput(span, attributes, config);\n\n for (const key of [\n LangfuseOtelSpanAttributes.OBSERVATION_INPUT,\n LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT,\n LangfuseOtelSpanAttributes.TRACE_INPUT,\n LangfuseOtelSpanAttributes.TRACE_OUTPUT,\n ]) {\n redactAttribute(attributes, key, config);\n }\n}\n\nfunction getContextToolOutputTracingConfig(\n activeContext: Context\n): ResolvedLangfuseToolOutputTracingConfig | undefined {\n const asyncConfig = toolOutputTracingStorage.getStore();\n if (asyncConfig != null) {\n return asyncConfig;\n }\n\n const value = activeContext.getValue(langfuseToolOutputTracingConfigKey);\n return isRecord(value)\n ? (value as ResolvedLangfuseToolOutputTracingConfig)\n : undefined;\n}\n\nexport function getContextLangfuseConfig(\n activeContext: Context\n): t.LangfuseConfig | undefined {\n const asyncConfig = langfuseConfigStorage.getStore();\n if (asyncConfig != null) {\n return asyncConfig;\n }\n\n const value = activeContext.getValue(langfuseConfigKey);\n return isRecord(value) ? (value as t.LangfuseConfig) : undefined;\n}\n\nclass ToolOutputRedactingLangfuseSpanProcessor implements SpanProcessor {\n private readonly processor: LangfuseSpanProcessor;\n private readonly fallbackConfig?: ResolvedLangfuseToolOutputTracingConfig;\n private readonly spanConfigs = new WeakMap<\n object,\n ResolvedLangfuseToolOutputTracingConfig\n >();\n\n constructor(\n params?: LangfuseSpanProcessorParams,\n fallbackConfig?: ResolvedLangfuseToolOutputTracingConfig\n ) {\n this.processor = new LangfuseSpanProcessor(params);\n this.fallbackConfig = fallbackConfig;\n }\n\n onStart(span: Span, parentContext: Context): void {\n const config =\n getContextToolOutputTracingConfig(parentContext) ?? this.fallbackConfig;\n if (config != null) {\n this.spanConfigs.set(span, config);\n }\n this.processor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n const config =\n this.spanConfigs.get(span) ??\n toolOutputTracingStorage.getStore() ??\n this.fallbackConfig ??\n resolveToolOutputTracingConfig();\n redactLangfuseSpanToolOutputs(span, config);\n this.processor.onEnd(span);\n }\n\n forceFlush(): Promise<void> {\n return this.processor.forceFlush();\n }\n\n shutdown(): Promise<void> {\n return this.processor.shutdown();\n }\n}\n\nexport function createLangfuseSpanProcessor(\n params?: LangfuseSpanProcessorParams,\n runLangfuse?: t.LangfuseConfig,\n agentLangfuse?: t.LangfuseConfig\n): SpanProcessor {\n const fallbackConfig =\n runLangfuse != null || agentLangfuse != null\n ? resolveToolOutputTracingConfig(runLangfuse, agentLangfuse)\n : undefined;\n return new ToolOutputRedactingLangfuseSpanProcessor(params, fallbackConfig);\n}\n\nexport function withLangfuseToolOutputTracingConfig<T>(\n runLangfuse: t.LangfuseConfig | undefined,\n action: () => T,\n agentLangfuse?: t.LangfuseConfig\n): T {\n const langfuse = resolveLangfuseConfig(runLangfuse, agentLangfuse);\n const hasNoToolOutputConfig =\n runLangfuse?.toolOutputTracing == null &&\n agentLangfuse?.toolOutputTracing == null;\n\n if (langfuse == null && hasNoToolOutputConfig) {\n return action();\n }\n\n const config = hasNoToolOutputConfig\n ? undefined\n : resolveToolOutputTracingConfig(runLangfuse, agentLangfuse);\n let activeContext = context.active();\n if (langfuse != null) {\n activeContext = activeContext.setValue(langfuseConfigKey, langfuse);\n }\n if (config != null) {\n activeContext = activeContext.setValue(\n langfuseToolOutputTracingConfigKey,\n config\n );\n }\n\n const runWithContext = (): T => context.with(activeContext, action);\n const runWithToolOutputConfig = (): T =>\n config != null\n ? toolOutputTracingStorage.run(config, runWithContext)\n : runWithContext();\n\n return langfuse != null\n ? langfuseConfigStorage.run(langfuse, runWithToolOutputConfig)\n : runWithToolOutputConfig();\n}\n\nfunction hasLangfuseEnvKeys(): boolean {\n return (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY)\n );\n}\n\nfunction hasLangfuseConfigKeys(langfuse?: t.LangfuseConfig): boolean {\n if (langfuse == null) {\n return false;\n }\n return isPresent(langfuse.secretKey) && isPresent(langfuse.publicKey);\n}\n\nexport function shouldTraceToolNodeForLangfuse({\n runLangfuse,\n agentLangfuse,\n}: {\n runLangfuse?: t.LangfuseConfig;\n agentLangfuse?: t.LangfuseConfig;\n}): boolean {\n const langfuse = resolveLangfuseConfig(runLangfuse, agentLangfuse);\n if (langfuse?.enabled === false) {\n return false;\n }\n\n const explicit = langfuse?.toolNodeTracing?.enabled;\n if (explicit != null) {\n return (\n explicit && (hasLangfuseConfigKeys(langfuse) || hasLangfuseEnvKeys())\n );\n }\n\n return hasLangfuseConfigKeys(langfuse) || hasLangfuseEnvKeys();\n}\n\nexport function resolveLangfuseConfig(\n runLangfuse?: t.LangfuseConfig,\n agentLangfuse?: t.LangfuseConfig\n): t.LangfuseConfig | undefined {\n if (runLangfuse == null) {\n return agentLangfuse;\n }\n if (agentLangfuse == null) {\n return runLangfuse;\n }\n\n const toolNodeTracing =\n runLangfuse.toolNodeTracing != null || agentLangfuse.toolNodeTracing != null\n ? {\n ...runLangfuse.toolNodeTracing,\n ...agentLangfuse.toolNodeTracing,\n }\n : undefined;\n const toolOutputTracing =\n runLangfuse.toolOutputTracing != null ||\n agentLangfuse.toolOutputTracing != null\n ? {\n ...runLangfuse.toolOutputTracing,\n ...agentLangfuse.toolOutputTracing,\n }\n : undefined;\n\n return {\n ...runLangfuse,\n ...agentLangfuse,\n ...(toolNodeTracing != null ? { toolNodeTracing } : {}),\n ...(toolOutputTracing != null ? { toolOutputTracing } : {}),\n };\n}\n"],"names":["createContextKey","AsyncLocalStorage","LangfuseOtelSpanAttributes","LangfuseSpanProcessor","context"],"mappings":"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"}
@@ -4,6 +4,7 @@ var aws = require('@langchain/aws');
4
4
  var clientBedrockRuntime = require('@aws-sdk/client-bedrock-runtime');
5
5
  var messages = require('@langchain/core/messages');
6
6
  var outputs = require('@langchain/core/outputs');
7
+ var toolCache = require('./toolCache.cjs');
7
8
  var message_inputs = require('./utils/message_inputs.cjs');
8
9
  var message_outputs = require('./utils/message_outputs.cjs');
9
10
 
@@ -30,6 +31,10 @@ var message_outputs = require('./utils/message_outputs.cjs');
30
31
  * the accumulated content is already an array.
31
32
  */
32
33
  class CustomChatBedrockConverse extends aws.ChatBedrockConverse {
34
+ /**
35
+ * Whether to insert Bedrock prompt cache checkpoints when available.
36
+ */
37
+ promptCache;
33
38
  /**
34
39
  * Application Inference Profile ARN to use instead of model ID.
35
40
  */
@@ -40,6 +45,7 @@ class CustomChatBedrockConverse extends aws.ChatBedrockConverse {
40
45
  serviceTier;
41
46
  constructor(fields) {
42
47
  super(fields);
48
+ this.promptCache = fields?.promptCache;
43
49
  this.applicationInferenceProfile = fields?.applicationInferenceProfile;
44
50
  this.serviceTier = fields?.serviceTier;
45
51
  }
@@ -58,10 +64,14 @@ class CustomChatBedrockConverse extends aws.ChatBedrockConverse {
58
64
  */
59
65
  invocationParams(options) {
60
66
  const baseParams = super.invocationParams(options);
67
+ const toolConfig = this.promptCache === true
68
+ ? toolCache.insertBedrockToolCachePoint(baseParams.toolConfig)
69
+ : baseParams.toolConfig;
61
70
  /** Service tier from options or fall back to class-level setting */
62
71
  const serviceTierType = options?.serviceTier ?? this.serviceTier;
63
72
  return {
64
73
  ...baseParams,
74
+ toolConfig,
65
75
  serviceTier: serviceTierType ? { type: serviceTierType } : undefined,
66
76
  };
67
77
  }