@visibe.ai/node 0.1.25 → 0.1.27
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.
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LangChainCallback = exports.LANGGRAPH_INTERNAL_NODES = exports.activeLangChainStorage = void 0;
|
|
4
4
|
exports.patchRunnableSequence = patchRunnableSequence;
|
|
5
5
|
exports.patchAgentExecutor = patchAgentExecutor;
|
|
6
|
+
exports.serializeInput = serializeInput;
|
|
6
7
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
7
8
|
const node_crypto_1 = require("node:crypto");
|
|
8
9
|
const utils_1 = require("../utils");
|
|
@@ -23,8 +24,19 @@ function extractTokenUsage(output) {
|
|
|
23
24
|
outputTokens: usage?.completionTokens ?? usage?.output_tokens ?? 0,
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
|
-
// Internal LangGraph
|
|
27
|
-
|
|
27
|
+
// Internal LangGraph/LangChain node names — never emit agent_start spans for these.
|
|
28
|
+
// Includes LangGraph system nodes and LangChain Runnable primitives that wrap
|
|
29
|
+
// routing functions (e.g. addConditionalEdges wraps the condition in a RunnableLambda).
|
|
30
|
+
exports.LANGGRAPH_INTERNAL_NODES = new Set([
|
|
31
|
+
'__start__',
|
|
32
|
+
'__end__',
|
|
33
|
+
'LangGraph',
|
|
34
|
+
'RunnableLambda',
|
|
35
|
+
'RunnableSequence',
|
|
36
|
+
'RunnableParallel',
|
|
37
|
+
'RunnablePassthrough',
|
|
38
|
+
'RunnableBranch',
|
|
39
|
+
]);
|
|
28
40
|
// ---------------------------------------------------------------------------
|
|
29
41
|
// LangChainCallback
|
|
30
42
|
// ---------------------------------------------------------------------------
|
|
@@ -68,6 +80,8 @@ class LangChainCallback {
|
|
|
68
80
|
this.totalOutputTokens = 0;
|
|
69
81
|
this.totalCost = 0;
|
|
70
82
|
this.llmCallCount = 0;
|
|
83
|
+
// First model seen across all LLM calls in this trace — set on first handleLLMEnd.
|
|
84
|
+
this.firstModel = undefined;
|
|
71
85
|
this.visibe = options.visibe;
|
|
72
86
|
this.traceId = options.traceId;
|
|
73
87
|
this.agentName = options.agentName;
|
|
@@ -133,6 +147,8 @@ class LangChainCallback {
|
|
|
133
147
|
this.totalOutputTokens += outputTokens;
|
|
134
148
|
this.totalCost += cost;
|
|
135
149
|
this.llmCallCount++;
|
|
150
|
+
if (!this.firstModel)
|
|
151
|
+
this.firstModel = model;
|
|
136
152
|
this._onLLMSpan?.(inputTokens, outputTokens, cost);
|
|
137
153
|
}
|
|
138
154
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -239,6 +255,7 @@ function patchRunnableSequence(lcModule, visibe) {
|
|
|
239
255
|
name: 'langchain',
|
|
240
256
|
framework: 'langchain',
|
|
241
257
|
started_at: startedAt,
|
|
258
|
+
prompt: serializeInput(input),
|
|
242
259
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
243
260
|
});
|
|
244
261
|
const cb = new LangChainCallback({ visibe, traceId, agentName: 'langchain' });
|
|
@@ -263,6 +280,7 @@ function patchRunnableSequence(lcModule, visibe) {
|
|
|
263
280
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
264
281
|
total_input_tokens: cb.totalInputTokens,
|
|
265
282
|
total_output_tokens: cb.totalOutputTokens,
|
|
283
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
266
284
|
});
|
|
267
285
|
}
|
|
268
286
|
return result;
|
|
@@ -281,6 +299,7 @@ function patchRunnableSequence(lcModule, visibe) {
|
|
|
281
299
|
name: 'langchain',
|
|
282
300
|
framework: 'langchain',
|
|
283
301
|
started_at: startedAt,
|
|
302
|
+
prompt: serializeInput(input),
|
|
284
303
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
285
304
|
});
|
|
286
305
|
const cb = new LangChainCallback({ visibe, traceId, agentName: 'langchain' });
|
|
@@ -304,6 +323,7 @@ function patchRunnableSequence(lcModule, visibe) {
|
|
|
304
323
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
305
324
|
total_input_tokens: cb.totalInputTokens,
|
|
306
325
|
total_output_tokens: cb.totalOutputTokens,
|
|
326
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
307
327
|
});
|
|
308
328
|
}
|
|
309
329
|
};
|
|
@@ -341,6 +361,7 @@ function patchAgentExecutor(agentsModule, visibe) {
|
|
|
341
361
|
name: agentName,
|
|
342
362
|
framework: 'langchain',
|
|
343
363
|
started_at: startedAt,
|
|
364
|
+
prompt: serializeInput(input),
|
|
344
365
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
345
366
|
});
|
|
346
367
|
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
@@ -365,6 +386,7 @@ function patchAgentExecutor(agentsModule, visibe) {
|
|
|
365
386
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
366
387
|
total_input_tokens: cb.totalInputTokens,
|
|
367
388
|
total_output_tokens: cb.totalOutputTokens,
|
|
389
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
368
390
|
});
|
|
369
391
|
}
|
|
370
392
|
return result;
|
|
@@ -384,6 +406,7 @@ function patchAgentExecutor(agentsModule, visibe) {
|
|
|
384
406
|
name: agentName,
|
|
385
407
|
framework: 'langchain',
|
|
386
408
|
started_at: startedAt,
|
|
409
|
+
prompt: serializeInput(input),
|
|
387
410
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
388
411
|
});
|
|
389
412
|
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
@@ -407,6 +430,7 @@ function patchAgentExecutor(agentsModule, visibe) {
|
|
|
407
430
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
408
431
|
total_input_tokens: cb.totalInputTokens,
|
|
409
432
|
total_output_tokens: cb.totalOutputTokens,
|
|
433
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
410
434
|
});
|
|
411
435
|
}
|
|
412
436
|
};
|
|
@@ -425,3 +449,37 @@ function _mergeCallbacks(config, cb) {
|
|
|
425
449
|
const existing = Array.isArray(config.callbacks) ? config.callbacks : [];
|
|
426
450
|
return { ...config, callbacks: [...existing, cb] };
|
|
427
451
|
}
|
|
452
|
+
// Serialize a graph/chain input to a prompt string for the trace header.
|
|
453
|
+
// Handles strings, common object shapes, and falls back to JSON.
|
|
454
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
455
|
+
function serializeInput(input, limit = 2000) {
|
|
456
|
+
if (!input)
|
|
457
|
+
return undefined;
|
|
458
|
+
let s;
|
|
459
|
+
if (typeof input === 'string') {
|
|
460
|
+
s = input;
|
|
461
|
+
}
|
|
462
|
+
else if (typeof input === 'object') {
|
|
463
|
+
// Try common single-field patterns first.
|
|
464
|
+
for (const key of ['task', 'prompt', 'input', 'query', 'question', 'text', 'content']) {
|
|
465
|
+
if (typeof input[key] === 'string') {
|
|
466
|
+
s = input[key];
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!s) {
|
|
471
|
+
// HumanMessage / messages array — grab the last message content.
|
|
472
|
+
if (Array.isArray(input.messages) && input.messages.length > 0) {
|
|
473
|
+
const last = input.messages[input.messages.length - 1];
|
|
474
|
+
s = typeof last?.content === 'string' ? last.content : JSON.stringify(last?.content ?? '');
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
s = JSON.stringify(input);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
s = String(input);
|
|
483
|
+
}
|
|
484
|
+
return s.length > limit ? s.slice(0, limit) + '…' : s;
|
|
485
|
+
}
|
|
@@ -68,6 +68,7 @@ function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
68
68
|
name: graphName,
|
|
69
69
|
framework: 'langgraph',
|
|
70
70
|
started_at: startedAt,
|
|
71
|
+
prompt: (0, langchain_1.serializeInput)(input),
|
|
71
72
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
72
73
|
});
|
|
73
74
|
// Collect node names from the graph's node registry.
|
|
@@ -98,6 +99,7 @@ function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
98
99
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
99
100
|
total_input_tokens: cb.totalInputTokens,
|
|
100
101
|
total_output_tokens: cb.totalOutputTokens,
|
|
102
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
return result;
|
|
@@ -119,6 +121,7 @@ function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
119
121
|
name: graphName,
|
|
120
122
|
framework: 'langgraph',
|
|
121
123
|
started_at: startedAt,
|
|
124
|
+
prompt: (0, langchain_1.serializeInput)(input),
|
|
122
125
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
123
126
|
});
|
|
124
127
|
const nodeNames = _extractNodeNames(this);
|
|
@@ -150,6 +153,7 @@ function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
150
153
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
151
154
|
total_input_tokens: cb.totalInputTokens,
|
|
152
155
|
total_output_tokens: cb.totalOutputTokens,
|
|
156
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
153
157
|
});
|
|
154
158
|
}
|
|
155
159
|
};
|
|
@@ -18,8 +18,19 @@ function extractTokenUsage(output) {
|
|
|
18
18
|
outputTokens: usage?.completionTokens ?? usage?.output_tokens ?? 0,
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
// Internal LangGraph
|
|
22
|
-
|
|
21
|
+
// Internal LangGraph/LangChain node names — never emit agent_start spans for these.
|
|
22
|
+
// Includes LangGraph system nodes and LangChain Runnable primitives that wrap
|
|
23
|
+
// routing functions (e.g. addConditionalEdges wraps the condition in a RunnableLambda).
|
|
24
|
+
export const LANGGRAPH_INTERNAL_NODES = new Set([
|
|
25
|
+
'__start__',
|
|
26
|
+
'__end__',
|
|
27
|
+
'LangGraph',
|
|
28
|
+
'RunnableLambda',
|
|
29
|
+
'RunnableSequence',
|
|
30
|
+
'RunnableParallel',
|
|
31
|
+
'RunnablePassthrough',
|
|
32
|
+
'RunnableBranch',
|
|
33
|
+
]);
|
|
23
34
|
// ---------------------------------------------------------------------------
|
|
24
35
|
// LangChainCallback
|
|
25
36
|
// ---------------------------------------------------------------------------
|
|
@@ -63,6 +74,8 @@ export class LangChainCallback {
|
|
|
63
74
|
this.totalOutputTokens = 0;
|
|
64
75
|
this.totalCost = 0;
|
|
65
76
|
this.llmCallCount = 0;
|
|
77
|
+
// First model seen across all LLM calls in this trace — set on first handleLLMEnd.
|
|
78
|
+
this.firstModel = undefined;
|
|
66
79
|
this.visibe = options.visibe;
|
|
67
80
|
this.traceId = options.traceId;
|
|
68
81
|
this.agentName = options.agentName;
|
|
@@ -128,6 +141,8 @@ export class LangChainCallback {
|
|
|
128
141
|
this.totalOutputTokens += outputTokens;
|
|
129
142
|
this.totalCost += cost;
|
|
130
143
|
this.llmCallCount++;
|
|
144
|
+
if (!this.firstModel)
|
|
145
|
+
this.firstModel = model;
|
|
131
146
|
this._onLLMSpan?.(inputTokens, outputTokens, cost);
|
|
132
147
|
}
|
|
133
148
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -233,6 +248,7 @@ export function patchRunnableSequence(lcModule, visibe) {
|
|
|
233
248
|
name: 'langchain',
|
|
234
249
|
framework: 'langchain',
|
|
235
250
|
started_at: startedAt,
|
|
251
|
+
prompt: serializeInput(input),
|
|
236
252
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
237
253
|
});
|
|
238
254
|
const cb = new LangChainCallback({ visibe, traceId, agentName: 'langchain' });
|
|
@@ -257,6 +273,7 @@ export function patchRunnableSequence(lcModule, visibe) {
|
|
|
257
273
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
258
274
|
total_input_tokens: cb.totalInputTokens,
|
|
259
275
|
total_output_tokens: cb.totalOutputTokens,
|
|
276
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
260
277
|
});
|
|
261
278
|
}
|
|
262
279
|
return result;
|
|
@@ -275,6 +292,7 @@ export function patchRunnableSequence(lcModule, visibe) {
|
|
|
275
292
|
name: 'langchain',
|
|
276
293
|
framework: 'langchain',
|
|
277
294
|
started_at: startedAt,
|
|
295
|
+
prompt: serializeInput(input),
|
|
278
296
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
279
297
|
});
|
|
280
298
|
const cb = new LangChainCallback({ visibe, traceId, agentName: 'langchain' });
|
|
@@ -298,6 +316,7 @@ export function patchRunnableSequence(lcModule, visibe) {
|
|
|
298
316
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
299
317
|
total_input_tokens: cb.totalInputTokens,
|
|
300
318
|
total_output_tokens: cb.totalOutputTokens,
|
|
319
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
301
320
|
});
|
|
302
321
|
}
|
|
303
322
|
};
|
|
@@ -335,6 +354,7 @@ export function patchAgentExecutor(agentsModule, visibe) {
|
|
|
335
354
|
name: agentName,
|
|
336
355
|
framework: 'langchain',
|
|
337
356
|
started_at: startedAt,
|
|
357
|
+
prompt: serializeInput(input),
|
|
338
358
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
339
359
|
});
|
|
340
360
|
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
@@ -359,6 +379,7 @@ export function patchAgentExecutor(agentsModule, visibe) {
|
|
|
359
379
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
360
380
|
total_input_tokens: cb.totalInputTokens,
|
|
361
381
|
total_output_tokens: cb.totalOutputTokens,
|
|
382
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
362
383
|
});
|
|
363
384
|
}
|
|
364
385
|
return result;
|
|
@@ -378,6 +399,7 @@ export function patchAgentExecutor(agentsModule, visibe) {
|
|
|
378
399
|
name: agentName,
|
|
379
400
|
framework: 'langchain',
|
|
380
401
|
started_at: startedAt,
|
|
402
|
+
prompt: serializeInput(input),
|
|
381
403
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
382
404
|
});
|
|
383
405
|
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
@@ -401,6 +423,7 @@ export function patchAgentExecutor(agentsModule, visibe) {
|
|
|
401
423
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
402
424
|
total_input_tokens: cb.totalInputTokens,
|
|
403
425
|
total_output_tokens: cb.totalOutputTokens,
|
|
426
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
404
427
|
});
|
|
405
428
|
}
|
|
406
429
|
};
|
|
@@ -419,3 +442,37 @@ function _mergeCallbacks(config, cb) {
|
|
|
419
442
|
const existing = Array.isArray(config.callbacks) ? config.callbacks : [];
|
|
420
443
|
return { ...config, callbacks: [...existing, cb] };
|
|
421
444
|
}
|
|
445
|
+
// Serialize a graph/chain input to a prompt string for the trace header.
|
|
446
|
+
// Handles strings, common object shapes, and falls back to JSON.
|
|
447
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
448
|
+
export function serializeInput(input, limit = 2000) {
|
|
449
|
+
if (!input)
|
|
450
|
+
return undefined;
|
|
451
|
+
let s;
|
|
452
|
+
if (typeof input === 'string') {
|
|
453
|
+
s = input;
|
|
454
|
+
}
|
|
455
|
+
else if (typeof input === 'object') {
|
|
456
|
+
// Try common single-field patterns first.
|
|
457
|
+
for (const key of ['task', 'prompt', 'input', 'query', 'question', 'text', 'content']) {
|
|
458
|
+
if (typeof input[key] === 'string') {
|
|
459
|
+
s = input[key];
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (!s) {
|
|
464
|
+
// HumanMessage / messages array — grab the last message content.
|
|
465
|
+
if (Array.isArray(input.messages) && input.messages.length > 0) {
|
|
466
|
+
const last = input.messages[input.messages.length - 1];
|
|
467
|
+
s = typeof last?.content === 'string' ? last.content : JSON.stringify(last?.content ?? '');
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
s = JSON.stringify(input);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
s = String(input);
|
|
476
|
+
}
|
|
477
|
+
return s.length > limit ? s.slice(0, limit) + '…' : s;
|
|
478
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { LangChainCallback, activeLangChainStorage, LANGGRAPH_INTERNAL_NODES } from './langchain.js';
|
|
2
|
+
import { LangChainCallback, activeLangChainStorage, LANGGRAPH_INTERNAL_NODES, serializeInput } from './langchain.js';
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
// LangGraphCallback
|
|
5
5
|
// Extends LangChainCallback and adds node-level agent_start spans.
|
|
@@ -63,6 +63,7 @@ export function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
63
63
|
name: graphName,
|
|
64
64
|
framework: 'langgraph',
|
|
65
65
|
started_at: startedAt,
|
|
66
|
+
prompt: serializeInput(input),
|
|
66
67
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
67
68
|
});
|
|
68
69
|
// Collect node names from the graph's node registry.
|
|
@@ -93,6 +94,7 @@ export function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
93
94
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
94
95
|
total_input_tokens: cb.totalInputTokens,
|
|
95
96
|
total_output_tokens: cb.totalOutputTokens,
|
|
97
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
96
98
|
});
|
|
97
99
|
}
|
|
98
100
|
return result;
|
|
@@ -114,6 +116,7 @@ export function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
114
116
|
name: graphName,
|
|
115
117
|
framework: 'langgraph',
|
|
116
118
|
started_at: startedAt,
|
|
119
|
+
prompt: serializeInput(input),
|
|
117
120
|
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
118
121
|
});
|
|
119
122
|
const nodeNames = _extractNodeNames(this);
|
|
@@ -145,6 +148,7 @@ export function patchCompiledStateGraph(lgModule, visibe) {
|
|
|
145
148
|
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
146
149
|
total_input_tokens: cb.totalInputTokens,
|
|
147
150
|
total_output_tokens: cb.totalOutputTokens,
|
|
151
|
+
...(cb.firstModel ? { model: cb.firstModel } : {}),
|
|
148
152
|
});
|
|
149
153
|
}
|
|
150
154
|
};
|
|
@@ -30,6 +30,7 @@ export declare class LangChainCallback {
|
|
|
30
30
|
totalOutputTokens: number;
|
|
31
31
|
totalCost: number;
|
|
32
32
|
llmCallCount: number;
|
|
33
|
+
firstModel: string | undefined;
|
|
33
34
|
constructor(options: {
|
|
34
35
|
visibe: Visibe;
|
|
35
36
|
traceId: string;
|
|
@@ -50,3 +51,4 @@ export declare class LangChainCallback {
|
|
|
50
51
|
}
|
|
51
52
|
export declare function patchRunnableSequence(lcModule: any, visibe: Visibe): () => void;
|
|
52
53
|
export declare function patchAgentExecutor(agentsModule: any, visibe: Visibe): () => void;
|
|
54
|
+
export declare function serializeInput(input: any, limit?: number): string | undefined;
|
package/package.json
CHANGED