05-16-26
AI Output Bridge: HTTP and Pipe Communication
Learn how to build an AI output bridge using Lua scripts for hardware input. This guide provides two methods: HTTP for remote AI and Pipe for local AI, enabling communication and action execution.
Question
I want to create a bridge between Rebind and an external AI service via HTTP, and also use a local Python script via shared memory (Pipe).
Rebind AI
Got it. I'll show you two approaches: sending data to an external AI service via HTTP, and using a local Python script via shared memory (Pipe).
Approach 1: HTTP Bridge to External AI
This script sends input state to a remote API and executes actions based on the response.
-- rebind: min_sdk=0.1.0
-- rebind: name=AI Output Bridge (HTTP)
-- rebind: permission=net
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable AI Bridge" }),
api_url = UI.Text("http://localhost:5000/predict", {
label = "AI API Endpoint",
placeholder = "http://your-ai-server/predict",
}),
poll_rate = UI.Slider(100, { min = 50, max = 500, suffix = "ms", label = "Poll Rate" }),
})
local lastPollTime = 0
local lastCommand = nil
function OnTick()
if not cfg.enabled then return end
local now = System.Time()
if now - lastPollTime < cfg.poll_rate then return end
lastPollTime = now
Run(function()
-- gather current input state
local mousePos = Input.GetMousePos()
local mods = Input.GetModifiers()
local payload = JSON.Stringify({
mouse_x = mousePos.x,
mouse_y = mousePos.y,
keys = Input.GetActiveKeys(),
modifiers = mods,
timestamp = now,
})
-- send to AI service
local response = Net.Post(cfg.api_url, payload, {
["Content-Type"] = "application/json",
["X-Rebind-Client"] = "1.0",
}, { timeout = 2000 })
if response.status == 200 then
local result = JSON.Parse(response.body)
-- execute AI-recommended action
if result.action == "move" then
HID.Move(result.dx or 0, result.dy or 0)
elseif result.action == "click" then
HID.Press(result.button or "Mouse1", result.hold or 50)
elseif result.action == "key" then
HID.Press(result.key)
elseif result.action == "type" then
HID.Type(result.text or "")
elseif result.action == "sequence" then
-- execute a sequence of actions
for _, step in ipairs(result.steps or {}) do
if step.action == "press" then
HID.Press(step.key, step.hold or 50)
Sleep(step.delay or 0)
elseif step.action == "move" then
HID.Move(step.dx, step.dy)
Sleep(step.delay or 0)
end
end
end
end
end)
end
function OnStop()
Audio.StopAll()
endHow it works:
- Every tick, gathers current mouse position, held keys, and modifiers
- Sends as JSON to your AI endpoint
- AI responds with an
action(move, click, key, type, sequence) - Script executes the recommended action immediately
Example AI server (Python with Flask):
from flask import Flask, request, jsonify
import numpy as np
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
data = request.json
mouse_x, mouse_y = data['mouse_x'], data['mouse_y']
keys = data['keys']
# Your AI logic here
# For demo: move toward center of screen
screen_w, screen_h = 1920, 1080
dx = (screen_w // 2 - mouse_x) * 0.1
dy = (screen_h // 2 - mouse_y) * 0.1
return jsonify({
"action": "move",
"dx": int(dx),
"dy": int(dy)
})
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000)Approach 2: Local AI via Shared Memory (Pipe)
This approach uses a named pipe for lower-latency communication with a local process (Python, Node.js, etc.).
-- rebind: min_sdk=0.1.0
-- rebind: name=AI Output Bridge (Pipe)
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable AI Bridge" }),
pipe_name = UI.Text("ai_bridge", { label = "Pipe Name", maxLength = 30 }),
poll_rate = UI.Slider(50, { min = 10, max = 200, suffix = "ms", label = "Poll Rate" }),
})
local pipe = nil
local lastPollTime = 0
function OnStart()
pipe = Pipe.Open(cfg.pipe_name, { size = 131072 })
Log.Info("AI bridge pipe opened: " .. pipe.name)
end
function OnTick()
if not cfg.enabled or not pipe then return end
local now = System.Time()
if now - lastPollTime < cfg.poll_rate then return end
lastPollTime = now
-- read response from AI process
local response = pipe:Read()
if response then
local command = JSON.Parse(response)
executeCommand(command)
end
-- send current state to AI process
local mousePos = Input.GetMousePos()
local state = JSON.Stringify({
mouse = { x = mousePos.x, y = mousePos.y },
keys = Input.GetActiveKeys(),
modifiers = Input.GetModifiers(),
time = now,
})
pipe:Write(state)
end
function executeCommand(cmd)
if cmd.action == "move" then
HID.Move(cmd.dx or 0, cmd.dy or 0)
elseif cmd.action == "click" then
HID.Press(cmd.button or "Mouse1", cmd.hold or 50)
elseif cmd.action == "key" then
HID.Press(cmd.key)
elseif cmd.action == "type" then
Run(function() HID.Type(cmd.text or "") end)
elseif cmd.action == "sequence" then
Run(function()
for _, step in ipairs(cmd.steps or {}) do
if step.action == "press" then
HID.Press(step.key, step.hold or 50)
Sleep(step.delay or 0)
elseif step.action == "move" then
HID.Move(step.dx, step.dy)
Sleep(step.delay or 0)
end
end
end)
end
end
function OnStop()
if pipe then pipe:Close() end
endExample AI process (Python):
import mmap
import json
import struct
import time
import threading
pipe_name = "ai_bridge"
shm_size = 131072
# Open shared memory
try:
shm = mmap.mmap(-1, shm_size, tagname=f"Local\\Rebind_{pipe_name}")
except:
shm = mmap.mmap(-1, shm_size, tagname=f"/dev/shm/Rebind_{pipe_name}")
def read_from_shm():
"""Read state sent by Rebind script"""
shm.seek(0)
seq = struct.unpack('<Q', shm.read(8))[0]
length = struct.unpack('<I', shm.read(4))[0]
if length > 0:
data = shm.read(length).decode('utf-8')
return json.loads(data)
return None
def write_to_shm(command):
"""Send command to Rebind script"""
offset = shm_size // 2
data = json.dumps(command).encode('utf-8')
shm.seek(offset)
shm.write(struct.pack('<Q', int(time.time() * 1000)))
shm.write(struct.pack('<I', len(data)))
shm.write(data)
def ai_loop():
"""Your AI logic here"""
while True:
state = read_from_shm()
if state:
# Example: simple aim assist (move toward center)
mouse = state['mouse']
screen_w, screen_h = 1920, 1080
center_x, center_y = screen_w // 2, screen_h // 2
dx = (center_x - mouse['x']) * 0.05
dy = (center_y - mouse['y']) * 0.05
if abs(dx) > 1 or abs(dy) > 1:
write_to_shm({
"action": "move",
"dx": int(dx),
"dy": int(dy)
})
time.sleep(0.01)
if __name__ == '__main__':
ai_loop()Comparison
| Feature | HTTP | Pipe | |---------|------|------| | Latency | Higher (~5-50ms) | Lower (~1-3ms) | | Setup | Simpler, any language | Requires memory mapping | | Remote | ✅ Can be on another machine | ❌ Local only | | Firewall | Can be blocked | Not affected | | Throughput | Lower | Higher |
Choose HTTP if:
- Your AI service runs remotely (cloud, another PC)
- You want simplicity over speed
- Latency tolerance is >10ms
Choose Pipe if:
- AI runs locally on the same PC
- You need sub-5ms latency
- Building a high-frequency loop
Learn more: