@agent-inspect/langchain 1.1.0 → 1.4.0
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/index.cjs +188 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.mjs +189 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -2
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
|
-
import { Redactor, hasActiveContext, getTraceDirFromContext, resolveTraceDir, getCurrentRunId, createRunId, resolveTraceSafetyOptions, createStepId, initializeTraceFile, prepareTraceEventForDisk, writeTraceEvent } from 'agent-inspect';
|
|
2
|
+
import { Redactor, getCurrentCorrelationMetadata, hasActiveContext, getTraceDirFromContext, resolveTraceDir, getCurrentRunId, createRunId, resolveTraceSafetyOptions, createStepId, initializeTraceFile, prepareTraceEventForDisk, writeTraceEvent } from 'agent-inspect';
|
|
3
3
|
|
|
4
4
|
// packages/langchain/src/agent-inspect-callback.ts
|
|
5
5
|
|
|
@@ -145,6 +145,68 @@ function toPlainMetadata(value) {
|
|
|
145
145
|
return {};
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
+
|
|
149
|
+
// packages/langchain/src/streaming-metadata.ts
|
|
150
|
+
function createLlmStreamState() {
|
|
151
|
+
return {
|
|
152
|
+
chunkCount: 0,
|
|
153
|
+
streamedCharCount: 0,
|
|
154
|
+
previewChars: "",
|
|
155
|
+
previewTruncated: false
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function recordLlmStreamToken(state, token, now, maxPreviewChars) {
|
|
159
|
+
state.chunkCount += 1;
|
|
160
|
+
if (state.firstChunkAt === void 0) {
|
|
161
|
+
state.firstChunkAt = now;
|
|
162
|
+
}
|
|
163
|
+
state.lastChunkAt = now;
|
|
164
|
+
if (typeof token === "string" && token.length > 0) {
|
|
165
|
+
state.streamedCharCount += token.length;
|
|
166
|
+
if (maxPreviewChars > 0) {
|
|
167
|
+
const remaining = maxPreviewChars - state.previewChars.length;
|
|
168
|
+
if (remaining > 0) {
|
|
169
|
+
const slice = token.slice(0, remaining);
|
|
170
|
+
state.previewChars += slice;
|
|
171
|
+
if (token.length > remaining) {
|
|
172
|
+
state.previewTruncated = true;
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
state.previewTruncated = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function streamMetadataFromState(state, options) {
|
|
181
|
+
if (!state || state.chunkCount === 0) {
|
|
182
|
+
return void 0;
|
|
183
|
+
}
|
|
184
|
+
const out = {
|
|
185
|
+
stream: true,
|
|
186
|
+
chunkCount: state.chunkCount,
|
|
187
|
+
streamedCharCount: state.streamedCharCount
|
|
188
|
+
};
|
|
189
|
+
if (state.firstChunkAt !== void 0) {
|
|
190
|
+
out.firstChunkAt = state.firstChunkAt;
|
|
191
|
+
}
|
|
192
|
+
if (state.lastChunkAt !== void 0) {
|
|
193
|
+
out.lastChunkAt = state.lastChunkAt;
|
|
194
|
+
}
|
|
195
|
+
if (state.firstChunkAt !== void 0 && state.lastChunkAt !== void 0 && state.lastChunkAt >= state.firstChunkAt) {
|
|
196
|
+
out.streamDurationMs = state.lastChunkAt - state.firstChunkAt;
|
|
197
|
+
}
|
|
198
|
+
if (state.previewTruncated) {
|
|
199
|
+
out.previewTruncated = true;
|
|
200
|
+
}
|
|
201
|
+
if (options.capturePreview && state.previewChars.length > 0) {
|
|
202
|
+
const preview = state.previewChars.length <= options.maxPreviewChars ? state.previewChars : `${state.previewChars.slice(0, options.maxPreviewChars)}\u2026`;
|
|
203
|
+
out.streamPreview = preview;
|
|
204
|
+
if (state.previewChars.length > options.maxPreviewChars) {
|
|
205
|
+
out.previewTruncated = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
148
210
|
function kindToStepType(kind) {
|
|
149
211
|
switch (kind) {
|
|
150
212
|
case "LLM":
|
|
@@ -241,7 +303,28 @@ var LangChainTracePersistence = class {
|
|
|
241
303
|
}
|
|
242
304
|
async onStepEnd(params) {
|
|
243
305
|
try {
|
|
244
|
-
|
|
306
|
+
let stepId = this.#lcToStepId.get(params.lcRunId);
|
|
307
|
+
if (!stepId && params.completionAttributes) {
|
|
308
|
+
stepId = createStepId();
|
|
309
|
+
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
310
|
+
const parentId = this.resolveParentId(params.lcParentRunId);
|
|
311
|
+
const startTime = params.endTime - (params.durationMs ?? 0);
|
|
312
|
+
const started = {
|
|
313
|
+
schemaVersion: "0.1",
|
|
314
|
+
event: "step_started",
|
|
315
|
+
timestamp: startTime,
|
|
316
|
+
runId: this.#runId,
|
|
317
|
+
stepId,
|
|
318
|
+
...parentId ? { parentId } : {},
|
|
319
|
+
name: String(params.completionAttributes.name ?? "llm:llm"),
|
|
320
|
+
type: kindToStepType(
|
|
321
|
+
params.completionAttributes.kind ?? "LLM"
|
|
322
|
+
),
|
|
323
|
+
startTime,
|
|
324
|
+
metadata: toStepMetadata(params.completionAttributes)
|
|
325
|
+
};
|
|
326
|
+
await this.#write(started);
|
|
327
|
+
}
|
|
245
328
|
if (!stepId) return;
|
|
246
329
|
const durationMs = typeof params.durationMs === "number" && Number.isFinite(params.durationMs) ? Math.max(0, Math.floor(params.durationMs)) : Math.max(0, params.endTime - (this.#runStartTime ?? params.endTime));
|
|
247
330
|
const event = {
|
|
@@ -376,6 +459,8 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
376
459
|
#persistence;
|
|
377
460
|
#events = [];
|
|
378
461
|
#starts = /* @__PURE__ */ new Map();
|
|
462
|
+
#streamState = /* @__PURE__ */ new Map();
|
|
463
|
+
#deferredPersistStart = /* @__PURE__ */ new Map();
|
|
379
464
|
#rootRunId;
|
|
380
465
|
constructor(options = {}) {
|
|
381
466
|
super({});
|
|
@@ -409,9 +494,71 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
409
494
|
clear() {
|
|
410
495
|
this.#events = [];
|
|
411
496
|
this.#starts.clear();
|
|
497
|
+
this.#streamState.clear();
|
|
498
|
+
this.#deferredPersistStart.clear();
|
|
412
499
|
this.#rootRunId = void 0;
|
|
413
500
|
this.#persistence?.reset();
|
|
414
501
|
}
|
|
502
|
+
#streamPreviewLimit() {
|
|
503
|
+
if (this.#opts.capture !== "preview") return 0;
|
|
504
|
+
return this.#opts.maxStreamPreviewChars ?? this.#opts.maxPreviewChars ?? 200;
|
|
505
|
+
}
|
|
506
|
+
#attachStreamMetadata(attrs, lcRunId) {
|
|
507
|
+
const meta = streamMetadataFromState(this.#streamState.get(lcRunId), {
|
|
508
|
+
capturePreview: this.#opts.capture === "preview",
|
|
509
|
+
maxPreviewChars: this.#streamPreviewLimit()
|
|
510
|
+
});
|
|
511
|
+
if (meta) {
|
|
512
|
+
Object.assign(attrs, meta);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
#clearStreamState(lcRunId) {
|
|
516
|
+
this.#streamState.delete(lcRunId);
|
|
517
|
+
this.#deferredPersistStart.delete(lcRunId);
|
|
518
|
+
}
|
|
519
|
+
#mergeCorrelation(attrs) {
|
|
520
|
+
if (this.#opts.capture === "none") return;
|
|
521
|
+
try {
|
|
522
|
+
const corr = getCurrentCorrelationMetadata();
|
|
523
|
+
if (!corr) return;
|
|
524
|
+
for (const [key, value] of Object.entries(corr)) {
|
|
525
|
+
if (typeof value === "string" && value.length > 0) {
|
|
526
|
+
attrs[key] = value;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
} catch {
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
async #persistLlmStepStart(lcRunId, lcParentRunId, name, kind, startTime, attributes) {
|
|
533
|
+
if (this.#opts.stream && this.#opts.persist) {
|
|
534
|
+
this.#deferredPersistStart.set(lcRunId, {
|
|
535
|
+
lcParentRunId,
|
|
536
|
+
name,
|
|
537
|
+
kind,
|
|
538
|
+
startTime,
|
|
539
|
+
attributes: { ...attributes }
|
|
540
|
+
});
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
await this.#persistStepStart(lcRunId, lcParentRunId, name, kind, attributes, startTime);
|
|
544
|
+
}
|
|
545
|
+
async #flushDeferredPersistStart(lcRunId, completionAttributes) {
|
|
546
|
+
const pending = this.#deferredPersistStart.get(lcRunId);
|
|
547
|
+
if (!pending || !this.#opts.persist) return;
|
|
548
|
+
const merged = {
|
|
549
|
+
...pending.attributes,
|
|
550
|
+
...completionAttributes
|
|
551
|
+
};
|
|
552
|
+
await this.#persistStepStart(
|
|
553
|
+
lcRunId,
|
|
554
|
+
pending.lcParentRunId,
|
|
555
|
+
pending.name,
|
|
556
|
+
pending.kind,
|
|
557
|
+
merged,
|
|
558
|
+
pending.startTime
|
|
559
|
+
);
|
|
560
|
+
this.#deferredPersistStart.delete(lcRunId);
|
|
561
|
+
}
|
|
415
562
|
#ensureRoot(lcRunId, parentRunId) {
|
|
416
563
|
if (parentRunId) return;
|
|
417
564
|
if (!this.#rootRunId) this.#rootRunId = lcRunId;
|
|
@@ -474,14 +621,15 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
474
621
|
attributes: attrs
|
|
475
622
|
});
|
|
476
623
|
}
|
|
477
|
-
async #persistStepEnd(lcRunId, lcParentRunId, status, endTime, durationMs, errorMessage) {
|
|
624
|
+
async #persistStepEnd(lcRunId, lcParentRunId, status, endTime, durationMs, errorMessage, completionAttributes) {
|
|
478
625
|
await this.#persistence?.onStepEnd({
|
|
479
626
|
lcRunId,
|
|
480
627
|
lcParentRunId,
|
|
481
628
|
endTime,
|
|
482
629
|
durationMs,
|
|
483
630
|
status,
|
|
484
|
-
errorMessage
|
|
631
|
+
errorMessage,
|
|
632
|
+
completionAttributes
|
|
485
633
|
});
|
|
486
634
|
}
|
|
487
635
|
async #persistInstant(lcRunId, lcParentRunId, name, kind, attrs, status, errorMessage) {
|
|
@@ -587,6 +735,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
587
735
|
};
|
|
588
736
|
if (model && this.#opts.capture !== "none") attrs.model = model;
|
|
589
737
|
this.#mergeMetadata(attrs, metadata);
|
|
738
|
+
this.#mergeCorrelation(attrs);
|
|
590
739
|
this.#applyPreview(attrs, previews);
|
|
591
740
|
const ts = Date.now();
|
|
592
741
|
const stepName = `llm:${model ?? "llm"}`;
|
|
@@ -602,7 +751,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
602
751
|
confidence: "explicit",
|
|
603
752
|
source: { type: "adapter" }
|
|
604
753
|
});
|
|
605
|
-
await this.#
|
|
754
|
+
await this.#persistLlmStepStart(runId, parentRunId, stepName, "LLM", ts, attrs);
|
|
606
755
|
}
|
|
607
756
|
async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
608
757
|
this.#ensureRoot(runId, parentRunId);
|
|
@@ -615,6 +764,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
615
764
|
};
|
|
616
765
|
if (model && this.#opts.capture !== "none") attrs.model = model;
|
|
617
766
|
this.#mergeMetadata(attrs, metadata);
|
|
767
|
+
this.#mergeCorrelation(attrs);
|
|
618
768
|
this.#applyPreview(attrs, previews);
|
|
619
769
|
const ts = Date.now();
|
|
620
770
|
const stepName = `llm:${model ?? "llm"}`;
|
|
@@ -630,7 +780,22 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
630
780
|
confidence: "explicit",
|
|
631
781
|
source: { type: "adapter" }
|
|
632
782
|
});
|
|
633
|
-
await this.#
|
|
783
|
+
await this.#persistLlmStepStart(runId, parentRunId, stepName, "LLM", ts, attrs);
|
|
784
|
+
}
|
|
785
|
+
handleLLMNewToken(token, _idx, runId, _parentRunId, _tags, _fields) {
|
|
786
|
+
try {
|
|
787
|
+
if (!this.#opts.stream) return;
|
|
788
|
+
let state = this.#streamState.get(runId);
|
|
789
|
+
if (!state) {
|
|
790
|
+
state = createLlmStreamState();
|
|
791
|
+
this.#streamState.set(runId, state);
|
|
792
|
+
}
|
|
793
|
+
recordLlmStreamToken(state, token, Date.now(), this.#streamPreviewLimit());
|
|
794
|
+
} catch (err) {
|
|
795
|
+
if (!this.#opts.silent) {
|
|
796
|
+
console.error("[agent-inspect:langchain]", err);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
634
799
|
}
|
|
635
800
|
async handleLLMEnd(output, runId, parentRunId, tags, _extraParams) {
|
|
636
801
|
this.#ensureRoot(runId, parentRunId);
|
|
@@ -645,6 +810,8 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
645
810
|
};
|
|
646
811
|
if (model && this.#opts.capture !== "none") attrs.model = model;
|
|
647
812
|
if (tokens && this.#opts.capture !== "none") attrs.tokens = tokens;
|
|
813
|
+
this.#attachStreamMetadata(attrs, runId);
|
|
814
|
+
this.#mergeCorrelation(attrs);
|
|
648
815
|
this.#applyPreview(attrs, previews);
|
|
649
816
|
const ts = Date.now();
|
|
650
817
|
this.#pushEvent({
|
|
@@ -660,7 +827,13 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
660
827
|
confidence: "explicit",
|
|
661
828
|
source: { type: "adapter" }
|
|
662
829
|
});
|
|
663
|
-
await this.#
|
|
830
|
+
await this.#flushDeferredPersistStart(runId, attrs);
|
|
831
|
+
await this.#persistStepEnd(runId, parentRunId, "success", ts, durationMs, void 0, {
|
|
832
|
+
...attrs,
|
|
833
|
+
name: `llm:${model ?? "llm"}`,
|
|
834
|
+
kind: "LLM"
|
|
835
|
+
});
|
|
836
|
+
this.#clearStreamState(runId);
|
|
664
837
|
}
|
|
665
838
|
async handleLLMError(err, runId, parentRunId, tags, _extraParams) {
|
|
666
839
|
this.#ensureRoot(runId, parentRunId);
|
|
@@ -672,6 +845,8 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
672
845
|
errorName,
|
|
673
846
|
errorMessage
|
|
674
847
|
};
|
|
848
|
+
this.#attachStreamMetadata(attrs, runId);
|
|
849
|
+
this.#mergeCorrelation(attrs);
|
|
675
850
|
const ts = Date.now();
|
|
676
851
|
this.#pushEvent({
|
|
677
852
|
eventId: `${runId}:LLM:error`,
|
|
@@ -686,7 +861,13 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
686
861
|
confidence: "explicit",
|
|
687
862
|
source: { type: "adapter" }
|
|
688
863
|
});
|
|
689
|
-
await this.#
|
|
864
|
+
await this.#flushDeferredPersistStart(runId, attrs);
|
|
865
|
+
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage, {
|
|
866
|
+
...attrs,
|
|
867
|
+
name: "llm:error",
|
|
868
|
+
kind: "LLM"
|
|
869
|
+
});
|
|
870
|
+
this.#clearStreamState(runId);
|
|
690
871
|
}
|
|
691
872
|
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, _toolCallId) {
|
|
692
873
|
this.#ensureRoot(runId, parentRunId);
|