const { Space, BodyAdapter } = require("@srk0102/plexa")
const { OllamaBrain } = require("@srk0102/plexa/bridges/ollama")
class CartpoleBody extends BodyAdapter {
static bodyName = "cartpole"
static tools = {
apply_force: {
description: "push cart left or right",
parameters: {
direction: { type: "string", enum: ["left", "right"], required: true },
magnitude: { type: "number", min: 0, max: 1, required: true },
},
},
hold: { description: "no-op", parameters: {} },
}
constructor() {
super()
this.physics = new CartpolePhysics()
}
async apply_force({ direction, magnitude }) {
this.physics.apply(direction, magnitude)
return { applied: direction, magnitude }
}
async hold() { this.physics.force = 0; return { ok: true } }
async tick() {
await super.tick()
this.physics.step()
this.setState({ pole_angle: this.physics.theta, cart_pos: this.physics.x })
if (Math.abs(this.physics.theta) > 0.8) {
this.emit("pole_critical", { angle: this.physics.theta }, "CRITICAL")
}
}
}
const space = new Space("balancer")
space.addBody(new CartpoleBody())
space.setBrain(new OllamaBrain({ model: "llama3.2" }))
await space.run()