Skip to content

Commit 6b4a270

Browse files
nirgaclaude
andcommitted
fix: resolve require() issue and apply prettier formatting
- Add eslint disable for require() usage in Node.js context - Apply prettier formatting to all source files - Build and tests still passing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 50fcc66 commit 6b4a270

File tree

3 files changed

+177
-104
lines changed

3 files changed

+177
-104
lines changed

packages/instrumentation-langchain/src/callback_handler.ts

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ import { BaseMessage } from "@langchain/core/messages";
1919
import { LLMResult } from "@langchain/core/outputs";
2020
import { Serialized } from "@langchain/core/load/serializable";
2121
import { ChainValues } from "@langchain/core/utils/types";
22-
import { Tracer, trace, SpanKind, SpanStatusCode, context } from "@opentelemetry/api";
22+
import {
23+
Tracer,
24+
trace,
25+
SpanKind,
26+
SpanStatusCode,
27+
context,
28+
} from "@opentelemetry/api";
2329
import { SpanAttributes } from "@traceloop/ai-semantic-conventions";
2430

2531
interface SpanData {
@@ -28,10 +34,9 @@ interface SpanData {
2834
runId: string;
2935
}
3036

31-
3237
export class TraceloopCallbackHandler extends BaseCallbackHandler {
3338
name = "traceloop_callback_handler";
34-
39+
3540
private tracer: Tracer;
3641
private spans: Map<string, SpanData> = new Map();
3742
private traceContent: boolean;
@@ -50,14 +55,14 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
5055
extraParams?: Record<string, unknown>,
5156
tags?: string[],
5257
metadata?: Record<string, unknown>,
53-
runName?: string
58+
runName?: string,
5459
): Promise<void> {
5560
const className = llm.id?.[llm.id.length - 1] || "unknown";
5661
const modelName = this.extractModelName(llm);
5762
const vendor = this.detectVendor(llm);
5863
const spanBaseName = this.convertClassNameToSpanName(className);
59-
60-
// Create both a task span and an LLM span like Python implementation
64+
65+
// Create both a task span and an LLM span like Python implementation
6166
const taskSpanName = `${spanBaseName}.task`;
6267
const taskSpan = this.tracer.startSpan(taskSpanName, {
6368
kind: SpanKind.CLIENT,
@@ -71,17 +76,26 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
7176
if (this.traceContent) {
7277
const flatMessages = messages.flat();
7378
taskSpan.setAttributes({
74-
"traceloop.entity.input": JSON.stringify(flatMessages.map(m => ({
75-
role: m._getType(),
76-
content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content)
77-
}))),
79+
"traceloop.entity.input": JSON.stringify(
80+
flatMessages.map((m) => ({
81+
role: m._getType(),
82+
content:
83+
typeof m.content === "string"
84+
? m.content
85+
: JSON.stringify(m.content),
86+
})),
87+
),
7888
});
7989
}
8090

8191
// Create LLM span as child of task span
82-
const llmSpan = this.tracer.startSpan(`${spanBaseName}.completion`, {
83-
kind: SpanKind.CLIENT,
84-
}, trace.setSpan(context.active(), taskSpan));
92+
const llmSpan = this.tracer.startSpan(
93+
`${spanBaseName}.completion`,
94+
{
95+
kind: SpanKind.CLIENT,
96+
},
97+
trace.setSpan(context.active(), taskSpan),
98+
);
8599

86100
const flatMessages = messages.flat();
87101
llmSpan.setAttributes({
@@ -96,7 +110,10 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
96110
const role = this.mapMessageTypeToRole(message._getType());
97111
llmSpan.setAttributes({
98112
[`${SpanAttributes.LLM_PROMPTS}.${idx}.role`]: role,
99-
[`${SpanAttributes.LLM_PROMPTS}.${idx}.content`]: typeof message.content === 'string' ? message.content : JSON.stringify(message.content),
113+
[`${SpanAttributes.LLM_PROMPTS}.${idx}.content`]:
114+
typeof message.content === "string"
115+
? message.content
116+
: JSON.stringify(message.content),
100117
});
101118
});
102119
}
@@ -113,14 +130,14 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
113130
_extraParams?: Record<string, unknown>,
114131
_tags?: string[],
115132
_metadata?: Record<string, unknown>,
116-
_runName?: string
133+
_runName?: string,
117134
): Promise<void> {
118135
const className = llm.id?.[llm.id.length - 1] || "unknown";
119136
const modelName = this.extractModelName(llm);
120137
const vendor = this.detectVendor(llm);
121138
const spanBaseName = this.convertClassNameToSpanName(className);
122139
const spanName = `${spanBaseName}.task`;
123-
140+
124141
const span = this.tracer.startSpan(spanName, {
125142
kind: SpanKind.CLIENT,
126143
});
@@ -150,7 +167,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
150167
runId: string,
151168
_parentRunId?: string,
152169
_tags?: string[],
153-
_extraParams?: Record<string, unknown>
170+
_extraParams?: Record<string, unknown>,
154171
): Promise<void> {
155172
// End both LLM and task spans
156173
const llmSpanData = this.spans.get(`${runId}_llm`);
@@ -159,12 +176,17 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
159176
if (llmSpanData) {
160177
const { span: llmSpan } = llmSpanData;
161178

162-
if (this.traceContent && output.generations && output.generations.length > 0) {
179+
if (
180+
this.traceContent &&
181+
output.generations &&
182+
output.generations.length > 0
183+
) {
163184
output.generations.forEach((generation, idx) => {
164185
if (generation && generation.length > 0) {
165186
llmSpan.setAttributes({
166187
[`${SpanAttributes.LLM_COMPLETIONS}.${idx}.role`]: "assistant",
167-
[`${SpanAttributes.LLM_COMPLETIONS}.${idx}.content`]: generation[0].text,
188+
[`${SpanAttributes.LLM_COMPLETIONS}.${idx}.content`]:
189+
generation[0].text,
168190
});
169191
}
170192
});
@@ -183,14 +205,15 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
183205
[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS]: usage.output_tokens,
184206
});
185207
}
186-
const totalTokens = (usage.input_tokens || 0) + (usage.output_tokens || 0);
208+
const totalTokens =
209+
(usage.input_tokens || 0) + (usage.output_tokens || 0);
187210
if (totalTokens > 0) {
188211
llmSpan.setAttributes({
189212
[SpanAttributes.LLM_USAGE_TOTAL_TOKENS]: totalTokens,
190213
});
191214
}
192215
}
193-
216+
194217
// Also check for tokenUsage format (for compatibility)
195218
if (output.llmOutput?.tokenUsage) {
196219
const usage = output.llmOutput.tokenUsage;
@@ -201,7 +224,8 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
201224
}
202225
if (usage.completionTokens) {
203226
llmSpan.setAttributes({
204-
[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS]: usage.completionTokens,
227+
[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS]:
228+
usage.completionTokens,
205229
});
206230
}
207231
if (usage.totalTokens) {
@@ -218,8 +242,12 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
218242

219243
if (taskSpanData) {
220244
const { span: taskSpan } = taskSpanData;
221-
222-
if (this.traceContent && output.generations && output.generations.length > 0) {
245+
246+
if (
247+
this.traceContent &&
248+
output.generations &&
249+
output.generations.length > 0
250+
) {
223251
const completions = output.generations.map((generation, _idx) => {
224252
if (generation && generation.length > 0) {
225253
return generation[0].text;
@@ -242,7 +270,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
242270
runId: string,
243271
_parentRunId?: string,
244272
_tags?: string[],
245-
_extraParams?: Record<string, unknown>
273+
_extraParams?: Record<string, unknown>,
246274
): Promise<void> {
247275
// Same as handleLLMEnd for chat models
248276
return this.handleLLMEnd(output, runId, _parentRunId, _tags, _extraParams);
@@ -253,7 +281,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
253281
runId: string,
254282
_parentRunId?: string,
255283
_tags?: string[],
256-
_extraParams?: Record<string, unknown>
284+
_extraParams?: Record<string, unknown>,
257285
): Promise<void> {
258286
// End both spans on error
259287
const llmSpanData = this.spans.get(`${runId}_llm`);
@@ -284,11 +312,11 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
284312
_tags?: string[],
285313
metadata?: Record<string, unknown>,
286314
runType?: string,
287-
runName?: string
315+
runName?: string,
288316
): Promise<void> {
289317
const chainName = chain.id?.[chain.id.length - 1] || "unknown";
290318
const spanName = `${chainName}.workflow`;
291-
319+
292320
const span = this.tracer.startSpan(spanName, {
293321
kind: SpanKind.CLIENT,
294322
});
@@ -312,7 +340,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
312340
runId: string,
313341
_parentRunId?: string,
314342
_tags?: string[],
315-
_kwargs?: { inputs?: Record<string, unknown> }
343+
_kwargs?: { inputs?: Record<string, unknown> },
316344
): Promise<void> {
317345
const spanData = this.spans.get(runId);
318346
if (!spanData) return;
@@ -335,7 +363,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
335363
runId: string,
336364
_parentRunId?: string,
337365
_tags?: string[],
338-
_kwargs?: { inputs?: Record<string, unknown> }
366+
_kwargs?: { inputs?: Record<string, unknown> },
339367
): Promise<void> {
340368
const spanData = this.spans.get(runId);
341369
if (!spanData) return;
@@ -354,11 +382,11 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
354382
_parentRunId?: string,
355383
_tags?: string[],
356384
_metadata?: Record<string, unknown>,
357-
_runName?: string
385+
_runName?: string,
358386
): Promise<void> {
359387
const toolName = tool.id?.[tool.id.length - 1] || "unknown";
360388
const spanName = `${toolName}.task`;
361-
389+
362390
const span = this.tracer.startSpan(spanName, {
363391
kind: SpanKind.CLIENT,
364392
});
@@ -381,7 +409,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
381409
output: any,
382410
runId: string,
383411
_parentRunId?: string,
384-
_tags?: string[]
412+
_tags?: string[],
385413
): Promise<void> {
386414
const spanData = this.spans.get(runId);
387415
if (!spanData) return;
@@ -403,7 +431,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
403431
err: Error,
404432
runId: string,
405433
_parentRunId?: string,
406-
_tags?: string[]
434+
_tags?: string[],
407435
): Promise<void> {
408436
const spanData = this.spans.get(runId);
409437
if (!spanData) return;
@@ -418,39 +446,38 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
418446
private extractModelName(llm: Serialized): string {
419447
// Extract from class hierarchy - last element is usually the class name
420448
const className = llm.id?.[llm.id.length - 1] || "unknown";
421-
449+
422450
// For BedrockChat, try to get the actual model name
423451
if (className === "BedrockChat") {
424452
// The model name might be available in kwargs - cast to any to access kwargs
425453
const llmAny = llm as any;
426454
const modelId = llmAny.kwargs?.model || llmAny.kwargs?.model_id;
427-
if (modelId && typeof modelId === 'string') {
455+
if (modelId && typeof modelId === "string") {
428456
// Extract clean model name from full ID (e.g., "us.anthropic.claude-3-7-sonnet-20250219-v1:0" -> "claude-3-7-sonnet")
429-
const parts = modelId.split('.');
457+
const parts = modelId.split(".");
430458
if (parts.length >= 3) {
431-
const modelPart = parts.slice(2).join('.').split(':')[0]; // Remove region and version
432-
return modelPart.replace('-20250219-v1', ''); // Clean up version suffix
459+
const modelPart = parts.slice(2).join(".").split(":")[0]; // Remove region and version
460+
return modelPart.replace("-20250219-v1", ""); // Clean up version suffix
433461
}
434462
return modelId;
435463
}
436464
}
437-
465+
438466
return className;
439467
}
440468

441469
private convertClassNameToSpanName(className: string): string {
442470
// Convert PascalCase to lowercase with dots
443471
// BedrockChat -> bedrock.chat
444472
// ChatOpenAI -> chat.openai
445-
return className
446-
.replace(/([A-Z])/g, (match, char, index) => {
447-
return index === 0 ? char.toLowerCase() : `.${char.toLowerCase()}`;
448-
});
473+
return className.replace(/([A-Z])/g, (match, char, index) => {
474+
return index === 0 ? char.toLowerCase() : `.${char.toLowerCase()}`;
475+
});
449476
}
450477

451478
private detectVendor(llm: Serialized): string {
452479
const className = llm.id?.[llm.id.length - 1] || "";
453-
480+
454481
// Follow Python implementation - map class names to vendors
455482
if (className.includes("OpenAI") || className.includes("GPT")) {
456483
return "OpenAI";
@@ -477,7 +504,7 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
477504
if (className.includes("Cohere")) {
478505
return "Cohere";
479506
}
480-
507+
481508
return "LangChain";
482509
}
483510

@@ -496,4 +523,4 @@ export class TraceloopCallbackHandler extends BaseCallbackHandler {
496523
return messageType;
497524
}
498525
}
499-
}
526+
}

0 commit comments

Comments
 (0)