I think the most robust way is deriving medial axis of line buffer:
Vector solution is hard, perhaps consider raster based solution explained here.
Workflow (tools) for raster solution:
arcpy.Buffer_analysis(in_features="ORIGINAL", out_feature_class="in_memory/BUFFER", buffer_distance_or_field="20 Meters", line_side="FULL", line_end_type="FLAT", dissolve_option="NONE", dissolve_field="", method="PLANAR")
arcpy.PolygonToLine_management(in_features="buffer", out_feature_class="in_memory/BORDER", neighbor_option="IDENTIFY_NEIGHBORS")
arcpy.Merge_management(inputs="BORDER;ORIGINAL", output="in_memory/MERGED", field_mappings='LEFT_FID "LEFT_FID" true true false 0 Long 0 0 ,First,#,BORDER,LEFT_FID,-1,-1')
arcpy.Dissolve_management(in_features="MERGED", out_feature_class="in_memory/THREE_LINES", dissolve_field="", statistics_fields="", multi_part="SINGLE_PART", unsplit_lines="DISSOLVE_LINES")
arcpy.SelectLayerByLocation_management(in_layer="THREE_LINES", overlap_type="SHARE_A_LINE_SEGMENT_WITH", select_features="ORIGINAL", search_distance="", selection_type="NEW_SELECTION", invert_spatial_relationship="INVERT")
arcpy.PolygonToRaster_conversion(in_features="buffer", value_field="OBJECTID", out_rasterdataset="in_memory/cost_3", cell_assignment="CELL_CENTER", priority_field="NONE", cellsize="F:\SCRATCH\SCRATCH.gdb\MASK")
arcpy.gp.CostAllocation_sa("THREE_LINES", "cost_3", "F:/SCRATCH/SCRATCH.gdb/ALLOCATION", "", "", "OID", "", "", "", "", "", "", "")
Output of above:
As one can see result is highly dependent on a quality of flat end buffer I used at the beginning - see artefact at eastern end. Perhaps smooth original first. Note it can be done with round buffer, but it is more tricky.
Convert allocation raster to polygons and delete lines on the sides:
RasterToPolygon_conversion(in_raster="ALLOCATION", out_polygon_features="in_memory/POLYGONS", simplify="NO_SIMPLIFY", raster_field="Value", create_multipart_features="SINGLE_OUTER_PART", max_vertices_per_feature="")
PolygonToLine_management(in_features="POLYGONS", out_feature_class="in_memory/LINES", neighbor_option="IDENTIFY_NEIGHBORS")
SelectLayerByAttribute_management(in_layer_or_view="LINES", selection_type="NEW_SELECTION", where_clause='"LEFT_FID" =-1')
DeleteFeatures_management(in_features="LINES")
Output shows original smoothed result line.