You would need to walk backwards across definitions until you hit the block arg and return the direction like what you’re doing.
However, I think you may actually want to compute “flow”. E.g., an input port aggregate can have flips. References of that (which may include some number of flips) may then be either inputs or outputs. Flow solves this by saying things are “source” (something that can appear on the right-hand-side of a connect/an input), “sink” (something that can appear on the left-hand-side of a connect/an output), or “duplex” (something that can appear on either side of a connect/a wire or reg).
There is an example usage of this and another utility,
getDeclarationKind that can be used to know if something is a port: circt/FIRRTLOps.cpp at main · llvm/circt · GitHub
Riffing off that, you can determine this directionality by checking if something is a port with
getDeclarationKind and then using
foldFlow to determine if it is an input or output (assuming you want flow and not direction).