An open API service indexing awesome lists of open source software.

https://github.com/julian-corbet/sporewright

A self-learning, multi-objective router for LLM and work routing — Rust + TypeScript (byte-equivalent), with failover, online learning, and a device↔orchestrator protocol
https://github.com/julian-corbet/sporewright

ai-agents failover llm llm-router load-balancing orchestration resilience router rust typescript

Last synced: 20 days ago
JSON representation

A self-learning, multi-objective router for LLM and work routing — Rust + TypeScript (byte-equivalent), with failover, online learning, and a device↔orchestrator protocol

Awesome Lists containing this project

README

          


sporewright

# sporewright

[![CI](https://github.com/julian-corbet/sporewright/actions/workflows/ci.yml/badge.svg)](https://github.com/julian-corbet/sporewright/actions/workflows/ci.yml)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Docs](https://img.shields.io/badge/docs-the%20model-brightgreen.svg)](docs/MODEL.md)
[![Cores](https://img.shields.io/badge/cores-Rust%20%2B%20TypeScript-orange.svg)](#the-object)

A **self-learning, multi-objective router** — one object, a sparse tensor, and the
operations on it. It answers one question for any kind of work (LLM calls, scraping,
rendering, embedding…) across any set of providers or devices (browser tabs, shells,
containers, servers, reachable peers):

> Given everything that *could* do this, in what order should *this* device try the
> options, what happens when one fails, and how does the order improve as we learn?

The engine has **no opinions about your domain**, and the same core ships in **Rust
and TypeScript, decision-equivalent**, so a browser tab and a server agree.

## The object

Everything is a read or write on one sparse tensor:

```
T[ level ][ instance ][ option ][ dimension ] → value
```

- **level** — a fixed, ordered hierarchy, coarse→fine (`global ≺ workspace ≺ … ≺ device`).
- **instance** — the horizontal axis a level spawns: `global` is one (`""`); `workspace`/`device` branch one-per-id.
- **option** — the candidates; the resolved **queue is a vector along this axis**.
- **dimension** — the per-option decision parameters (`latency`, `financial`, `reliability`, a gate…). A dimension's **weight** lives one axis coarser.

You read with a **cursor** (one instance per axis — `{workspace: acme, device: A}`).
Three operators:

- **fold** — collapse the level axis; the deepest set cell wins (most-specific inheritance, the CSS cascade).
- **resolve** — collapse the dimension axis; `Σ w·v`, a `+∞` gate drops the option, order ascending → the queue.
- **reduce** — the one path *up*: the median over a level's instances, the orchestrator's trusted aggregation.

Writes obey **write-down** (a device sets its own slice, never the shared levels), and
robustness is the orchestrator reading where evidence is thin — not metadata in the
cells. The full model, maths, and design choices are in **[docs/MODEL.md](docs/MODEL.md)**;
for *why* one `resolve` becomes a self-learning, multi-objective, resource-aware router
— the three-role dimension vector, the Lagrangian-dual maths, and eight worked stories —
read **[docs/ROUTING-MODEL.md](docs/ROUTING-MODEL.md)**.

## Quickstart

**Rust** (`crates/sporewright`)

```rust
use sporewright::tensor::{Tensor, Cursor};

let mut t = Tensor::new(["global", "workspace", "device"]);
let mut w = t.writer("global").unwrap();
w.set_value("global", "", "groq", "latency", 0.4).unwrap();
w.set_value("global", "", "cerebras", "latency", 0.3).unwrap();
w.set_weight("global", "", "latency", 1.0).unwrap();

// a premium workspace loosens a weight on its own slice; a device records its own value
w.set_value("device", "A", "groq", "latency", 0.05).unwrap();

let mut cursor = Cursor::new();
cursor.insert("device".into(), "A".into());
assert_eq!(t.resolve(&cursor), vec!["groq".to_string(), "cerebras".to_string()]);
```

**TypeScript** (`packages/sporewright`) — same model, decision-equivalent.

```ts
import { Tensor } from "sporewright";

const t = new Tensor(["global", "workspace", "device"]);
const w = t.writer("global")!;
w.setValue("global", "", "groq", "latency", 0.4);
w.setValue("global", "", "cerebras", "latency", 0.3);
w.setWeight("global", "", "latency", 1.0);
w.setValue("device", "A", "groq", "latency", 0.05);

t.resolve({ device: "A" }); // -> ["groq", "cerebras"]
```

## Build

```
cargo test -p sporewright # the Rust core
cd packages/sporewright && bun test # the TypeScript core
```

The two cores are kept decision-equivalent (the wire round-trips); see
[CONTRIBUTING.md](CONTRIBUTING.md) and [SCOPE.md](SCOPE.md) (what lives in the
engine vs the product).