A variety of keras ops have paths that return objects of type OpenVINOKerasTensor. For example

import keras.ops as ops
from typing import reveal_type

result = keras.ops.concatenate(...)
reveal_type(result) # OpenVINOKerasTensor

This is because the paths of this op route to backend.numpy.concatenate(...)

And backend.numpy.concatenate has the following implementation:

def concatenate(xs, axis=0):
    assert isinstance(xs, list), "`concatenate` is supported only for `x` list"
    elems = []
    for elem in xs:
        elem = get_ov_output(elem)
        elems.append(elem)
    res = ov_opset.concat(elems, axis).output(0)
    return OpenVINOKerasTensor(res)

However, when inspecting the definition of OpenVINOKerasTensor here, it doesn't implement a variety of the __dunder__ methods expected (we see KerasTensor and frameworks like PyTorch, Jax, Numpy, and TFs objects all implement a much larger superset). Furthermore, it is missing an __array__ implementation, which is surprising of the return of any op coming from backend.numpy.some_operation.

When working with framework code that is supposed to cleanly be interoperable with other frameworks, which is a large selling point of Keras 3.x, the minimum expectation should be to abide by the same interface defined by KerasTensor, including overloads that are expected from non-symbolic tensors like __array__ with errors just like KerasTensor has. The reason for this is that it makes it much easier to write properly typed downstream code with Protocols for things like ArrayLike and TensorLike. Right now, all such code will get typing errors for any ops that have implementations through backend.numpy, which is not ideal.