@@ -968,6 +968,151 @@ test.each(["true", "false"])(
968968 }
969969) ;
970970
971+ test . each ( [ "true" , "false" ] ) (
972+ "runnable nested within a traceable with manual tracer passed, background callbacks: %s" ,
973+ async ( value ) => {
974+ process . env . LANGCHAIN_CALLBACKS_BACKGROUND = value ;
975+
976+ const child = RunnableLambda . from ( async ( ) => {
977+ return { message : new HumanMessage ( { content : "From child!" } ) } ;
978+ } ) . withConfig ( { runName : "child" } ) ;
979+
980+ const parent = traceable (
981+ async ( ) => {
982+ return child . invoke (
983+ { } ,
984+ {
985+ callbacks : [ new LangChainTracer ( ) ] ,
986+ }
987+ ) ;
988+ } ,
989+ { name : "parent" , tracingEnabled : true , client }
990+ ) ;
991+
992+ await parent ( ) ;
993+
994+ await awaitAllCallbacks ( ) ;
995+ await client . awaitPendingTraceBatches ( ) ;
996+
997+ const relevantCalls = fetchMock . mock . calls . filter ( ( call : any ) => {
998+ return call [ 0 ] . startsWith ( "https://api.smith.langchain.com/runs" ) ;
999+ } ) ;
1000+
1001+ expect ( relevantCalls . length ) . toEqual ( 4 ) ;
1002+ const firstCallParams = JSON . parse (
1003+ decoder . decode ( ( relevantCalls [ 0 ] [ 1 ] as any ) . body )
1004+ ) ;
1005+ const secondCallParams = JSON . parse (
1006+ decoder . decode ( ( relevantCalls [ 1 ] [ 1 ] as any ) . body )
1007+ ) ;
1008+ const thirdCallParams = JSON . parse (
1009+ decoder . decode ( ( relevantCalls [ 2 ] [ 1 ] as any ) . body )
1010+ ) ;
1011+ const fourthCallParams = JSON . parse (
1012+ decoder . decode ( ( relevantCalls [ 3 ] [ 1 ] as any ) . body )
1013+ ) ;
1014+ const callParams = [
1015+ firstCallParams ,
1016+ secondCallParams ,
1017+ thirdCallParams ,
1018+ fourthCallParams ,
1019+ ] ;
1020+ const parentCallCreateParams = callParams . find ( ( param ) => {
1021+ return param . name === "parent" && param . start_time !== undefined ;
1022+ } ) ;
1023+ const childCallCreateParams = callParams . find ( ( param ) => {
1024+ return param . name === "child" && param . start_time !== undefined ;
1025+ } ) ;
1026+ const parentCallUpdateParams = callParams . find ( ( param ) => {
1027+ return (
1028+ param . dotted_order === parentCallCreateParams . dotted_order &&
1029+ param . end_time !== undefined
1030+ ) ;
1031+ } ) ;
1032+ const childCallUpdateParams = callParams . find ( ( param ) => {
1033+ return (
1034+ param . dotted_order === childCallCreateParams . dotted_order &&
1035+ param . end_time !== undefined
1036+ ) ;
1037+ } ) ;
1038+ expect ( parentCallCreateParams ) . toMatchObject ( {
1039+ id : parentCallCreateParams . id ,
1040+ name : "parent" ,
1041+ start_time : expect . any ( String ) ,
1042+ run_type : "chain" ,
1043+ extra : expect . any ( Object ) ,
1044+ serialized : { } ,
1045+ inputs : { } ,
1046+ child_runs : [ ] ,
1047+ trace_id : parentCallCreateParams . id ,
1048+ dotted_order : parentCallCreateParams . dotted_order ,
1049+ tags : [ ] ,
1050+ } ) ;
1051+
1052+ expect ( childCallCreateParams ) . toMatchObject ( {
1053+ id : expect . any ( String ) ,
1054+ name : "child" ,
1055+ parent_run_id : parentCallCreateParams . id ,
1056+ start_time : expect . any ( String ) ,
1057+ serialized : {
1058+ lc : 1 ,
1059+ type : "not_implemented" ,
1060+ id : [ "langchain_core" , "runnables" , "RunnableLambda" ] ,
1061+ } ,
1062+ inputs : { } ,
1063+ run_type : "chain" ,
1064+ extra : expect . any ( Object ) ,
1065+ tags : [ ] ,
1066+ trace_id : parentCallCreateParams . id ,
1067+ dotted_order : expect . stringContaining (
1068+ `${ parentCallCreateParams . dotted_order } .`
1069+ ) ,
1070+ } ) ;
1071+
1072+ expect ( childCallUpdateParams ) . toMatchObject ( {
1073+ end_time : expect . any ( Number ) ,
1074+ outputs : {
1075+ message : {
1076+ lc : 1 ,
1077+ type : "constructor" ,
1078+ id : [ "langchain_core" , "messages" , "HumanMessage" ] ,
1079+ kwargs : {
1080+ content : "From child!" ,
1081+ additional_kwargs : { } ,
1082+ response_metadata : { } ,
1083+ } ,
1084+ } ,
1085+ } ,
1086+ inputs : { } ,
1087+ trace_id : parentCallCreateParams . id ,
1088+ dotted_order : expect . stringContaining (
1089+ `${ parentCallCreateParams . dotted_order } .`
1090+ ) ,
1091+ } ) ;
1092+
1093+ expect ( parentCallUpdateParams ) . toMatchObject ( {
1094+ end_time : expect . any ( Number ) ,
1095+ inputs : { } ,
1096+ outputs : {
1097+ message : {
1098+ lc : 1 ,
1099+ type : "constructor" ,
1100+ id : [ "langchain_core" , "messages" , "HumanMessage" ] ,
1101+ kwargs : {
1102+ content : "From child!" ,
1103+ additional_kwargs : { } ,
1104+ response_metadata : { } ,
1105+ } ,
1106+ } ,
1107+ } ,
1108+ extra : expect . any ( Object ) ,
1109+ dotted_order : parentCallCreateParams . dotted_order ,
1110+ trace_id : parentCallCreateParams . id ,
1111+ tags : [ ] ,
1112+ } ) ;
1113+ }
1114+ ) ;
1115+
9711116test ( "LangChain V2 tracer creates and updates runs with replicas" , async ( ) => {
9721117 const projectNames = [ "replica1" , "replica2" ] ;
9731118 const referenceExampleId = "00000000-0000-0000-0000-000000000000" ;
0 commit comments