Arsen,
you are right, there is no way of specifying no input timeout on dialogflow side and the client has to maintain its own timer. the notion of no input timeout I was referring to is the gdf's no input timeout config. on google side, I was referring to the no-input handlers which are triggered when no input is received. it's not necessarily caused by a timeout, but either no audio detected or an empty query text is received. in your gdf implementation, when the no input timer is reached, you simply cancel the detect stream, which triggers "No-input 1" handler as shown below, however, gdf cannot receive this response anymore after the stream is cancelled thus we are missing the bot response associated with the handler. and at the same time, you return your own timeout error to your client, which is our app. like you said, our app needs to keep a counter so we know which No-input handler (1, 2 or 3) we need to trigger by sending a corresponding event. since different intent may have different number of no-input handlers, it's going to be tedious work to maintain a counter for each intent in our app. these handlers are supposed to be designed in dialogflow and transparent to our app.
that being said, we did our own experiment with Dialogflow API using freeswitch, basically when our timer is reached, instead of closing the detect stream immediately, we first send an empty query text to dialogflow using detectIntent method and receive a No-input handler from dialogflow (say No-input 1), we then close the detect stream. When the timer is reached again next time, we send another empty text and dialogflow will return us No-input 2 handler. and so on so forth ...
In summary, in order to receive a handler with correct counter from dialogflow, we need to send empty text before closing the detect stream. Not sure if it's something you can add to your gdf's feature list.

Thanks,
Frank