@visibe.ai/node 0.1.21 → 0.1.22
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/index.js
CHANGED
|
@@ -190,12 +190,25 @@ async function patchFramework(framework, client) {
|
|
|
190
190
|
}
|
|
191
191
|
case 'langchain': {
|
|
192
192
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
193
|
-
const { patchRunnableSequence } = await Promise.resolve().then(() => __importStar(require('./integrations/langchain')));
|
|
193
|
+
const { patchRunnableSequence, patchAgentExecutor } = await Promise.resolve().then(() => __importStar(require('./integrations/langchain')));
|
|
194
194
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
195
195
|
const lcModule = await Promise.resolve().then(() => __importStar(require('@langchain/core/runnables')));
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
const r1 = patchRunnableSequence(lcModule, client);
|
|
197
|
+
// Also patch AgentExecutor (langchain/agents) if installed — AgentExecutor is NOT a
|
|
198
|
+
// RunnableSequence so without this patch each agent loop iteration creates a separate trace.
|
|
199
|
+
let r2;
|
|
200
|
+
try {
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
202
|
+
const agentsModule = await Promise.resolve().then(() => __importStar(require('langchain/agents')));
|
|
203
|
+
r2 = patchAgentExecutor(agentsModule, client);
|
|
204
|
+
}
|
|
205
|
+
catch { /* langchain package not installed — skip */ }
|
|
206
|
+
_lcRestore = () => {
|
|
207
|
+
if (typeof r1 === 'function')
|
|
208
|
+
r1();
|
|
209
|
+
if (typeof r2 === 'function')
|
|
210
|
+
r2();
|
|
211
|
+
};
|
|
199
212
|
break;
|
|
200
213
|
}
|
|
201
214
|
case 'vercel_ai': {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LangChainCallback = exports.LANGGRAPH_INTERNAL_NODES = exports.activeLangChainStorage = void 0;
|
|
4
4
|
exports.patchRunnableSequence = patchRunnableSequence;
|
|
5
|
+
exports.patchAgentExecutor = patchAgentExecutor;
|
|
5
6
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
6
7
|
const node_crypto_1 = require("node:crypto");
|
|
7
8
|
const utils_1 = require("../utils");
|
|
@@ -312,6 +313,109 @@ function patchRunnableSequence(lcModule, visibe) {
|
|
|
312
313
|
};
|
|
313
314
|
}
|
|
314
315
|
// ---------------------------------------------------------------------------
|
|
316
|
+
// patchAgentExecutor — patches AgentExecutor from `langchain/agents` so the
|
|
317
|
+
// entire multi-step agent loop is captured as ONE trace.
|
|
318
|
+
//
|
|
319
|
+
// AgentExecutor is NOT a RunnableSequence — it extends Runnable directly and
|
|
320
|
+
// calls the inner agent RunnableSequence in a loop. Without this patch each
|
|
321
|
+
// iteration fires patchRunnableSequence and creates a separate trace.
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
324
|
+
function patchAgentExecutor(agentsModule, visibe) {
|
|
325
|
+
const AgentExecutor = agentsModule?.AgentExecutor;
|
|
326
|
+
if (!AgentExecutor)
|
|
327
|
+
return () => { };
|
|
328
|
+
const originalInvoke = AgentExecutor.prototype.invoke;
|
|
329
|
+
const originalStream = AgentExecutor.prototype.stream;
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
331
|
+
AgentExecutor.prototype.invoke = async function (input, config) {
|
|
332
|
+
if (exports.activeLangChainStorage.getStore() !== undefined) {
|
|
333
|
+
return originalInvoke.call(this, input, config);
|
|
334
|
+
}
|
|
335
|
+
const traceId = (0, node_crypto_1.randomUUID)();
|
|
336
|
+
const startedAt = new Date().toISOString();
|
|
337
|
+
const startMs = Date.now();
|
|
338
|
+
const agentName = this.name ?? 'langchain';
|
|
339
|
+
await visibe.apiClient.createTrace({
|
|
340
|
+
trace_id: traceId,
|
|
341
|
+
name: agentName,
|
|
342
|
+
framework: 'langchain',
|
|
343
|
+
started_at: startedAt,
|
|
344
|
+
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
345
|
+
});
|
|
346
|
+
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
347
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
348
|
+
let result;
|
|
349
|
+
let status = 'completed';
|
|
350
|
+
try {
|
|
351
|
+
result = await exports.activeLangChainStorage.run(cb, () => originalInvoke.call(this, input, _mergeCallbacks(config, cb)));
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
status = 'failed';
|
|
355
|
+
throw err;
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
visibe.batcher.flush();
|
|
359
|
+
await visibe.apiClient.completeTrace(traceId, {
|
|
360
|
+
status,
|
|
361
|
+
ended_at: new Date().toISOString(),
|
|
362
|
+
duration_ms: Date.now() - startMs,
|
|
363
|
+
llm_call_count: cb.llmCallCount,
|
|
364
|
+
total_cost: cb.totalCost,
|
|
365
|
+
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
366
|
+
total_input_tokens: cb.totalInputTokens,
|
|
367
|
+
total_output_tokens: cb.totalOutputTokens,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return result;
|
|
371
|
+
};
|
|
372
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
373
|
+
AgentExecutor.prototype.stream = async function* (input, config) {
|
|
374
|
+
if (exports.activeLangChainStorage.getStore() !== undefined) {
|
|
375
|
+
yield* (await originalStream.call(this, input, config));
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const traceId = (0, node_crypto_1.randomUUID)();
|
|
379
|
+
const startedAt = new Date().toISOString();
|
|
380
|
+
const startMs = Date.now();
|
|
381
|
+
const agentName = this.name ?? 'langchain';
|
|
382
|
+
await visibe.apiClient.createTrace({
|
|
383
|
+
trace_id: traceId,
|
|
384
|
+
name: agentName,
|
|
385
|
+
framework: 'langchain',
|
|
386
|
+
started_at: startedAt,
|
|
387
|
+
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
388
|
+
});
|
|
389
|
+
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
390
|
+
let status = 'completed';
|
|
391
|
+
try {
|
|
392
|
+
const gen = await exports.activeLangChainStorage.run(cb, () => originalStream.call(this, input, _mergeCallbacks(config, cb)));
|
|
393
|
+
yield* gen;
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
status = 'failed';
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
finally {
|
|
400
|
+
visibe.batcher.flush();
|
|
401
|
+
await visibe.apiClient.completeTrace(traceId, {
|
|
402
|
+
status,
|
|
403
|
+
ended_at: new Date().toISOString(),
|
|
404
|
+
duration_ms: Date.now() - startMs,
|
|
405
|
+
llm_call_count: cb.llmCallCount,
|
|
406
|
+
total_cost: cb.totalCost,
|
|
407
|
+
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
408
|
+
total_input_tokens: cb.totalInputTokens,
|
|
409
|
+
total_output_tokens: cb.totalOutputTokens,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
return () => {
|
|
414
|
+
AgentExecutor.prototype.invoke = originalInvoke;
|
|
415
|
+
AgentExecutor.prototype.stream = originalStream;
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
315
419
|
// Private helpers
|
|
316
420
|
// ---------------------------------------------------------------------------
|
|
317
421
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/dist/esm/index.js
CHANGED
|
@@ -151,12 +151,25 @@ async function patchFramework(framework, client) {
|
|
|
151
151
|
}
|
|
152
152
|
case 'langchain': {
|
|
153
153
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
|
-
const { patchRunnableSequence } = await import('./integrations/langchain.js');
|
|
154
|
+
const { patchRunnableSequence, patchAgentExecutor } = await import('./integrations/langchain.js');
|
|
155
155
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
156
156
|
const lcModule = await import('@langchain/core/runnables');
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const r1 = patchRunnableSequence(lcModule, client);
|
|
158
|
+
// Also patch AgentExecutor (langchain/agents) if installed — AgentExecutor is NOT a
|
|
159
|
+
// RunnableSequence so without this patch each agent loop iteration creates a separate trace.
|
|
160
|
+
let r2;
|
|
161
|
+
try {
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
163
|
+
const agentsModule = await import('langchain/agents');
|
|
164
|
+
r2 = patchAgentExecutor(agentsModule, client);
|
|
165
|
+
}
|
|
166
|
+
catch { /* langchain package not installed — skip */ }
|
|
167
|
+
_lcRestore = () => {
|
|
168
|
+
if (typeof r1 === 'function')
|
|
169
|
+
r1();
|
|
170
|
+
if (typeof r2 === 'function')
|
|
171
|
+
r2();
|
|
172
|
+
};
|
|
160
173
|
break;
|
|
161
174
|
}
|
|
162
175
|
case 'vercel_ai': {
|
|
@@ -307,6 +307,109 @@ export function patchRunnableSequence(lcModule, visibe) {
|
|
|
307
307
|
};
|
|
308
308
|
}
|
|
309
309
|
// ---------------------------------------------------------------------------
|
|
310
|
+
// patchAgentExecutor — patches AgentExecutor from `langchain/agents` so the
|
|
311
|
+
// entire multi-step agent loop is captured as ONE trace.
|
|
312
|
+
//
|
|
313
|
+
// AgentExecutor is NOT a RunnableSequence — it extends Runnable directly and
|
|
314
|
+
// calls the inner agent RunnableSequence in a loop. Without this patch each
|
|
315
|
+
// iteration fires patchRunnableSequence and creates a separate trace.
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
318
|
+
export function patchAgentExecutor(agentsModule, visibe) {
|
|
319
|
+
const AgentExecutor = agentsModule?.AgentExecutor;
|
|
320
|
+
if (!AgentExecutor)
|
|
321
|
+
return () => { };
|
|
322
|
+
const originalInvoke = AgentExecutor.prototype.invoke;
|
|
323
|
+
const originalStream = AgentExecutor.prototype.stream;
|
|
324
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
325
|
+
AgentExecutor.prototype.invoke = async function (input, config) {
|
|
326
|
+
if (activeLangChainStorage.getStore() !== undefined) {
|
|
327
|
+
return originalInvoke.call(this, input, config);
|
|
328
|
+
}
|
|
329
|
+
const traceId = randomUUID();
|
|
330
|
+
const startedAt = new Date().toISOString();
|
|
331
|
+
const startMs = Date.now();
|
|
332
|
+
const agentName = this.name ?? 'langchain';
|
|
333
|
+
await visibe.apiClient.createTrace({
|
|
334
|
+
trace_id: traceId,
|
|
335
|
+
name: agentName,
|
|
336
|
+
framework: 'langchain',
|
|
337
|
+
started_at: startedAt,
|
|
338
|
+
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
339
|
+
});
|
|
340
|
+
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
341
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
342
|
+
let result;
|
|
343
|
+
let status = 'completed';
|
|
344
|
+
try {
|
|
345
|
+
result = await activeLangChainStorage.run(cb, () => originalInvoke.call(this, input, _mergeCallbacks(config, cb)));
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
status = 'failed';
|
|
349
|
+
throw err;
|
|
350
|
+
}
|
|
351
|
+
finally {
|
|
352
|
+
visibe.batcher.flush();
|
|
353
|
+
await visibe.apiClient.completeTrace(traceId, {
|
|
354
|
+
status,
|
|
355
|
+
ended_at: new Date().toISOString(),
|
|
356
|
+
duration_ms: Date.now() - startMs,
|
|
357
|
+
llm_call_count: cb.llmCallCount,
|
|
358
|
+
total_cost: cb.totalCost,
|
|
359
|
+
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
360
|
+
total_input_tokens: cb.totalInputTokens,
|
|
361
|
+
total_output_tokens: cb.totalOutputTokens,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
};
|
|
366
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
367
|
+
AgentExecutor.prototype.stream = async function* (input, config) {
|
|
368
|
+
if (activeLangChainStorage.getStore() !== undefined) {
|
|
369
|
+
yield* (await originalStream.call(this, input, config));
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const traceId = randomUUID();
|
|
373
|
+
const startedAt = new Date().toISOString();
|
|
374
|
+
const startMs = Date.now();
|
|
375
|
+
const agentName = this.name ?? 'langchain';
|
|
376
|
+
await visibe.apiClient.createTrace({
|
|
377
|
+
trace_id: traceId,
|
|
378
|
+
name: agentName,
|
|
379
|
+
framework: 'langchain',
|
|
380
|
+
started_at: startedAt,
|
|
381
|
+
...(visibe.sessionId ? { session_id: visibe.sessionId } : {}),
|
|
382
|
+
});
|
|
383
|
+
const cb = new LangChainCallback({ visibe, traceId, agentName });
|
|
384
|
+
let status = 'completed';
|
|
385
|
+
try {
|
|
386
|
+
const gen = await activeLangChainStorage.run(cb, () => originalStream.call(this, input, _mergeCallbacks(config, cb)));
|
|
387
|
+
yield* gen;
|
|
388
|
+
}
|
|
389
|
+
catch (err) {
|
|
390
|
+
status = 'failed';
|
|
391
|
+
throw err;
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
visibe.batcher.flush();
|
|
395
|
+
await visibe.apiClient.completeTrace(traceId, {
|
|
396
|
+
status,
|
|
397
|
+
ended_at: new Date().toISOString(),
|
|
398
|
+
duration_ms: Date.now() - startMs,
|
|
399
|
+
llm_call_count: cb.llmCallCount,
|
|
400
|
+
total_cost: cb.totalCost,
|
|
401
|
+
total_tokens: cb.totalInputTokens + cb.totalOutputTokens,
|
|
402
|
+
total_input_tokens: cb.totalInputTokens,
|
|
403
|
+
total_output_tokens: cb.totalOutputTokens,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
return () => {
|
|
408
|
+
AgentExecutor.prototype.invoke = originalInvoke;
|
|
409
|
+
AgentExecutor.prototype.stream = originalStream;
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
310
413
|
// Private helpers
|
|
311
414
|
// ---------------------------------------------------------------------------
|
|
312
415
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/package.json
CHANGED