@@ -40,6 +40,7 @@ export class LangfuseClient {
4040 this . traceState . generationParentSpans . clear ( ) ;
4141 this . traceState . turnObservationsByMessageId . clear ( ) ;
4242 this . traceState . latestTurnObservationsBySession . clear ( ) ;
43+ this . traceState . finalizedToolCallIds . clear ( ) ;
4344 }
4445
4546 endActiveToolObservations ( sessionID ?: string , error ?: SessionErrorInfo ) {
@@ -61,6 +62,7 @@ export class LangfuseClient {
6162
6263 observation . span . end ( ) ;
6364 this . traceState . activeToolObservations . delete ( callID ) ;
65+ this . traceState . finalizedToolCallIds . add ( callID ) ;
6466 }
6567 }
6668
@@ -707,6 +709,7 @@ export class LangfuseClient {
707709 args : unknown ;
708710 } ) {
709711 this . traceState . activeToolObservations . get ( input . callID ) ?. span . end ( ) ;
712+ this . traceState . finalizedToolCallIds . delete ( input . callID ) ;
710713 this . ensureGenerationParent ( input . sessionID ) ;
711714
712715 this . withObservationParent ( input . sessionID , ( ) => {
@@ -738,6 +741,10 @@ export class LangfuseClient {
738741 title : string ;
739742 output : string ;
740743 } ) {
744+ if ( this . traceState . finalizedToolCallIds . has ( input . callID ) ) {
745+ return ;
746+ }
747+
741748 if ( ! this . traceState . activeToolObservations . has ( input . callID ) ) {
742749 this . traceToolStart ( {
743750 sessionID : input . sessionID ,
@@ -767,6 +774,32 @@ export class LangfuseClient {
767774
768775 span . end ( ) ;
769776 this . traceState . activeToolObservations . delete ( input . callID ) ;
777+ this . traceState . finalizedToolCallIds . add ( input . callID ) ;
778+ }
779+
780+ traceToolError ( input : { callID : string ; error : string ; completed : number } ) {
781+ if ( this . traceState . finalizedToolCallIds . has ( input . callID ) ) {
782+ return ;
783+ }
784+
785+ const span = this . traceState . activeToolObservations . get ( input . callID ) ?. span ;
786+
787+ if ( ! span ) {
788+ return ;
789+ }
790+
791+ span . setAttribute (
792+ "langfuse.observation.output" ,
793+ JSON . stringify ( { error : input . error } ) ,
794+ ) ;
795+ span . setStatus ( {
796+ code : SpanStatusCode . ERROR ,
797+ message : input . error ,
798+ } ) ;
799+ span . recordException ( { message : input . error } ) ;
800+ span . end ( new Date ( input . completed ) ) ;
801+ this . traceState . activeToolObservations . delete ( input . callID ) ;
802+ this . traceState . finalizedToolCallIds . add ( input . callID ) ;
770803 }
771804
772805 private ensureGenerationParent ( sessionID : string ) {
@@ -873,6 +906,7 @@ export type LangfuseTraceState = {
873906 turnObservationsByMessageId : Map < string , TurnObservation > ;
874907 latestTurnObservationsBySession : Map < string , TurnObservation > ;
875908 activeToolObservations : Map < string , ToolObservation > ;
909+ finalizedToolCallIds : Set < string > ;
876910 activeGenerationSteps : Map < string , ActiveGenerationStep > ;
877911 generationParentSpans : Map < string , ApiSpan > ;
878912} ;
@@ -1029,6 +1063,7 @@ export const createLangfuseClient = (input: {
10291063 turnObservationsByMessageId : new Map < string , TurnObservation > ( ) ,
10301064 latestTurnObservationsBySession : new Map < string , TurnObservation > ( ) ,
10311065 activeToolObservations : new Map < string , ToolObservation > ( ) ,
1066+ finalizedToolCallIds : new Set < string > ( ) ,
10321067 activeGenerationSteps : new Map < string , ActiveGenerationStep > ( ) ,
10331068 generationParentSpans : new Map < string , ApiSpan > ( ) ,
10341069 } ;
0 commit comments