Tensorflow js processing

I was following this example https://www.youtube.com/watch?v=cdUNkwXx-I4 & then when i went to test i keep getting this error, but in the code he used he didn’t add shape;
Right now I’m just trying to get 1 bird to think.

Uncaught Error: tensor2d() requires shape to be provided when `values` are a flat/TypedArray
    at Object.Gte [as tensor2d] (tensor2d.js:61:11)
    at nn.js:49:21
    at engine.js:469:20
    at e.value (engine.js:480:19)
    at e.value (engine.js:467:17)
    at Object.X5 [as tidy] (globals.js:192:17)
    at NeuralNetwork.predict (nn.js:48:8)
    at Bird.think (Bird.js:26:29)
    at draw (FlappyBird.js:24:8)
    at e.default.redraw (p5.min.js:2:529954)

here a link to code the video uses website-archive/Courses/natureofcode/11.3_neuroevolution_tfjs.js/nn.js at main · CodingTrain/website-archive · GitHub
Oh Yea, I’m trying to get 1 bird to think before adding mutate
flappybird.js

var bird;
var savedBird = [];
var pipe = [];
var sp = 200;
var mx = 50;
var pipeCount = 0;

function setup() {
  createCanvas(600,500);
  tf.setBackend('cpu');
  bird = new Bird();
  pipe.push(new Pipe(sp,mx));
}


function draw() {
  background(0);
  fill(255);
  textSize(20);
  text("PC: " + pipeCount, 20, 60);
  text("PL: " + pipe.length, 20, 80);
  bird.show();
  bird.move();
  bird.think();
  for (var i = 0; i < pipe.length; i++){
    pipe[i].show();
    pipe[i].move();
    if (pipe[i].destroy == true){
      pipe.splice(i,1);
      bird.score += 1;
    }
  }
  if (pipeCount == 5){
    pipeCount = 0;
    mx += 10;
  }
}

function keyPressed(){
  if (keyCode == 38){bird.yspd = -1;}
  if (keyCode == 40){bird.yspd = 1;}
}

bird.js

class Bird{
  constructor(){
    this.x = 32;
    this.y = height/2;
    this.yspd = 1;
    this.w = 32;
    this.score = 0;
    this.brain = new NeuralNetwork(5,8,2);
  }
  
  dispose(){
    this.brain.dispose();
  }
  
  mutate() {
    this.brain.mutate(0.1);
  }
  
  think(){
    let inputs = [];
    inputs[0] = this.x;
    inputs[1] = this.y;
    inputs[2] = this.yspd;
    inputs[3] = pipe[0].x;
    inputs[4] = pipe[0].top - (pipe[0].w/2);
    let output = this.brain.predict(this.inputs);
    if (output[0] > output[1]){this.yspd = 1;}
    if (output[0] < output[1]){this.yspd = -1;}
  }
  
  show(){
    fill(255,255,0);
    ellipse(this.x,this.y,this.w,this.w);
    fill(255);
    textSize(20);
    text("S: " + this.score, 5, 20);
  }
  
  move(){
    this.y += this.yspd;
    if (this.y + (this.w/2) > height || this.y - (this.w/2) < 0){this.yspd = 0;}
  }
}

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- PLEASE NO CHANGES BELOW THIS LINE (UNTIL I SAY SO) -->
  <script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>
  <script language="javascript" type="text/javascript" src="Bird.js"></script>
  <script language="javascript" type="text/javascript" src="GA.js"></script>
  <script language="javascript" type="text/javascript" src="nn.js"></script>
  <script language="javascript" type="text/javascript" src="pipe.js"></script>
  <script language="javascript" type="text/javascript" src="FlappyBird.js"></script>
  <!-- OK, YOU CAN MAKE CHANGES BELOW THIS LINE AGAIN -->

  <style>
    body {
      padding: 0;
      margin: 0;
    }
  </style>
</head>

<body>
</body>
</html>

nn.js

class NeuralNetwork{
  constructor(a,b,c){
    if (a instanceof tf.Sequential){
      this.model = a;
    } else {
      this.input_nodes = a;
      this.hidden_nodes = b;
      this.output_nodes = c;
      this.model = this.createModel();
    }
  }
  
  mutate(rate){
    tf.tidy(() => {
      const weights = this.model.getWeights();
      const mutatedWeights = [];
      for (let i = 0; i < weightslength; i++){
        let tensor = weights[i];
        let shape = weights[i].shape;
        let values = tensor.dataSync().slice();
        for (let j = 0; j < values.length; j++){
          if (random(1) < rate){
            let w = values[j];
            values[j] = w + randomGaussian();
          }
        }
        let newTensor = tf.tensor(values, shape);
        mutatedWeights[i] = newTensor();
      }
      this.model.setWeights(mutatedWeights);
    });
  }// mutate
  
  copy(){
    return tf.tidy (() => {
    const modelCopy = this.createModel();
    const weights = this.model.getWeights();
    const weightCopies = [];
    for (var i = 0; i < weights.length; i++){
      weightCopies[i] = weights[i].clone();
    }
    modelCopy.setWeights(weightCopies);
    return new NeuralNetwork(modelCopy);
    });
  }
  
  predict(inputs){
    tf.tidy(() =>  {
      const xs = tf.tensor2d([inputs]);
      const ys = this.model.predict(xs);
    });
  }
  
  dispose(){
    this.model.dispose();
  }
  
  createModel(){
    const model = tf.sequential();
    const hidden = tf.layers.dense({
      units: this.hidden_nodes,
      inputShape: [this.input_nodes],
      activation: 'sigmoid'
    });
    model.add(hidden);
    const output = tf.layers.dense({
      units: this.output_nodes,
      activation: 'softmax'
    });
    model.add(output);
    return model;
  }// create
}

pipe.js

class Pipe{
  constructor(s,m){
    this.x = 550;
    this.space = s;
    this.top = round(random(20,height-(this.space+20)));
    this.bottom = height - this.top - this.space;
    this.w = 50;
    this.destroy = false;
    this.minx = m;
    this.create = false;
    pipeCount += 1;
    this.xspd = 1;
  }
  
  show(){
    fill(255);
    rect(this.x,0,this.w,this.top);
    rect(this.x,height - this.bottom,this.w,this.bottom);
  }
  
  move(){
    this.x -= this.xspd;
    if (this.x < -100){
      this.destroy = true;
      this.xspd = 0;
    }
    if (this.x < this.minx && this.create == false){
      pipe.push(new Pipe(sp,mx));
      this.create = true;
    }
  }// move
}