It seems make-custom-textual-input-port will solve the problem of intercepting reads from stdin in evaluation thread. It is not in a release version, but is available in guile-next:
https://git.sv.gnu.org/cgit/guile.git/tree/module/ice-9/textual-ports.scm?h=075599e5b#n184
Thank you to @wingo for implementing it! :)