Should we make all hyper-parameters into a named tuple

And make it a fourth type variable for the primitive, passing it as one value to the constructor?

In some sense this is true. Primitives are parameterized by inputs, outputs, internal params, and hyper-parameters. Passing also one value (named tuple) to the constructor is better than current approach with listing all hyper-parameters as separate arguments to the constructor. The latter though allow a bit easier subclassing of a primitive, as you can easily add extra arguments to the constructor (with named tuple it is a bit trickier to do reasonable inheritance in current Python typing).

Having one value represent all hyper-parameters is also better because one could define relations between hyper-parameters in this value as well. There could be methods attached to the named tuple value to for example sample the whole set of hyper-parameters in a way which respects relations between them.