Don't overthink it. The idea is that there's an inside and an outside of an application, and a boundary between them. The boundary ("ports") is not merely a line in some diagram, it consists of actual software elements and contracts/protocols associated with them. Despite what you may have read, these elements do not have to all be pure interfaces. There are some pros and cons there. A port could just be a concrete class behind which you can shift things around. I'll come back to that.
Now, what you strive for in your initial design, and then work towards as your software evolves and/or your understanding of what the requirements actually are changes, is to make the boundary relatively stable compared to both the inside and the outside (as in, arrive to a structure that doesn't change as frequently in comparison). This is because both the inside and the outside depend on the boundary to communicate with each other, so changes there would have rippling effects.
"Changes" could mean a number of different things - the outside might change because the UI is fiddly by nature, or because you want to rip out the UI and drive your application by a test suite, or because the format (but not the fundamental content) of the JSON response of some external API outside of your control changed. The inside might change because you've found a simpler, better way to represent something in code, or because you gained a new understanding of the requirements, or because you need to add another use case or something. Or because, to quote Ward Cunningham, "evolution of business practice wiggles around even those rules that 'must' apply".
Thinking in terms of input vs output ports is not actually that helpful. Alistair Cockburn, who first codified Hexagonal Architecture (a.k.a. Ports and Adapters), makes a distinction between primary ports and secondary ports, based on considerations about which of the two sides (outside, inside) initiates the interaction.
Primary ports are there to support outer components that call into the internal part of the application, so these outer components need to have a reference to the port. The port could just be an ordinary (concrete) class, an abstract class, an interface, or even just a function. What actually plays the role of the port there is the public (externally) visible members of the port class (or the signature + semantics of the function). You can choose (or evolve your design towards) any of these based on your needs and judgement. The important thing is that the port codifies the interaction, and that the core business logic happens behind it. Note that this sort of boundary is not limited to passing input. You can also use it to ask the application core for data or behavior.
Secondary ports allow the inside of the application to call into external components, so the ports (or rather, the implementations behind them) have to have a reference to these external components. Here's where you want to make use of dependency inversion, to make these references abstract and isolate the core. The abstraction of the external component is a part of the boundary (it's owned by the port); it is an important feature of the port's contract. If you decide to split the core (or parts of it) into a separate package, the port and the abstraction go inside the same package. Note that this reference to an external component does not have to be used for output only - the application's core can use this port to both push and pull data, and invoke behaviors.
I think the Internet's focus on input vs output ports comes from a common scenario where you have an outer component initiate some action by calling a primary port, providing some input, after which some internal processing happens that ultimately results in some output data being pushed through a secondary port.
Now, there's a number of reasons you might decide to have an input boundary / primary port represented by an interface. Maybe you've transparently composed your port out of multiple components in the style of the Composite pattern, and some of those components act as independent ports elsewhere. Maybe having an interface helps you with testing. Maybe you need some kind of multiple inheritance and you're using Java. Again, it's up to you.
Having an interface might help communicate to other devs in the team that it's a port, but the danger is that you'll come up with the wrong abstraction too early, and not course-correct in time, which is a problem. You know (or are in position to find out) the tendencies of your team best, so I guess you guys need to figure out what approach works for you.
In the end, don't adopt a certain convention because you're "supposed to" and because of "consistency" without first thinking it through as a team. Blind consistency is how you end up with spaghetti code.
P.S. If an adapter grows to be particularly complicated, you can at some point start treating it as its own small hexagonal component that's, in the grand scheme of things, dependent on the main hexagon, but locally has a small secondary port allowing you to inject either a reference towards the main app, or a mock.