@visibe.ai/node 0.1.20 → 0.1.21

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.
@@ -31,6 +31,16 @@ class LangChainCallback {
31
31
  nextSpanId() {
32
32
  return `step_${++this.stepCounter}`;
33
33
  }
34
+ // Walk up the run parent chain to find the nearest agent name.
35
+ // Falls back to this.agentName if no ancestor has an associated agent.
36
+ _findAgentName(runId) {
37
+ if (!runId)
38
+ return this.agentName;
39
+ const name = this.runIdToAgentName.get(runId);
40
+ if (name)
41
+ return name;
42
+ return this._findAgentName(this.runIdToParent.get(runId));
43
+ }
34
44
  constructor(options) {
35
45
  // Required by @langchain/core v1+ for proper callback registration.
36
46
  // Without `name`, ensureHandler() wraps via fromMethods() which drops prototype methods.
@@ -41,6 +51,11 @@ class LangChainCallback {
41
51
  this.raiseError = false;
42
52
  // Maps LangChain runId → our spanId so we can set parent_span_id.
43
53
  this.runIdToSpanId = new Map();
54
+ // Tracks parent run IDs so we can walk up the chain hierarchy.
55
+ this.runIdToParent = new Map();
56
+ // Maps runId → agent name for chains that emitted an agent_start span.
57
+ // Used by _findAgentName() to resolve the correct agent for llm_call / tool_call spans.
58
+ this.runIdToAgentName = new Map();
44
59
  // Pending LLM calls: runId → { startMs, model, inputText }
45
60
  this.pendingLLMCalls = new Map();
46
61
  this.pendingToolCalls = new Map();
@@ -103,7 +118,7 @@ class LangChainCallback {
103
118
  const span = this.visibe.buildLLMSpan({
104
119
  spanId,
105
120
  parentSpanId,
106
- agentName: this.agentName,
121
+ agentName: this._findAgentName(parentRunId),
107
122
  model,
108
123
  status: 'success',
109
124
  inputTokens,
@@ -146,7 +161,7 @@ class LangChainCallback {
146
161
  spanId,
147
162
  parentSpanId,
148
163
  toolName: pending?.toolName ?? 'tool',
149
- agentName: this.agentName,
164
+ agentName: this._findAgentName(parentRunId),
150
165
  status: 'success',
151
166
  durationMs: pending ? Date.now() - pending.startMs : 0,
152
167
  inputText: pending?.inputText ?? '',
@@ -175,12 +190,16 @@ class LangChainCallback {
175
190
  if (!this.runIdToSpanId.has(runId)) {
176
191
  this.runIdToSpanId.set(runId, this.nextSpanId());
177
192
  }
193
+ if (_parentRunId) {
194
+ this.runIdToParent.set(runId, _parentRunId);
195
+ }
178
196
  // Emit agent_start for the root chain so LLM spans have a real parent and
179
197
  // the agents breakdown is populated. Subclasses that manage their own
180
198
  // agent_start spans (LangGraphCallback) set _emitRootAgentStart = false.
181
199
  if (this._emitRootAgentStart && !_parentRunId) {
182
200
  const spanId = this.runIdToSpanId.get(runId);
183
201
  const agentName = _name ?? _chain?.name ?? this.agentName;
202
+ this.runIdToAgentName.set(runId, agentName);
184
203
  this.visibe.batcher.add(this.traceId, this.visibe.buildAgentStartSpan({ spanId, agentName }));
185
204
  }
186
205
  }
@@ -31,6 +31,8 @@ class LangGraphCallback extends langchain_1.LangChainCallback {
31
31
  // Use the spanId already assigned by super for this runId.
32
32
  const spanId = this.runIdToSpanId.get(runId) ?? this.nextSpanId();
33
33
  this.runIdToSpanId.set(runId, spanId);
34
+ // Register agent name so _findAgentName() resolves it for child llm_call / tool_call spans.
35
+ this.runIdToAgentName.set(runId, nodeName);
34
36
  this.visibe.batcher.add(this.traceId, this.visibe.buildAgentStartSpan({
35
37
  spanId,
36
38
  agentName: nodeName,
@@ -27,6 +27,16 @@ export class LangChainCallback {
27
27
  nextSpanId() {
28
28
  return `step_${++this.stepCounter}`;
29
29
  }
30
+ // Walk up the run parent chain to find the nearest agent name.
31
+ // Falls back to this.agentName if no ancestor has an associated agent.
32
+ _findAgentName(runId) {
33
+ if (!runId)
34
+ return this.agentName;
35
+ const name = this.runIdToAgentName.get(runId);
36
+ if (name)
37
+ return name;
38
+ return this._findAgentName(this.runIdToParent.get(runId));
39
+ }
30
40
  constructor(options) {
31
41
  // Required by @langchain/core v1+ for proper callback registration.
32
42
  // Without `name`, ensureHandler() wraps via fromMethods() which drops prototype methods.
@@ -37,6 +47,11 @@ export class LangChainCallback {
37
47
  this.raiseError = false;
38
48
  // Maps LangChain runId → our spanId so we can set parent_span_id.
39
49
  this.runIdToSpanId = new Map();
50
+ // Tracks parent run IDs so we can walk up the chain hierarchy.
51
+ this.runIdToParent = new Map();
52
+ // Maps runId → agent name for chains that emitted an agent_start span.
53
+ // Used by _findAgentName() to resolve the correct agent for llm_call / tool_call spans.
54
+ this.runIdToAgentName = new Map();
40
55
  // Pending LLM calls: runId → { startMs, model, inputText }
41
56
  this.pendingLLMCalls = new Map();
42
57
  this.pendingToolCalls = new Map();
@@ -99,7 +114,7 @@ export class LangChainCallback {
99
114
  const span = this.visibe.buildLLMSpan({
100
115
  spanId,
101
116
  parentSpanId,
102
- agentName: this.agentName,
117
+ agentName: this._findAgentName(parentRunId),
103
118
  model,
104
119
  status: 'success',
105
120
  inputTokens,
@@ -142,7 +157,7 @@ export class LangChainCallback {
142
157
  spanId,
143
158
  parentSpanId,
144
159
  toolName: pending?.toolName ?? 'tool',
145
- agentName: this.agentName,
160
+ agentName: this._findAgentName(parentRunId),
146
161
  status: 'success',
147
162
  durationMs: pending ? Date.now() - pending.startMs : 0,
148
163
  inputText: pending?.inputText ?? '',
@@ -171,12 +186,16 @@ export class LangChainCallback {
171
186
  if (!this.runIdToSpanId.has(runId)) {
172
187
  this.runIdToSpanId.set(runId, this.nextSpanId());
173
188
  }
189
+ if (_parentRunId) {
190
+ this.runIdToParent.set(runId, _parentRunId);
191
+ }
174
192
  // Emit agent_start for the root chain so LLM spans have a real parent and
175
193
  // the agents breakdown is populated. Subclasses that manage their own
176
194
  // agent_start spans (LangGraphCallback) set _emitRootAgentStart = false.
177
195
  if (this._emitRootAgentStart && !_parentRunId) {
178
196
  const spanId = this.runIdToSpanId.get(runId);
179
197
  const agentName = _name ?? _chain?.name ?? this.agentName;
198
+ this.runIdToAgentName.set(runId, agentName);
180
199
  this.visibe.batcher.add(this.traceId, this.visibe.buildAgentStartSpan({ spanId, agentName }));
181
200
  }
182
201
  }
@@ -27,6 +27,8 @@ export class LangGraphCallback extends LangChainCallback {
27
27
  // Use the spanId already assigned by super for this runId.
28
28
  const spanId = this.runIdToSpanId.get(runId) ?? this.nextSpanId();
29
29
  this.runIdToSpanId.set(runId, spanId);
30
+ // Register agent name so _findAgentName() resolves it for child llm_call / tool_call spans.
31
+ this.runIdToAgentName.set(runId, nodeName);
30
32
  this.visibe.batcher.add(this.traceId, this.visibe.buildAgentStartSpan({
31
33
  spanId,
32
34
  agentName: nodeName,
@@ -10,6 +10,8 @@ export declare class LangChainCallback {
10
10
  protected readonly traceId: string;
11
11
  protected readonly agentName: string;
12
12
  protected runIdToSpanId: Map<string, string>;
13
+ protected runIdToParent: Map<string, string>;
14
+ protected runIdToAgentName: Map<string, string>;
13
15
  protected pendingLLMCalls: Map<string, {
14
16
  startMs: number;
15
17
  model?: string;
@@ -23,6 +25,7 @@ export declare class LangChainCallback {
23
25
  protected stepCounter: number;
24
26
  protected nextSpanId(): string;
25
27
  protected _emitRootAgentStart: boolean;
28
+ protected _findAgentName(runId?: string): string;
26
29
  totalInputTokens: number;
27
30
  totalOutputTokens: number;
28
31
  totalCost: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visibe.ai/node",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "AI Agent Observability — Track OpenAI, LangChain, LangGraph, Bedrock, Vercel AI, Anthropic",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",